about summary refs log tree commit diff
path: root/configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245
diff options
context:
space:
mode:
authorWilliam Carroll <wpcarro@gmail.com>2018-10-02T13·54-0400
committerWilliam Carroll <wpcarro@gmail.com>2018-10-02T13·54-0400
commit9da3ffee41fa481a404a5fb19b7128d557df6114 (patch)
treeabac717a4d44360910233bd6a7dc7ad956f2440a /configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245
parentde97c7bcd0ed4b4877c1ae70e86cb37386755a37 (diff)
Update Emacs packages
This is a massive diff that I had to do in a hurry - when leaving
Urbint. I'm pretty sure that most of these are updating Emacs packages,
but I'm not positive.
Diffstat (limited to 'configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245')
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245/elixir-format.el199
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245/elixir-format.elcbin0 -> 5404 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245/elixir-mode-autoloads.el81
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245/elixir-mode-pkg.el9
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245/elixir-mode.el560
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245/elixir-mode.elcbin0 -> 15476 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245/elixir-smie.el904
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245/elixir-smie.elcbin0 -> 16788 bytes
8 files changed, 1753 insertions, 0 deletions
diff --git a/configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245/elixir-format.el b/configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245/elixir-format.el
new file mode 100644
index 000000000000..c3a718a91ed7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245/elixir-format.el
@@ -0,0 +1,199 @@
+;;; elixir-format.el --- Emacs plugin to mix format Elixir files
+
+;; Copyright 2017-2018 Anil Wadghule, Christian Kruse
+
+;; 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 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.
+
+;;; Commentary:
+
+;; The elixir-format function formats the elixir files with Elixir's `mix format`
+;; command
+
+;; e.g.
+;; M-x elixir-format
+;;
+
+(require 'ansi-color)
+
+(defcustom elixir-format-arguments nil
+  "Additional arguments to 'mix format'"
+  :type '(repeat string)
+  :group 'elixir-format)
+
+(defcustom elixir-format-hook nil
+  "Hook called by `elixir-format'."
+  :type 'hook
+  :group 'elixir-format)
+
+
+;;; Code:
+
+(defun elixir-format--errbuff ()
+  (get-buffer-create "*elixir-format-errors*"))
+
+(defun elixir-format--outbuff ()
+  (get-buffer-create "*elixir-format-output*"))
+
+(defun elixir-format--elixir-executable ()
+  (executable-find "elixir"))
+
+(defun elixir-format--mix-executable ()
+  (executable-find "mix"))
+
+;;;###autoload
+(defun elixir-format (&optional called-interactively-p)
+  (interactive "p")
+  (if (not (elixir-format--elixir-and-mix-path-set-p))
+      (elixir-format--display-missing-executables-error called-interactively-p)
+    (unwind-protect
+        (save-restriction
+          (elixir-format--clean-output-buffers)
+          (elixir-format--run-format called-interactively-p)))))
+
+(defun elixir-format--elixir-and-mix-path-set-p ()
+  (and (elixir-format--elixir-executable)
+       (elixir-format--mix-executable)))
+
+(defun elixir-format--display-missing-executables-error (called-interactively-p)
+  (with-current-buffer (elixir-format--errbuff)
+    (setq buffer-read-only nil)
+    (erase-buffer)
+    (insert "Emacs is unable to find the executables for elixir and/or mix. Either they are not installed on your system or emacs' PATH is not as wide as it needs to be. The latter is most likely to happen on OSX, in which case the simplest answer may be to add the exec-path-from-shell package to your configuration.")
+    (setq buffer-read-only t)
+    (ansi-color-apply-on-region (point-min) (point-max))
+    (special-mode)
+    (if called-interactively-p
+        (display-buffer (elixir-format--errbuff))
+      (error "Elixir Format error see %s" (elixir-format--errbuff)))))
+
+(defun elixir-format--clean-output-buffers ()
+  (with-current-buffer (elixir-format--outbuff)
+    (erase-buffer))
+
+  (with-current-buffer (elixir-format--errbuff)
+    (setq buffer-read-only nil)
+    (erase-buffer)))
+
+(defun elixir-format--run-format (called-interactively-p)
+  (let ((tmpfile (make-temp-file "elixir-format" nil ".ex"))
+        (our-elixir-format-arguments (list (elixir-format--mix-executable) "format")))
+
+    (write-region nil nil tmpfile)
+    (run-hooks 'elixir-format-hook)
+
+    (when elixir-format-arguments
+      (setq our-elixir-format-arguments (append our-elixir-format-arguments elixir-format-arguments)))
+    (setq our-elixir-format-arguments (append our-elixir-format-arguments (list tmpfile)))
+
+    (if (zerop (apply #'call-process (elixir-format--elixir-executable) nil (elixir-format--errbuff) nil our-elixir-format-arguments))
+        (elixir-format--call-format-command tmpfile)
+      (elixir-format--failed-to-format called-interactively-p))
+    (delete-file tmpfile)
+    (kill-buffer (elixir-format--outbuff))))
+
+(defun elixir-format--call-format-command (tmpfile)
+  (if (zerop (call-process-region (point-min) (point-max) "diff" nil (elixir-format--outbuff) nil "-n" "-" tmpfile))
+      (message "File is already formatted")
+    (elixir-format--apply-rcs-patch (elixir-format--outbuff))
+    (message "elixir-format format applied"))
+  (kill-buffer (elixir-format--errbuff)))
+
+(defun elixir-format--failed-to-format (called-interactively-p)
+  (with-current-buffer (elixir-format--errbuff)
+    (setq buffer-read-only t)
+    (ansi-color-apply-on-region (point-min) (point-max))
+    (special-mode))
+
+  (if called-interactively-p
+      (display-buffer (elixir-format--errbuff))
+    (error "elixir-format failed: see %s" (buffer-name (elixir-format--errbuff)))))
+
+(defun elixir-format--apply-rcs-patch (patch-buffer)
+  "Apply an RCS-formatted diff from PATCH-BUFFER to the current buffer.
+Shamelessly stolen from go-mode (https://github.com/dominikh/go-mode.el)"
+
+  (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 elixir-format--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 (point-min))
+                    (forward-line (- from len line-offset))
+                    (insert text)))))
+             ((equal action "d")
+              (with-current-buffer target-buffer
+                (elixir-format--goto-line (- from line-offset))
+                (cl-incf line-offset len)
+                (elixir-format--delete-whole-line len)))
+             (t
+              (error "Invalid rcs patch or internal error in elixir-format--apply-rcs-patch")))))))))
+
+(defun elixir-format--goto-line (line)
+  (goto-char (point-min))
+  (forward-line (1- line)))
+
+(defun elixir-format--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.
+
+Shamelessly stolen from go-mode (https://github.com/dominikh/go-mode.el)"
+  (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))))))
+
+(provide 'elixir-format)
+
+;;; elixir-format.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245/elixir-format.elc b/configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245/elixir-format.elc
new file mode 100644
index 000000000000..82ba5f00b683
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245/elixir-format.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245/elixir-mode-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245/elixir-mode-autoloads.el
new file mode 100644
index 000000000000..fb44552bf9de
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245/elixir-mode-autoloads.el
@@ -0,0 +1,81 @@
+;;; elixir-mode-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "elixir-format" "elixir-format.el" (23454 53158
+;;;;;;  963266 440000))
+;;; Generated autoloads from elixir-format.el
+
+(autoload 'elixir-format "elixir-format" "\
+
+
+\(fn &optional CALLED-INTERACTIVELY-P)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "elixir-mode" "elixir-mode.el" (23454 53158
+;;;;;;  956961 640000))
+;;; Generated autoloads from elixir-mode.el
+
+(autoload 'elixir-mode-open-github "elixir-mode" "\
+Elixir mode open GitHub page.
+
+\(fn)" t nil)
+
+(autoload 'elixir-mode-open-elixir-home "elixir-mode" "\
+Elixir mode go to language home.
+
+\(fn)" t nil)
+
+(autoload 'elixir-mode-open-docs-master "elixir-mode" "\
+Elixir mode go to master documentation.
+
+\(fn)" t nil)
+
+(autoload 'elixir-mode-open-docs-stable "elixir-mode" "\
+Elixir mode go to stable documentation.
+
+\(fn)" t nil)
+
+(autoload 'elixir-mode-version "elixir-mode" "\
+Get the Elixir-Mode 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 'elixir-mode "elixir-mode" "\
+Major mode for editing Elixir code.
+
+\\{elixir-mode-map}
+
+\(fn)" t nil)
+
+(add-to-list 'auto-mode-alist '("\\.elixir\\'" . elixir-mode))
+
+(add-to-list 'auto-mode-alist '("\\.ex\\'" . elixir-mode))
+
+(add-to-list 'auto-mode-alist '("\\.exs\\'" . elixir-mode))
+
+;;;***
+
+;;;### (autoloads nil nil ("elixir-mode-pkg.el" "elixir-smie.el")
+;;;;;;  (23454 53158 961236 810000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; elixir-mode-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245/elixir-mode-pkg.el b/configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245/elixir-mode-pkg.el
new file mode 100644
index 000000000000..bd2dbae498ab
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245/elixir-mode-pkg.el
@@ -0,0 +1,9 @@
+(define-package "elixir-mode" "20180711.1245" "Major mode for editing Elixir files"
+  '((emacs "24")
+    (pkg-info "0.4"))
+  :keywords
+  '("languages" "elixir")
+  :url "https://github.com/elixir-lang/emacs-elixir")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245/elixir-mode.el b/configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245/elixir-mode.el
new file mode 100644
index 000000000000..c396d3032b11
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245/elixir-mode.el
@@ -0,0 +1,560 @@
+;;; elixir-mode.el --- Major mode for editing Elixir files
+
+;; Copyright 2011-2015 secondplanet
+;;           2013-2015 Samuel Tonini, Matt DeBoard, Andreas Fuchs
+;; Authors: Humza Yaqoob,
+;;          Andreas Fuchs <asf@boinkor.net>,
+;;          Matt DeBoard
+;;          Samuel Tonini <tonini.samuel@gmail.com>
+
+;; URL: https://github.com/elixir-lang/emacs-elixir
+;; Created: Mon Nov 7 2011
+;; Keywords: languages elixir
+;; Version: 2.3.1
+;; Package-Requires: ((emacs "24") (pkg-info "0.4"))
+
+;; This file is not a 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 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; if not, write to the Free Software
+;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+;;; Commentary:
+
+;;  Provides font-locking, indentation and navigation support
+;;  for the Elixir programming language.
+
+;;; Code:
+
+(require 'easymenu)           ; Elixir Mode menu definition
+(require 'elixir-smie)        ; Syntax and indentation support
+(require 'pkg-info)           ; Display Elixir Mode package version
+(require 'elixir-format)      ; Elixir Format functions
+
+(defgroup elixir nil
+  "Major mode for editing Elixir code."
+  :prefix "elixir-"
+  :group 'languages
+  :link '(url-link :tag "Github" "https://github.com/elixir-lang/emacs-elixir")
+  :link '(emacs-commentary-link :tag "Commentary" "elixir-mode"))
+
+(defvar elixir-mode-website-url "http://elixir-lang.org"
+  "Official url of Elixir programming website.")
+
+(defvar elixir-mode-doc-url "https://hexdocs.pm/elixir"
+  "Official documentation for the Elixir programming language.")
+
+(defvar elixir-mode-hook nil)
+
+(defvar elixir-mode-map
+  (let ((map (make-sparse-keymap)))
+    map)
+  "Keymap used in `elixir-mode'.")
+
+(defvar elixir-imenu-generic-expression
+  '(("Modules" "^\\s-*defmodule[ \n\t]+\\([A-Z][A-Za-z0-9._]+\\)\\s-+.*$" 1)
+    ("Public Functions" "^\\s-*def[ \n\t]+\\([a-z0-9_!\\?]+\\)\\(([^)]*)\\)*.*" 1)
+    ("Private Functions" "^\\s-*defp[ \n\t]+\\([a-z0-9_!\\?]+\\)\\(([^)]*)\\)*.*" 1)
+    ("Public Macros" "^\\s-*defmacro[ \n\t]+\\([a-z0-9_!\\?]+\\)\\(([^)]*)\\)*.*" 1)
+    ("Private Macros" "^\\s-*defmacrop[ \n\t]+\\([a-z0-9_!\\?]+\\)\\(([^)]*)\\)*.*" 1)
+    ("Delegates" "^\\s-*defdelegate[ \n\t]+\\([a-z0-9_]+\\)\\(([^)]*)\\)*.*" 1)
+    ("Overridables" "^\\s-*defoverridable[ \n\t]+\\([a-z0-9_]+\\)\\(([^)]*)\\)*.*" 1)
+    ("Tests" "^\\s-*test[ \t\n]+\"?\\(:?[a-z0-9_@+() \t-]+\\)\"?[ \t\n]+.*" 1))
+  "Imenu pattern for `elixir-mode'.")
+
+(defvar elixir-basic-offset 2)
+(defvar elixir-key-label-offset 0)
+(defvar elixir-match-label-offset 2)
+
+(defvar elixir-attribute-face 'elixir-attribute-face)
+(defface elixir-attribute-face
+  '((((class color) (min-colors 88) (background light))
+     :foreground "MediumPurple4")
+    (((class color) (background dark))
+     (:foreground "thistle"))
+    (t nil))
+  "For use with module attribute tokens."
+  :group 'font-lock-faces)
+
+(defvar elixir-atom-face 'elixir-atom-face)
+(defface elixir-atom-face
+  '((((class color) (min-colors 88) (background light))
+     :foreground "RoyalBlue4")
+    (((class color) (background dark))
+     (:foreground "light sky blue"))
+    (t nil))
+  "For use with atoms & map keys."
+  :group 'font-lock-faces)
+
+(eval-when-compile
+  (defconst elixir-rx-constituents
+    `(
+      (string-delimiter . ,(rx (and
+                                ;; Match even number of backslashes.
+                                (or (not (any ?\\ ?\' ?\")) point
+                                    ;; Quotes might be preceded by escaped quote
+                                    (and (or (not (any ?\\)) point) ?\\
+                                         (* ?\\ ?\\) (any ?\' ?\")))
+                                (* ?\\ ?\\)
+                                ;; Match single or triple quotes of any kind.
+                                (group (or "\"" "\"\"\"" "'" "'''")))))
+      (atoms . ,(rx ":"
+                    (or
+                     (and
+                      (any "a-z" "A-Z" "_" "\"" "'")
+                      (zero-or-more (any "a-z" "A-Z" "0-9" "_" "\"" "'" "!" "@" "?")))
+                     (and "\"" (one-or-more (not (any "\""))) "\"")
+                     (and "'" (one-or-more (not (any "'"))) "'"))))
+      (builtin . ,(rx symbol-start
+                      (or "case" "cond" "for" "if" "quote" "raise" "receive" "send"
+                          "super" "throw" "try" "unless" "unquote" "unquote_splicing"
+                          "with")
+                      symbol-end))
+      (builtin-declaration . ,(rx symbol-start
+                                  (or "def" "defp" "defmodule" "defprotocol"
+                                      "defmacro" "defmacrop" "defdelegate"
+                                      "defexception" "defstruct" "defimpl"
+                                      "defcallback" "defoverridable")
+                                  symbol-end))
+      (builtin-namespace . ,(rx symbol-start
+                                (or "import" "require" "use" "alias")
+                                symbol-end))
+      ;; Set aside code point syntax for negation face.
+      (code-point . ,(rx symbol-start
+                         "?"
+                         anything
+                         symbol-end))
+      (function-declaration . ,(rx (or line-start (not (any ".")))
+                                   symbol-start
+                                   (or "def" "defp")
+                                   symbol-end))
+      ;; The first character of an identifier must be a letter or an underscore.
+      ;; After that, they may contain any alphanumeric character + underscore.
+      ;; Additionally, the final character may be either `?' or `!'.
+      (identifiers . ,(rx (one-or-more (any "A-Z" "a-z" "_"))
+                          (zero-or-more (any "A-Z" "a-z" "0-9" "_"))
+                          (optional (or "?" "!"))))
+      (keyword . ,(rx symbol-start
+                      (or "fn" "do" "end" "after" "else" "rescue" "catch")
+                      symbol-end))
+      (keyword-operator . ,(rx symbol-start
+                               (or "not" "and" "or" "when" "in")
+                               symbol-end))
+      ;; Module and submodule names start with upper case letter. This
+      ;; can then be followed by any combination of alphanumeric chars.
+      ;; In turn, this can be followed by a `.' which begins the notation of
+      ;; a submodule, which follows the same naming pattern of the module.
+      ;; Finally, like other identifiers, it can be terminated with either `?'
+      ;; or `!'.
+      (module-names . ,(rx symbol-start
+                           (optional (or "%" "&"))
+                           (one-or-more (any "A-Z"))
+                           (zero-or-more (any "A-Z" "a-z" "_" "0-9"))
+                           (zero-or-more
+                            (and "."
+                                 (one-or-more (any "A-Z" "_"))
+                                 (zero-or-more (any "A-Z" "a-z" "_" "0-9"))))
+                           (optional (or "!" "?"))
+                           symbol-end))
+      (pseudo-var . ,(rx symbol-start
+                         (optional (or "%" "&"))
+                         (or "_" "__MODULE__" "__DIR__" "__ENV__" "__CALLER__"
+                             "__block__" "__aliases__")
+                         symbol-end))
+      (sigils . ,(rx "~" (or "B" "C" "D" "N" "R" "S" "T" "b" "c" "r" "s" "w")))))
+
+  (defmacro elixir-rx (&rest sexps)
+    (let ((rx-constituents (append elixir-rx-constituents rx-constituents)))
+      (cond ((null sexps)
+             (error "No regexp"))
+            ((cdr sexps)
+             (rx-to-string `(and ,@sexps) t))
+            (t
+             (rx-to-string (car sexps) t))))))
+
+(defsubst elixir-syntax-in-string-or-comment-p ()
+  (nth 8 (syntax-ppss)))
+
+(defsubst elixir-syntax-count-quotes (quote-char &optional point limit)
+  "Count number of quotes around point (max is 3).
+QUOTE-CHAR is the quote char to count.  Optional argument POINT is
+the point where scan starts (defaults to current point), and LIMIT
+is used to limit the scan."
+  (let ((i 0))
+    (while (and (< i 3)
+                (or (not limit) (< (+ point i) limit))
+                (eq (char-after (+ point i)) quote-char))
+      (setq i (1+ i)))
+    i))
+
+(defun elixir-syntax-stringify ()
+  "Put `syntax-table' property correctly on single/triple quotes."
+  (let* ((num-quotes (length (match-string-no-properties 1)))
+         (ppss (prog2
+                   (backward-char num-quotes)
+                   (syntax-ppss)
+                 (forward-char num-quotes)))
+         (string-start (and (not (nth 4 ppss)) (nth 8 ppss)))
+         (quote-starting-pos (- (point) num-quotes))
+         (quote-ending-pos (point))
+         (num-closing-quotes
+          (and string-start
+               (elixir-syntax-count-quotes
+                (char-before) string-start quote-starting-pos))))
+    (cond ((and string-start (= num-closing-quotes 0))
+           ;; This set of quotes doesn't match the string starting
+           ;; kind. Do nothing.
+           nil)
+          ((not string-start)
+           ;; This set of quotes delimit the start of a string.
+           (put-text-property quote-starting-pos (1+ quote-starting-pos)
+                              'syntax-table (string-to-syntax "|")))
+          ((= num-quotes num-closing-quotes)
+           ;; This set of quotes delimit the end of a string.
+           (put-text-property (1- quote-ending-pos) quote-ending-pos
+                              'syntax-table (string-to-syntax "|")))
+          ((> num-quotes num-closing-quotes)
+           ;; This may only happen whenever a triple quote is closing
+           ;; a single quoted string. Add string delimiter syntax to
+           ;; all three quotes.
+           (put-text-property quote-starting-pos quote-ending-pos
+                              'syntax-table (string-to-syntax "|"))))))
+
+
+(defun elixir-syntax-propertize-interpolation ()
+  (let* ((beg (match-beginning 0))
+         (context (save-excursion (save-match-data (syntax-ppss beg)))))
+    (put-text-property beg (1+ beg) 'syntax-table (string-to-syntax "w"))
+    (put-text-property beg (1+ beg) 'elixir-interpolation
+                       (cons (nth 3 context) (match-data)))))
+
+(defconst elixir-sigil-delimiter-pair
+  '((?\( . ")")
+    (?\{ . "}")
+    (?\< . ">")
+    (?\[ . "]")))
+
+(defun elixir-syntax-replace-property-in-sigil ()
+  (unless (elixir-syntax-in-string-or-comment-p)
+    (let ((heredoc-p (save-excursion
+                       (goto-char (match-beginning 0))
+                       (looking-at-p "~[sS]\\(?:'''\\|\"\"\"\\)"))))
+      (unless heredoc-p
+        (forward-char 1)
+        (let* ((start-delim (char-after (1- (point))))
+               (end-delim (or (assoc-default start-delim elixir-sigil-delimiter-pair)
+                              (char-to-string start-delim)))
+               (end (save-excursion
+                      (let (finish)
+                        (while (not finish)
+                          (skip-chars-forward (concat "^" end-delim))
+                          (if (or (not (eq (char-before) ?\\))
+                                  (eq (char-before (1- (point))) ?\\)
+                                  (eobp))
+                              (setq finish t)
+                            (forward-char 1)))
+                        (point))))
+               (word-syntax (string-to-syntax "w")))
+          (when (memq start-delim '(?' ?\"))
+            (setq end (1+ end))
+            (forward-char -1))
+          (while (re-search-forward "[\"'#]" end 'move)
+            (put-text-property (1- (point)) (point) 'syntax-table word-syntax)))))))
+
+(defun elixir-syntax-propertize-function (start end)
+  (let ((case-fold-search nil))
+    (goto-char start)
+    (funcall
+     (syntax-propertize-rules
+      ("\\(\\?\\)[\"']"
+       (1 (if (save-excursion (nth 3 (syntax-ppss (match-beginning 0))))
+              ;; Within a string, skip.
+              (ignore
+               (goto-char (match-end 1)))
+            (put-text-property (match-end 1) (match-end 0)
+                               'syntax-table (string-to-syntax "_"))
+            (string-to-syntax "'"))))
+      ((elixir-rx string-delimiter)
+       (0 (ignore (elixir-syntax-stringify))))
+      ((elixir-rx sigils)
+       (0 (ignore (elixir-syntax-replace-property-in-sigil))))
+      ((rx (group "#{" (0+ (not (any "}"))) "}"))
+       (0 (ignore (elixir-syntax-propertize-interpolation)))))
+     start end)))
+
+(defun elixir-match-interpolation (limit)
+  (let ((pos (next-single-char-property-change (point) 'elixir-interpolation
+                                               nil limit)))
+    (when (and pos (> pos (point)))
+      (goto-char pos)
+      (let ((value (get-text-property pos 'elixir-interpolation)))
+        (if (car value)
+            (progn
+              (set-match-data (cdr value))
+              t)
+          (elixir-match-interpolation limit))))))
+
+
+(defconst elixir-font-lock-keywords
+  `(
+    ;; String interpolation
+    (elixir-match-interpolation 0 font-lock-variable-name-face t)
+
+    ;; Module attributes
+    (,(elixir-rx (and "@" (1+ identifiers)))
+     0 elixir-attribute-face)
+
+    ;; Keywords
+    (,(elixir-rx (and (or line-start (not (any ".")))
+                      (group (or builtin builtin-declaration builtin-namespace
+                                 keyword keyword-operator))))
+     1 font-lock-keyword-face)
+
+    ;; Function names, i.e. `def foo do'.
+    (,(elixir-rx (group function-declaration)
+                 space
+                 (group identifiers))
+     2 font-lock-function-name-face)
+
+    ;; Sigil patterns. Elixir has support for eight different sigil delimiters.
+    ;; This isn't a very DRY approach here but it gets the job done.
+    (,(elixir-rx (group sigils)
+                 (and "/"
+                      (group (zero-or-more (or (and "\\" "/") (not (any "/" "\n" "\r")))))
+                      "/"))
+     (1 font-lock-builtin-face)
+     (2 font-lock-string-face))
+    (,(elixir-rx (group sigils)
+                 (and "["
+                      (group (zero-or-more (or (and "\\" "]") (not (any "]" "\n" "\r")))))
+                      "]"))
+     (1 font-lock-builtin-face)
+     (2 font-lock-string-face))
+    (,(elixir-rx (group sigils)
+                 (and "{"
+                      (group (zero-or-more (or (and "\\" "}") (not (any "}" "\n" "\r")))))
+                      "}"))
+     (1 font-lock-builtin-face)
+     (2 font-lock-string-face))
+    (,(elixir-rx (group sigils)
+                 (and "("
+                      (group (zero-or-more (or (and "\\" ")") (not (any ")" "\n" "\r")))))
+                      ")"))
+     (1 font-lock-builtin-face)
+     (2 font-lock-string-face))
+    (,(elixir-rx (group sigils)
+                 (and "|"
+                      (group (zero-or-more (or (and "\\" "|") (not (any "|" "\n" "\r")))))
+                      "|"))
+     (1 font-lock-builtin-face)
+     (2 font-lock-string-face))
+    (,(elixir-rx (group sigils)
+                 (and "\""
+                      (group (zero-or-more (or (and "\\" "\"") (not (any "\"" "\n" "\r")))))
+                      "\""))
+     (1 font-lock-builtin-face)
+     (2 font-lock-string-face))
+    (,(elixir-rx (group sigils)
+                 (and "'"
+                      (group (zero-or-more (or (and "\\" "'") (not (any "'" "\n" "\r")))))
+                      "'"))
+     (1 font-lock-builtin-face)
+     (2 font-lock-string-face))
+    (,(elixir-rx (group sigils)
+                 (and "<"
+                      (group (zero-or-more (or (and "\\" ">") (not (any ">" "\n" "\r")))))
+                      ">"))
+     (1 font-lock-builtin-face)
+     (2 font-lock-string-face))
+
+    ;; Modules
+    (,(elixir-rx (group module-names))
+     1 font-lock-type-face)
+
+    ;; Atoms and singleton-like words like true/false/nil.
+    (,(elixir-rx symbol-start
+                 (group (or atoms "true" "false" "nil"))
+                 symbol-end
+                 (zero-or-more space)
+                 (optional "="))
+     1 elixir-atom-face)
+
+    ;; Gray out variables starting with "_"
+    (,(elixir-rx symbol-start
+                 (group (and "_"
+                             (any "A-Z" "a-z" "0-9"))
+                        (zero-or-more (any "A-Z" "a-z" "0-9" "_"))
+                        (optional (or "?" "!"))))
+     1 font-lock-comment-face)
+
+    ;; Variable definitions
+    (,(elixir-rx (group identifiers)
+                 (zero-or-more space)
+                 (repeat 1 "=")
+                 (or (or sigils identifiers space)
+                     (one-or-more "\n")))
+     1 font-lock-variable-name-face)
+
+    ;; Map keys
+    (,(elixir-rx (group (and (one-or-more identifiers) ":")) space)
+     1 elixir-atom-face)
+
+    ;; Pseudovariables
+    (,(elixir-rx (group pseudo-var))
+     1 font-lock-constant-face)
+
+    ;; Code points
+    (,(elixir-rx (group code-point))
+     1 font-lock-negation-char-face)))
+
+;;;###autoload
+(defun elixir-mode-open-github ()
+  "Elixir mode open GitHub page."
+  (interactive)
+  (browse-url "https://github.com/elixir-lang/emacs-elixir"))
+
+;;;###autoload
+(defun elixir-mode-open-elixir-home ()
+  "Elixir mode go to language home."
+  (interactive)
+  (browse-url elixir-mode-website-url))
+
+;;;###autoload
+(defun elixir-mode-open-docs-master ()
+  "Elixir mode go to master documentation."
+  (interactive)
+  (browse-url (concat elixir-mode-doc-url "/master")))
+
+;;;###autoload
+(defun elixir-mode-open-docs-stable ()
+  "Elixir mode go to stable documentation."
+  (interactive)
+  (browse-url elixir-mode-doc-url))
+
+;;;###autoload
+(defun elixir-mode-version (&optional show-version)
+  "Get the Elixir-Mode 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 'elixir-mode)))
+    (when show-version
+      (message "Elixir-Mode version: %s" version))
+    version))
+
+(defun elixir-mode-fill-doc-string ()
+  (interactive)
+  (save-excursion
+    (re-search-backward "@\\(?:module\\)?doc +\"\"\"" nil t)
+    (re-search-forward "\"\"\"" nil t)
+    (set-mark (point))
+    (re-search-forward "\"\"\"" nil t)
+    (re-search-backward "^ *\"\"\"" nil t)
+    (backward-char)
+    (fill-region (point) (mark))))
+
+(defun elixir-beginning-of-defun (&optional arg)
+  (interactive "p")
+  (let ((regexp (concat "^\\s-*" (elixir-rx builtin-declaration)))
+        case-fold-search)
+    (while (and (re-search-backward regexp nil t (or arg 1))
+                (elixir-syntax-in-string-or-comment-p)))
+    (goto-char (line-beginning-position))))
+
+(defun elixir-end-of-defun ()
+  (interactive)
+  (goto-char (line-beginning-position))
+  (if (re-search-forward "\\_<do:" (line-end-position) t)
+      (goto-char (line-end-position))
+    (goto-char (line-end-position))
+    (let ((level (save-excursion
+                   (elixir-beginning-of-defun)
+                   (current-indentation)))
+          finish)
+      (while (and (not finish) (re-search-forward "^\\s-*\\_<end\\_>" nil t))
+        (when (and (not (elixir-syntax-in-string-or-comment-p))
+                   (= (current-indentation) level))
+          (setq finish t)))
+      (when (looking-back "^\\s-*\\_<end" (line-beginning-position))
+        (forward-line 1)))))
+
+(defun elixir--docstring-p (&optional pos)
+  "Check to see if there is a docstring at pos."
+  (let ((pos (or pos (nth 8 (parse-partial-sexp (point-min) (point))))))
+    (when pos
+      (save-excursion
+        (goto-char pos)
+        (and (looking-at "\"\"\"")(looking-back "@moduledoc[ \]+\\|@doc[ \]+"
+                                                (line-beginning-position)))))))
+
+(defun elixir-font-lock-syntactic-face-function (state)
+  (if (nth 3 state)
+      (if (elixir--docstring-p (nth 8 state))
+          font-lock-doc-face
+        font-lock-string-face)
+    font-lock-comment-face))
+
+(easy-menu-define elixir-mode-menu elixir-mode-map
+  "Elixir mode menu."
+  '("Elixir"
+    ["Indent line" smie-indent-line]
+    "---"
+    ["elixir-mode on GitHub" elixir-mode-open-github]
+    ["Elixir homepage" elixir-mode-open-elixir-home]
+    ["About" elixir-mode-version]))
+
+;;;###autoload
+(define-derived-mode elixir-mode prog-mode "Elixir"
+  "Major mode for editing Elixir code.
+
+\\{elixir-mode-map}"
+  (set (make-local-variable 'font-lock-defaults)
+       '(elixir-font-lock-keywords
+         nil nil nil nil
+         (font-lock-syntactic-face-function
+          . elixir-font-lock-syntactic-face-function)))
+  (set (make-local-variable 'comment-start) "# ")
+  (set (make-local-variable 'comment-end) "")
+  (set (make-local-variable 'comment-start-skip) "#+ *")
+  (set (make-local-variable 'comment-use-syntax) t)
+  (set (make-local-variable 'syntax-propertize-function)
+       #'elixir-syntax-propertize-function)
+  (set (make-local-variable 'imenu-generic-expression)
+       elixir-imenu-generic-expression)
+
+  (set (make-local-variable 'beginning-of-defun-function) #'elixir-beginning-of-defun)
+  (set (make-local-variable 'end-of-defun-function) #'elixir-end-of-defun)
+
+  (smie-setup elixir-smie-grammar 'verbose-elixir-smie-rules
+              :forward-token 'elixir-smie-forward-token
+              :backward-token 'elixir-smie-backward-token))
+
+;; Invoke elixir-mode when appropriate
+
+;;;###autoload
+(progn
+  (add-to-list 'auto-mode-alist '("\\.elixir\\'" . elixir-mode))
+  (add-to-list 'auto-mode-alist '("\\.ex\\'" . elixir-mode))
+  (add-to-list 'auto-mode-alist '("\\.exs\\'" . elixir-mode)))
+
+(provide 'elixir-mode)
+
+;;; elixir-mode.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245/elixir-mode.elc b/configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245/elixir-mode.elc
new file mode 100644
index 000000000000..ba82c31ff2c6
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245/elixir-mode.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245/elixir-smie.el b/configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245/elixir-smie.el
new file mode 100644
index 000000000000..c3b524a58175
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245/elixir-smie.el
@@ -0,0 +1,904 @@
+;;; elixir-smie.el --- Structural syntax support for elixir-mode
+
+;; Copyright 2011-2015 secondplanet
+;;           2013-2015 Samuel Tonini, Matt DeBoard, Andreas Fuchs
+
+;; This file is not a 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 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; if not, write to the Free Software
+;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+;;; Commentary:
+
+;;  Structural syntax support for elixir-mode
+
+;;; Code:
+
+(require 'smie)           ; Simple minded indentation engine
+(require 'cl-lib)         ; `cl-flet'
+
+;; HACK: Patch for Emacs 24.3 smie that fix
+;; https://github.com/elixir-lang/emacs-elixir/issues/107.
+;;
+;; defadvice is used to change the behavior only for elixir-mode.
+;; Definition of advice is a definition of corresponding function
+;; in Emacs 24.4.
+(when (and (= 24 emacs-major-version)
+           (= 3  emacs-minor-version))
+  (defadvice smie-rule-parent (around elixir-mode-patch activate)
+    (if (not (eq major-mode 'elixir-mode))
+        (progn ad-do-it)
+      (setq ad-return-value
+            (save-excursion
+              (goto-char (cadr (smie-indent--parent)))
+              (cons 'column
+                    (+ (or offset 0)
+                       (smie-indent-virtual)))))))
+
+  (defadvice smie-indent-comment (around elixir-mode-patch activate)
+    (if (not (eq major-mode 'elixir-mode))
+        (progn ad-do-it)
+      (setq ad-return-value
+            (and (smie-indent--bolp)
+                 (let ((pos (point)))
+                   (save-excursion
+                     (beginning-of-line)
+                     (and (re-search-forward comment-start-skip (line-end-position) t)
+                          (eq pos (or (match-end 1) (match-beginning 0))))))
+                 (save-excursion
+                   (forward-comment (point-max))
+                   (skip-chars-forward " \t\r\n")
+                   (unless
+                       (save-excursion
+                         (let ((next (funcall smie-forward-token-function)))
+                           (or (if (zerop (length next))
+                                   (or (eobp) (eq (car (syntax-after (point))) 5)))
+                               (rassoc next smie-closer-alist))))
+                     (smie-indent-calculate))))))))
+
+(defun elixir-smie-looking-around (back at)
+  "Check if looking backwards at BACK and forward at AT."
+  (and (looking-at-p at) (looking-back back)))
+
+;; Declare variable that we need from the smie package
+(defvar smie--parent)
+
+(defvar elixir-smie-verbose-p nil
+  "Emit context information about the current syntax state.")
+
+(defvar elixir-mode-syntax-table
+  (let ((table (make-syntax-table)))
+
+    ;; Note that ?_ might be better as class "_", but either seems to
+    ;; work:
+    (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 ?_ "_" table)
+    (modify-syntax-entry ?? "w" table)
+    (modify-syntax-entry ?~ "w" table)
+    (modify-syntax-entry ?! "_" table)
+    (modify-syntax-entry ?' "\"'" table)
+    (modify-syntax-entry ?\" "\"\"" table)
+    (modify-syntax-entry ?# "<" table)
+    (modify-syntax-entry ?\n ">" 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 ?@ "_" table)
+    table)
+  "Elixir mode syntax table.")
+
+(defconst elixir-smie-grammar
+  (smie-prec2->grammar
+   (smie-merge-prec2s
+    (smie-bnf->prec2
+     '((id)
+       (statements (statement)
+                   (statement ";" statements))
+       (statement (non-block-expr "fn" match-statements "end")
+                  (non-block-expr "do" statements "end")
+                  ("if" non-block-expr "do" statements "else" statements "end")
+                  ("if" non-block-expr "do" statements "end")
+                  ("if" non-block-expr "COMMA" "do:" non-block-expr)
+                  ("if" non-block-expr "COMMA"
+                   "do:" non-block-expr "COMMA"
+                   "else:" non-block-expr)
+                  ("try" "do" statements "after" statements "end")
+                  ("try" "do" statements "catch" match-statements "end")
+                  ("try" "do" statements "rescue" match-statements "end")
+                  ("try" "do" statements "end")
+                  ("case" non-block-expr "do" match-statements "end")
+                  ("for" non-block-expr "COMMA" "do:" non-block-expr)
+		  ("for" non-block-expr "COMMA" "into:" non-block-expr "COMMA" "do" statements "end")
+		  ("for" non-block-expr "COMMA" "into:" non-block-expr "COMMA" "do:" non-block-expr)
+		  ("with" non-block-expr "do" statements "else" statements "end")
+		  ("with" non-block-expr "do:" non-block-expr "COMMA" "else:" non-block-expr))
+       (non-block-expr (non-block-expr "OP" non-block-expr)
+                       ("(" non-block-expr ")")
+                       ("{" non-block-expr "}")
+                       ("[" non-block-expr "]")
+                       ("STRING"))
+       (match-statements (match-statement "MATCH-STATEMENT-DELIMITER"
+                                          match-statements)
+                         (match-statement))
+       (match-statement (non-block-expr "->" statements)))
+     '((assoc "if" "do:" "else:")
+       (assoc "COMMA")
+       (left "OP")))
+
+    (smie-precs->prec2
+     '((left "||")
+       (left "&&")
+       (nonassoc "=~" "===" "!==" "==" "!=" "<=" ">=" "<" ">")
+       (left "+" "-" "<<<" ">>>" "^^^" "~~~" "&&&" "|||")
+       (left "*" "/"))))))
+
+(defvar elixir-smie--operator-regexp
+  (rx (or "<<<" ">>>" "^^^" "~~~" "&&&" "|||" "===" "!==" "==" "!=" "<="
+          "=" ">=" "<" ">" "&&" "||" "<>" "++" "--" "//" "/>" "=~" "|>")))
+
+(defvar elixir-smie--binary-sequence-regexp
+  (rx (or "<<" ">>")))
+
+(defvar elixir-smie--block-operator-regexp
+  (rx "->" (0+ nonl)))
+
+(defvar elixir-smie--oneline-def-operator-regexp
+  (rx "do:" (0+ nonl)))
+
+(defvar elixir-smie--spaces-til-eol-regexp
+  (rx (and (1+ space) eol))
+  "Regex representing one or more whitespace characters concluding with eol.")
+
+(defvar elixir-smie--comment-regexp
+  (rx (and (0+ space) "#" (0+ not-newline)))
+  "Regex matching comments.")
+
+(defvar elixir-smie-indent-basic 2)
+
+(defmacro elixir-smie-debug (message &rest format-args)
+  `(progn
+     (when elixir-smie-verbose-p
+       (message (format ,message ,@format-args)))
+     nil))
+
+(defun elixir-smie--implicit-semi-p ()
+  (not (or (memq (char-before) '(?\{ ?\[))
+           (looking-back elixir-smie--operator-regexp (- (point) 3) t))))
+
+(defun elixir-smie-current-line-contains-built-in-keyword-p ()
+  "Return non-nil if the current line contains built in keywords with a `.'"
+  (save-excursion
+    (beginning-of-line)
+    (looking-at ".+\\.\\(case\\|try\\|if\\|rescue\\)")))
+
+(defun elixir-smie-last-line-end-with-block-operator-p ()
+  "Return non-nil if the previous line ends with a `->' operator."
+  (save-excursion
+    (forward-line -1)
+    (move-end-of-line 1)
+    (looking-back elixir-smie--block-operator-regexp (- (point) 3) t)))
+
+(defun elixir-smie-last-line-start-with-block-operator-p ()
+  (save-excursion
+    (forward-line -1)
+    (beginning-of-line)
+    (looking-at "^\s+->.+$")))
+
+(defun elixir-smie-current-line-start-with-pipe-operator-p ()
+  (save-excursion
+    (beginning-of-line)
+    (looking-at "^\s*|>.+$")))
+
+(defun elixir-smie-last-line-is-assignment-p ()
+  (save-excursion
+    (forward-line -1)
+    (beginning-of-line)
+    (looking-at "^.+=.+$")))
+
+(defun elixir-smie-last-line-start-with-pipe-operator-p ()
+  (save-excursion
+    (forward-line -1)
+    (beginning-of-line)
+    (looking-at "^\s*|>.+$")))
+
+(defun elixir-smie-line-starts-with-do-colon-p ()
+  (save-excursion
+    (beginning-of-line)
+    (looking-at "^\s+do:")))
+
+(defun elixir-smie--semi-ends-match ()
+  "Return non-nil if the current line concludes a match block."
+  (when (not (eobp))
+    (save-excursion
+      ;; Warning: Recursion.
+      ;; This is easy though.
+
+      ;; 1. If we're at a blank line, move forward a character. This takes us to
+      ;;    the next line.
+      ;; 2. If we're not at the end of the buffer, call this function again.
+      ;;    (Otherwise, return nil.)
+
+      ;; The point here is that we want to treat blank lines as a single semi-
+      ;; colon when it comes to detecting the end of match statements. This could
+      ;; also be handled by a `while' expression or some other looping mechanism.
+      (cl-flet ((self-call ()
+                           (if (< (point) (point-max))
+                               (elixir-smie--semi-ends-match)
+                             nil)))
+        (cond
+         ((and (eolp) (bolp))
+          (forward-char)
+          (self-call))
+         ((looking-at elixir-smie--spaces-til-eol-regexp)
+          (forward-char)
+          (self-call))
+         ;; And if we're NOT on a blank line, move to the end of the line, and see
+         ;; if we're looking back at a block operator.
+         (t (move-end-of-line 1)
+            (and (looking-back elixir-smie--block-operator-regexp)
+                 (not (looking-back ".+fn.+")))))))))
+
+(defun elixir-smie--same-line-as-parent (parent-pos child-pos)
+  "Return non-nil if `child-pos' is on same line as `parent-pos'."
+  (= (line-number-at-pos parent-pos) (line-number-at-pos child-pos)))
+
+(defun elixir-smie-forward-token ()
+  (cond
+   ;; If there is nothing but whitespace between the last token and eol, emit
+   ;; a semicolon.
+   ((looking-at elixir-smie--spaces-til-eol-regexp)
+    (goto-char (match-end 0))
+    ";")
+   ((and (or (looking-at elixir-smie--comment-regexp)
+             (looking-at "[\n#]"))
+         (elixir-smie--implicit-semi-p))
+    (if (eolp) (forward-char 1) (forward-comment 1))
+    ;; Note: `elixir-smie--semi-ends-match' will be called when the point is at
+    ;; the beginning of a new line. Keep that in mind.
+    (if (elixir-smie--semi-ends-match)
+        "MATCH-STATEMENT-DELIMITER"
+      (if (and (looking-at ".+,$")
+               (not (> (nth 0 (syntax-ppss)) 0)))
+          "COMMA"
+        ";")))
+   ((looking-at elixir-smie--block-operator-regexp)
+    (goto-char (match-end 0))
+    "->")
+   ((looking-at elixir-smie--operator-regexp)
+    (goto-char (match-end 0))
+    "OP")
+   (t
+    (let ((token (smie-default-forward-token)))
+      (unless (or (elixir-smie-empty-string-p token)
+		  (elixir-smie--at-dot-call))
+	token)))))
+
+(defun elixir-smie--at-dot-call ()
+  (and (eq ?w (char-syntax (following-char)))
+       (eq (char-before) ?.)
+       (not (eq (char-before (1- (point))) ?.))))
+
+(defun elixir-smie-backward-token ()
+  (let ((pos (point)))
+    (forward-comment (- (point)))
+    (cond
+     ((and (> pos (line-end-position))
+           (elixir-smie--implicit-semi-p))
+      (if (elixir-smie--semi-ends-match)
+          "MATCH-STATEMENT-DELIMITER"
+        (if (and (looking-back ",$" (- (point) 3) t)
+                 (not (> (nth 0 (syntax-ppss)) 0)))
+	    "COMMA"
+	  ";")))
+     ((looking-back elixir-smie--block-operator-regexp (- (point) 3) t)
+      (goto-char (match-beginning 0))
+      "->")
+     ((looking-back elixir-smie--binary-sequence-regexp (- (point) 3) t)
+      (goto-char (match-beginning 0))
+      "OP")
+     ((looking-back elixir-smie--operator-regexp (- (point) 3) t)
+      (goto-char (match-beginning 0))
+      "OP")
+     (t (let ((token (smie-default-backward-token)))
+          (unless (or (elixir-smie-empty-string-p token)
+                      (elixir-smie--at-dot-call))
+            token))))))
+
+(defun verbose-elixir-smie-rules (kind token)
+  (let ((value (elixir-smie-rules kind token)))
+    (elixir-smie-debug "%s '%s'; sibling-p:%s parent:%s prev-is-OP:%s hanging:%s == %s" kind token
+                       (ignore-errors (smie-rule-sibling-p))
+                       (ignore-errors smie--parent)
+                       (ignore-errors (smie-rule-prev-p "OP"))
+                       (ignore-errors (smie-rule-hanging-p))
+                       value)
+    value))
+
+(defun elixir-smie-rules (kind token)
+  (pcase (cons kind token)
+    (`(:list-intro . ";")
+     -4)
+    (`(:list-intro . nil)
+     -4)
+    (`(:elem . args)
+     -4)
+    (`(:before . "COMMA")
+     (cond
+      ((and (smie-rule-parent-p "with")
+            (smie-rule-hanging-p))
+       (smie-rule-parent 5))
+      ((and (smie-rule-parent-p ";")
+            (smie-rule-hanging-p))
+       (smie-rule-parent))
+      ((and (smie-rule-parent-p "COMMA")
+            (smie-rule-hanging-p))
+       (if (save-excursion
+	     (forward-line 1)
+	     (move-beginning-of-line 1)
+	     (looking-at "^.+do:.+$"))
+	   (smie-rule-parent -5)
+	 (smie-rule-parent)))
+      ((and (smie-rule-parent-p "COMMA")
+            (not (smie-rule-hanging-p)))
+       (smie-rule-parent elixir-smie-indent-basic))
+      ((smie-rule-parent-p "(")
+       (smie-rule-parent))
+      ((smie-rule-parent-p "if")
+       (smie-rule-parent))
+      ((smie-rule-parent-p "->")
+       (smie-rule-parent))))
+    (`(:after . "COMMA")
+     (cond
+      ((and (smie-rule-parent-p ";")
+            (smie-rule-hanging-p))
+       (smie-rule-parent elixir-smie-indent-basic))
+      ((and (smie-rule-parent-p "with")
+            (smie-rule-hanging-p))
+       (smie-rule-parent 5))
+      ((and (smie-rule-parent-p "{")
+            (smie-rule-hanging-p))
+       (smie-rule-parent elixir-smie-indent-basic))
+      ((and (smie-rule-parent-p "[")
+            (smie-rule-hanging-p))
+       0)
+      ((smie-rule-parent-p "COMMA")
+       (smie-rule-parent elixir-smie-indent-basic))
+      ((smie-rule-parent-p "->")
+       (smie-rule-parent elixir-smie-indent-basic))
+      (t (smie-rule-parent elixir-smie-indent-basic))))
+    (`(:before . "OP")
+     (cond
+      ((smie-rule-parent-p "for")
+       (smie-rule-parent))
+      ((and (not (smie-rule-hanging-p))
+            (elixir-smie-current-line-start-with-pipe-operator-p)
+            (elixir-smie-last-line-is-assignment-p))
+       (smie-rule-parent))
+      ((and (not (smie-rule-hanging-p))
+            (elixir-smie-current-line-start-with-pipe-operator-p))
+       (cons 'column  (elixir-smie--previous-line-indentation)))
+      ((and (not (smie-rule-hanging-p))
+            (smie-rule-prev-p "OP"))
+       (- elixir-smie-indent-basic))
+      ((smie-rule-parent-p "def" "defp" "defmacro" "defmacrop")
+       (smie-rule-parent))
+      (t (smie-rule-parent))))
+    (`(:after . "OP")
+     (cond
+      ((smie-rule-sibling-p) nil)
+      ((smie-rule-hanging-p)
+       (smie-rule-parent elixir-smie-indent-basic))
+      ((and (not (smie-rule-sibling-p))
+            (not (smie-rule-hanging-p))
+            (smie-rule-parent-p "do:"))
+       (smie-rule-parent))
+      ((smie-rule-parent-p ";")
+       (smie-rule-parent))
+      (t (smie-rule-parent (- elixir-smie-indent-basic)))))
+    (`(:before . "MATCH-STATEMENT-DELIMITER")
+     (cond
+      ((and (smie-rule-parent-p "do")
+            (smie-rule-hanging-p))
+       (smie-rule-parent))
+      ((and (smie-rule-parent-p "do")
+            (not (smie-rule-hanging-p)))
+       (smie-rule-parent elixir-smie-indent-basic))
+      ((and (smie-rule-parent-p "fn"))
+       (smie-rule-parent elixir-smie-indent-basic))
+      ;; There is a case when between two line inside a def block
+      ;; when jumping to the next line and indent, where the cursor
+      ;; jumps too much in front.
+      ;;
+      ;; Example:
+      ;; def generate_pkg(path, opts) do
+      ;;   name = Path.basename(Path.expand(path))
+      ;;
+      ;;   File.mkdir_p!(path)
+      ;;                              <-
+      ;;   File.cd! path, fn ->
+      ;;     _generate_pkg(name, opts)
+      ;;   end
+      ;; end
+      ((and (smie-rule-parent-p "do")
+            (not (smie-rule-hanging-p)))
+       0)
+      ((and (not (smie-rule-sibling-p))
+            (nth 2 smie--parent)
+            (smie-rule-hanging-p))
+       (smie-rule-parent elixir-smie-indent-basic))
+      ((and (not (smie-rule-sibling-p))
+            (not (nth 2 smie--parent))
+            (smie-rule-hanging-p))
+       (smie-rule-parent))))
+    (`(:after . "MATCH-STATEMENT-DELIMITER")
+     (cond
+      ((and (smie-rule-parent-p "MATCH-STATEMENT-DELIMITER")
+            (smie-rule-hanging-p)
+            (smie-rule-sibling-p))
+       (smie-rule-parent))
+      ((and (smie-rule-parent-p "after")
+            (smie-rule-hanging-p))
+       (smie-rule-parent elixir-smie-indent-basic))
+      ;; Correct indentation after a one-line fn definition
+      ;; Example:
+      ;;
+      ;;  sum = Enum.reduce(dbms, fn(x, sum) -> x + sum end)
+      ;;  average_dbm = sum / length(addresses)
+      ((smie-rule-parent-p "fn")
+       (smie-rule-parent elixir-smie-indent-basic))
+      (t
+       (smie-rule-parent))))
+    (`(:before . "fn")
+     (cond
+      ((smie-rule-parent-p "(")
+       (smie-rule-parent))
+      (t (smie-rule-parent))))
+    (`(:before . "for")
+     (cond
+      ((elixir-smie-last-line-end-with-block-operator-p)
+       (smie-rule-parent elixir-smie-indent-basic))
+      ((and (smie-rule-parent-p ";")
+	    (smie-rule-prev-p "OP"))
+       (smie-rule-parent))
+      ((smie-rule-prev-p "OP" "def")
+       (smie-rule-parent -2))))
+    (`(:before . "into:")
+     (cond
+      ((smie-rule-parent-p "COMMA")
+       (smie-rule-parent elixir-smie-indent-basic))))
+    (`(:before . "do:")
+     (cond
+      ((smie-rule-parent-p "def" "defp" "defmacro" "defmacrop")
+       (if (save-excursion
+	     (move-beginning-of-line 1)
+	     (looking-at "^\s*do:.+$"))
+	   (smie-rule-parent)
+	 (smie-rule-parent)))
+      ;; Example
+      ;;
+      ;; hi = for i <- list, do: i
+      ;; # weird spacing now <- Indent
+      ;;
+      ;; for i <- list, do: i
+      ;; IO.puts 'WORKED' <- Indent
+      ((and (smie-rule-parent-p "for")
+            (not (smie-rule-hanging-p)))
+       (smie-rule-parent))
+      ((and (smie-rule-parent-p ";")
+            (not (smie-rule-hanging-p))
+	    (save-excursion
+	      (move-beginning-of-line 1)
+	      (looking-at "^\s*do:.+$")))
+       (if (> (nth 0 (syntax-ppss)) 0)
+	   (smie-rule-parent (- 3))
+	 (smie-rule-parent elixir-smie-indent-basic)))
+      ((and (smie-rule-parent-p ";")
+            (not (smie-rule-hanging-p)))
+       (if (> (nth 0 (syntax-ppss)) 0)
+	   (smie-rule-parent (- elixir-smie-indent-basic))
+	 (smie-rule-parent)))
+      ((and (smie-rule-parent-p "OP")
+            (not (smie-rule-hanging-p)))
+       (smie-rule-parent elixir-smie-indent-basic))
+      ((and (smie-rule-parent-p "COMMA")
+            (not (smie-rule-hanging-p)))
+       (smie-rule-parent elixir-smie-indent-basic))))
+    (`(:before . "do")
+     (cond
+      ((and (smie-rule-parent-p "for")
+            (smie-rule-hanging-p))
+       (if (save-excursion
+	     (move-beginning-of-line 1)
+	     (looking-at "^.+\sfor\s.+\sdo\s*"))
+	   (smie-rule-parent elixir-smie-indent-basic)
+	 (smie-rule-parent (+ elixir-smie-indent-basic
+			      elixir-smie-indent-basic))))
+      ((and (smie-rule-parent-p "case")
+            (smie-rule-hanging-p))
+       (smie-rule-parent elixir-smie-indent-basic))
+      ;; There is a case when between two line inside a def block
+      ;; when jumping to the next line and indent, where the cursor
+      ;; jumps too much in front.
+      ;;
+      ;; Example:
+      ;; def generate_pkg(path, opts) do
+      ;;   name = Path.basename(Path.expand(path))
+      ;;
+      ;;   File.mkdir_p!(path)
+      ;;                              <-
+      ;;   File.cd! path, fn ->
+      ;;     _generate_pkg(name, opts)
+      ;;   end
+      ;; end
+      ((and (smie-rule-parent-p "def")
+            (smie-rule-hanging-p))
+       (smie-rule-parent elixir-smie-indent-basic))
+      (t elixir-smie-indent-basic)))
+    (`(:before . "end")
+     (cond
+      ((smie-rule-parent-p "for")
+       (smie-rule-parent))
+      ((smie-rule-parent-p "(")
+       (smie-rule-parent))
+      (t (smie-rule-parent))))
+    (`(:before . "else:")
+     (cond
+      ((smie-rule-parent-p ";")
+       (if (> (nth 0 (syntax-ppss)) 0)
+	   (smie-rule-parent elixir-smie-indent-basic)
+	 (smie-rule-parent)))
+      ((smie-rule-parent-p "if")
+       (smie-rule-parent elixir-smie-indent-basic))
+      (t (smie-rule-parent))))
+    ;; Closing paren on the other line
+    (`(:before . "(")
+     (cond
+      ((smie-rule-parent-p "fn")
+       (smie-rule-parent elixir-smie-indent-basic))
+      ;; Indent parenthesis correctly inside a block
+      ;;
+      ;; Example:
+      ;;
+      ;; def bar do
+      ;;   ()
+      ;; .....
+      ((smie-rule-parent-p "do")
+       (smie-rule-parent))
+      ((smie-rule-parent-p "OP")
+       (smie-rule-parent))
+      ((and (smie-rule-parent-p "with")
+	    (smie-rule-hanging-p))
+       (smie-rule-parent))
+      ((and (smie-rule-parent-p "with")
+	    (not (smie-rule-hanging-p)))
+       (smie-rule-parent 3))
+      ((smie-rule-parent-p ";")
+       (smie-rule-parent))
+      (t (smie-rule-parent))))
+    (`(:before . "[")
+     (cond
+      ((smie-rule-hanging-p)
+       (smie-rule-parent))))
+    (`(:before . "{")
+     (cond
+      ((smie-rule-parent-p "COMMA")
+       (smie-rule-parent))
+      ;; Example
+      ;;
+      ;; case parse do
+      ;;   { [ help: true ], _, _ }
+      ;;     -> :help
+      ;;   { _, [ user, project, count ], _ }
+      ((and (not (smie-rule-hanging-p))
+            (smie-rule-parent-p "do"))
+       ;; If the last line ends with a block operator `->'
+       ;; indent two spaces more
+       ;;
+       ;; Example
+       ;;
+       ;; case File.read("/usr/share/dict/words") do
+       ;;   {:ok, contents} ->
+       ;;     {:something, contents} <- Indent here two spaces
+       ;;   ...
+       (if (elixir-smie-last-line-end-with-block-operator-p)
+           (smie-rule-parent elixir-smie-indent-basic)))
+      ((and (smie-rule-parent-p "MATCH-STATEMENT-DELIMITER")
+            (not (smie-rule-hanging-p)))
+       (if (elixir-smie-last-line-end-with-block-operator-p)
+           (smie-rule-parent elixir-smie-indent-basic)
+         (if (elixir-smie-last-line-start-with-block-operator-p)
+             (smie-rule-parent (- elixir-smie-indent-basic))
+           (smie-rule-parent))))
+      ((and (smie-rule-parent-p "OP")
+            (smie-rule-hanging-p))
+       (smie-rule-parent))
+      ((smie-rule-parent-p ";")
+       (if (save-excursion
+             (move-end-of-line 1)
+             (looking-back elixir-smie--block-operator-regexp (- (point) 3) t))
+           (smie-rule-parent (- elixir-smie-indent-basic))
+         (if (save-excursion
+	       (move-beginning-of-line 1)
+	       (looking-at "^.+->.+$"))
+	     (smie-rule-parent (- elixir-smie-indent-basic))
+	   (smie-rule-parent))))))
+    (`(:after . "{")
+     (cond
+      ((smie-rule-hanging-p)
+       (smie-rule-parent elixir-smie-indent-basic))
+      (t elixir-smie-indent-basic)))
+    (`(:after . "[")
+     (cond
+      ((smie-rule-hanging-p)
+       (smie-rule-parent elixir-smie-indent-basic))
+      (t elixir-smie-indent-basic)))
+    (`(:before . "if")
+     (cond
+      ;; Indent when if is inside a `->' block
+      ;;
+      ;; Example:
+      ;;
+      ;; whatever ->
+      ;;   if true do <-
+      ;;     :foo
+      ;;   end
+      ;;   ....
+      ((elixir-smie-last-line-end-with-block-operator-p)
+       (smie-rule-parent elixir-smie-indent-basic))
+      ;; Indent if inside else
+      ;;
+      ;; Example:
+      ;;
+      ;; else
+      ;;   if condition, do: :bar <-
+      ;; end
+      ((smie-rule-parent-p "else")
+       (smie-rule-parent elixir-smie-indent-basic))
+      (t (smie-rule-parent))))
+    (`(:before . "->")
+     (cond
+      ;; Example
+      ;;
+      ;; receive do
+      ;; after
+      ;;   2000 ->
+      ;;     IO.puts 'hello'
+      ;;     IO.puts 'status 2000 ends' <- Indent second line
+      ;;   { :ok } ->
+      ;;     ....
+      ((and (smie-rule-parent-p "after")
+            (not (smie-rule-sibling-p)))
+       (smie-rule-parent (+ elixir-smie-indent-basic
+                            elixir-smie-indent-basic)))
+      ;; Example
+      ;;
+      ;; case parse do
+      ;;   { [ help: true ], _, _ }
+      ;;     -> :help
+      ;;   ...
+      ((and (not (smie-rule-hanging-p))
+            (smie-rule-parent-p "do"))
+       elixir-smie-indent-basic)
+      ((and (not (smie-rule-hanging-p))
+            (smie-rule-parent-p "MATCH-STATEMENT-DELIMITER"))
+       (smie-rule-parent))
+      (t (smie-rule-parent elixir-smie-indent-basic))))
+    (`(:after . "->")
+     (cond
+      ;; This first condition is kind of complicated so I'll try to make this
+      ;; comment as clear as possible.
+
+      ;; "If `->' is the last thing on the line, and its parent token
+      ;; is `fn' ..."
+      ((and (smie-rule-hanging-p)
+            (smie-rule-parent-p "fn"))
+       ;; "... and if:
+
+       ;; 1. `smie--parent' is non-nil
+       ;; 2. the `->' token in question is on the same line as its parent (if
+       ;;    the logic has gotten this far, its parent will be `fn')
+
+       ;; ... then indent the line after the `->' aligned with the
+       ;; parent, offset by `elixir-smie-indent-basic'."
+       (if (and smie--parent (elixir-smie--same-line-as-parent
+                              (nth 1 smie--parent)
+                              (point)))
+           (smie-rule-parent elixir-smie-indent-basic)
+         elixir-smie-indent-basic))
+      ;; Otherwise, if just indent by two.
+      ((smie-rule-hanging-p)
+       (cond
+        ((smie-rule-parent-p "catch" "rescue" "else")
+         (smie-rule-parent (+ elixir-smie-indent-basic
+                              elixir-smie-indent-basic)))
+        ((smie-rule-parent-p "do" "try")
+         (smie-rule-parent elixir-smie-indent-basic))
+        ;; Example
+        ;;
+        ;; receive do
+        ;; after
+        ;;   2000 ->
+        ;;     IO.puts 'hello' <- Indent two spaces
+        ((and (smie-rule-parent-p "after")
+              (smie-rule-hanging-p)
+              (not (smie-rule-sibling-p)))
+         (smie-rule-parent (+ elixir-smie-indent-basic
+                              elixir-smie-indent-basic)))
+        (t (smie-rule-parent elixir-smie-indent-basic))))))
+    (`(:before . ";")
+     (cond
+      ;; Handle cases where built in keywords are used
+      ;; as function names.
+      ;;
+      ;; Example:
+      ;;
+      ;; def foo(test) do
+      ;;   test_case = test.case
+      ;;   run(test_case)
+      ;; end
+      ((and (smie-rule-parent-p "case" "try" "rescue")
+            (smie-rule-hanging-p)
+            (elixir-smie-current-line-contains-built-in-keyword-p))
+       (+ (- (cdr (smie-rule-parent))) (+ elixir-smie-indent-basic
+                                          elixir-smie-indent-basic)))
+      ;; There is a case after an one line definition of functions/macros
+      ;; when an `if' keyword token is involved, where the next block `end'
+      ;; token will have a `if' as parent and it's hanging.
+      ;;
+      ;; Example:
+      ;;
+      ;; defmacro my_if(expr, do: if_block), do: if(expr, do: if_block, else: nil)
+      ;; defmacro my_if(expr, do: if_block, else: else_block) do
+      ;;   ...
+      ;; end <- parent is `if`
+      ((and (smie-rule-parent-p "if")
+            (smie-rule-hanging-p))
+       (smie-rule-parent))
+      ((and (smie-rule-parent-p "else")
+            (smie-rule-hanging-p))
+       (smie-rule-parent elixir-smie-indent-basic))
+      ((smie-rule-parent-p "catch" "def" "defmodule" "defp" "do" "else"
+                           "fn" "if" "rescue" "try" "unless" "defmacro" "defmacrop")
+       (smie-rule-parent))
+      ((smie-rule-parent-p "after")
+       (smie-rule-parent elixir-smie-indent-basic))
+      ;; Example
+      ;;
+      ;; case parse do
+      ;;   { [ help: true ], _, _ }
+      ;;     -> :help
+      ;;   { _, [ user, project, count ], _ }
+      ;;     -> { user, project, count }
+      ;;   ...
+      ((and (smie-rule-parent-p "->")
+            (smie-rule-hanging-p))
+       (smie-rule-parent))
+      ((and (smie-rule-parent-p ";")
+      	    (smie-rule-hanging-p)
+      	    (save-excursion
+      	      (move-beginning-of-line 1)
+      	      (looking-at "^\s+else:.+$"))
+      	    (not (save-excursion
+      	      (move-beginning-of-line 1)
+      	      (looking-at "^\s+else:.+)$"))))
+       (smie-rule-parent (- elixir-smie-indent-basic)))
+      ((and (smie-rule-parent-p ";")
+	    (save-excursion
+	      (move-beginning-of-line 1)
+	      (looking-at "^.+,$")))
+       (smie-rule-parent))
+      ((and (smie-rule-parent-p ";")
+      	    (smie-rule-hanging-p)
+      	    (save-excursion
+      	      (move-beginning-of-line 1)
+      	      (looking-at "^\s+do:.+$"))
+      	    (not (save-excursion
+		   (move-beginning-of-line 1)
+		   (looking-at "^\s+do:.+)$"))))
+       (smie-rule-parent))
+      ((elixir-smie-current-line-start-with-pipe-operator-p)
+       (smie-rule-parent))
+      ((smie-rule-parent-p "(")
+       (smie-rule-parent elixir-smie-indent-basic))))
+    (`(:after . ";")
+     (cond
+      ((smie-rule-parent-p "def")
+       (smie-rule-parent))
+      ((and (smie-rule-parent-p "if")
+            (elixir-smie-current-line-contains-built-in-keyword-p))
+       (+ (- (cdr (smie-rule-parent))) (+ elixir-smie-indent-basic
+                                          elixir-smie-indent-basic)))
+      ((smie-rule-parent-p "if")
+       (smie-rule-parent))
+      ((smie-rule-parent-p "after")
+       (smie-rule-parent elixir-smie-indent-basic))
+      ((and (smie-rule-parent-p "(")
+            (boundp 'smie--parent)
+            (save-excursion
+              (goto-char (cadr smie--parent))
+              (smie-rule-hanging-p)))
+       (smie-rule-parent elixir-smie-indent-basic))))))
+
+(defun elixir-smie--heredoc-at-current-point-p ()
+  "Return non-nil if cursor is at a string."
+  (save-excursion
+    (or (and (nth 3 (save-excursion
+                      (let ((pos (point)))
+                        (parse-partial-sexp 1 pos))))
+             (nth 8 (save-excursion
+                      (let ((pos (point)))
+                        (parse-partial-sexp 1 pos)))))
+        (and (looking-at "\"\"\"")
+             (match-beginning 0)))))
+
+(defun elixir-smie--previous-line-empty-p ()
+  "Return non-nil if the previous line is blank."
+  (save-excursion
+    (forward-line -1)
+    (move-beginning-of-line 1)
+    (looking-at "[[:space:]]*$")))
+
+(defun elixir-smie--previous-line-indentation ()
+  "Return the indentation of the previous line."
+  (save-excursion
+    (forward-line -1)
+    (current-indentation)))
+
+;; Add the custom function to handle indentation inside heredoc to the
+;; smie-indent-functions list. The indentation function will only be
+;; process inside an elixir-mode.
+(defun elixir-smie--indent-inside-heredoc ()
+  "Handle indentation inside Elixir heredocs.
+
+Rules:
+  1. If the previous line is empty, indent as the basic indentation
+     at the beginning of the heredoc.
+  2. If the previous line is not empty, indent as the previous line.
+"
+  (if (eq major-mode 'elixir-mode)
+      (if (elixir-smie--heredoc-at-current-point-p)
+          (let ((indent
+                 (save-excursion
+                   (when (re-search-backward "^\\(\s+\\)\\(@doc\\|@moduledoc\\|.*\\)\"\"\"" nil t)
+                     (string-width (match-string 1))))))
+	    (cond
+	     ((elixir-smie--previous-line-empty-p)
+	      (goto-char indent))
+	     ((and (not (save-excursion (looking-at "\"\"\"")))
+		   (not (elixir-smie--previous-line-empty-p)))
+	      (goto-char (elixir-smie--previous-line-indentation)))
+	     (indent
+	      (goto-char indent)))))))
+
+(defun elixir-smie-empty-string-p (string)
+  "Return non-nil if STRING is null, blank or whitespace only."
+  (or (null string)
+      (string= string "")
+      (if (string-match-p "^\s+$" string) t)))
+
+(add-to-list 'smie-indent-functions 'elixir-smie--indent-inside-heredoc)
+
+(provide 'elixir-smie)
+
+;;; elixir-smie.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245/elixir-smie.elc b/configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245/elixir-smie.elc
new file mode 100644
index 000000000000..faa1d24f249f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245/elixir-smie.elc
Binary files differ