mirror of https://github.com/Chizi123/.emacs.d.git

Chizi123
2018-11-18 c655eea759be1db69c5e6b45c228139d8390122a
commit | author | age
5cb5f7 1 ;;; smartparens-elixir.el --- Configuration for Elixir.  -*- lexical-binding: t; -*-
C 2
3 ;; Copyright (C) 2017 Matúš Goljer
4
5 ;; Author: Matúš Goljer <matus.goljer@gmail.com>
6 ;; Maintainer: Matúš Goljer <matus.goljer@gmail.com>
7 ;; Version: 0.0.1
8 ;; Created: 15th January 2017
9 ;; Keywords: languages
10
11 ;; This program is free software; you can redistribute it and/or
12 ;; modify it under the terms of the GNU General Public License
13 ;; as published by the Free Software Foundation; either version 3
14 ;; of the License, or (at your option) any later version.
15
16 ;; This program is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 ;; GNU General Public License for more details.
20
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
23
24 ;;; Commentary:
25
26 ;;; Code:
27
28 (require 'smartparens)
29
30 (--each '(elixir-mode)
31   (add-to-list 'sp-sexp-suffix (list it 'regexp "")))
32
33 (defun sp-elixir-def-p (id)
34   "Return non-nil if the \"do\" keyword is part of definition.
35
36 ID is the opening delimiter.
37
38 Definitions are the constructions of the form defmodule-do-end,
39 def-do-end and similar pairs."
40   (save-excursion
41     (when (equal "do" id)
42       (back-to-indentation)
43       (looking-at (regexp-opt '(
44                                 "defmodule"
45                                 "defmacro"
46                                 "defmacrop"
47                                 "quote"
48                                 "def"
49                                 "defp"
50                                 "if"
51                                 "unless"
52                                 "case"
53                                 "cond"
54                                 "with"
55                                 "for"
56                                 "receive"
57                                 "try"
58                                 ))))))
59
60 (defun sp-elixir-skip-def-p (ms _mb _me)
61   "Test if \"do\" is part of definition.
62 MS, MB, ME."
63   (sp-elixir-def-p ms))
64
65 (defun sp-elixir-do-block-post-handler (_id action _context)
66   "Insert \"do\" keyword and indent the new block.
67 ID, ACTION, CONTEXT."
68   (when (eq action 'insert)
69     (let ((m (make-marker)))
70       (save-excursion
71         (forward-word) ;; over the "end"
72         (move-marker m (point)))
73       (save-excursion (newline))
74       (save-excursion (insert " do"))
75       (indent-region (line-beginning-position) m)
76       (move-marker m nil nil))))
77
78 (defun sp-elixir-empty-do-block-post-handler (_id action _context)
79   "Insert empty \"do\" keyword and indent the new block.
80
81 This is used for receive-do-end expression.
82 ID, ACTION, CONTEXT."
83   (when (eq action 'insert)
84     (let ((m (make-marker)))
85       (save-excursion
86         (forward-word) ;; over the "end"
87         (move-marker m (point)))
88       (save-excursion
89         (forward-line -1)
90         (end-of-line)
91         (insert " do"))
92       (save-excursion (newline))
93       (indent-region (line-beginning-position) m)
94       (indent-according-to-mode)
95       (move-marker m nil nil))))
96
97 (sp-with-modes 'elixir-mode
98   (sp-local-pair "do" "end"
99                  :when '(("SPC" "RET" "<evil-ret>"))
100                  :skip-match 'sp-elixir-skip-def-p
101                  :unless '(sp-in-comment-p sp-in-string-p))
102   (sp-local-pair "def" "end"
103                  :when '(("SPC" "RET" "<evil-ret>"))
104                  :post-handlers '(sp-elixir-do-block-post-handler)
105                  :unless '(sp-in-comment-p sp-in-string-p))
106   (sp-local-pair "defp" "end"
107                  :when '(("SPC" "RET" "<evil-ret>"))
108                  :post-handlers '(sp-elixir-do-block-post-handler)
109                  :unless '(sp-in-comment-p sp-in-string-p))
110   (sp-local-pair "defmodule" "end"
111                  :when '(("SPC" "RET" "<evil-ret>"))
112                  :post-handlers '(sp-elixir-do-block-post-handler)
113                  :unless '(sp-in-comment-p sp-in-string-p))
114   (sp-local-pair "fn" "end"
115                  :when '(("SPC" "RET" "<evil-ret>"))
116                  :post-handlers '("| "))
117   (sp-local-pair "if" "end"
118                  :when '(("SPC" "RET" "<evil-ret>"))
119                  :post-handlers '(sp-elixir-do-block-post-handler)
120                  :unless '(sp-in-comment-p sp-in-string-p))
121   (sp-local-pair "unless" "end"
122                  :when '(("SPC" "RET" "<evil-ret>"))
123                  :post-handlers '(sp-elixir-do-block-post-handler)
124                  :unless '(sp-in-comment-p sp-in-string-p))
125   (sp-local-pair "case" "end"
126                  :when '(("SPC" "RET" "<evil-ret>"))
127                  :post-handlers '(sp-elixir-do-block-post-handler)
128                  :unless '(sp-in-comment-p sp-in-string-p))
129   (sp-local-pair "receive" "end"
130                  :when '(("RET" "<evil-ret>"))
131                  :post-handlers '(sp-elixir-empty-do-block-post-handler))
132   )
133
134 (provide 'smartparens-elixir)
135 ;;; smartparens-elixir.el ends here