about summary refs log tree commit diff
path: root/configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245/elixir-smie.el
diff options
context:
space:
mode:
Diffstat (limited to 'configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245/elixir-smie.el')
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245/elixir-smie.el904
1 files changed, 0 insertions, 904 deletions
diff --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
deleted file mode 100644
index c3b524a58175..000000000000
--- a/configs/shared/emacs/.emacs.d/elpa/elixir-mode-20180711.1245/elixir-smie.el
+++ /dev/null
@@ -1,904 +0,0 @@
-;;; 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