|
1 | 1 | ;;; elixir-mode.el --- Major mode for editing Elixir files
|
2 | 2 |
|
3 | 3 | ;; Copyright (c) 2011 secondplanet
|
4 |
| -;; Author: Humza Yaqoob |
5 |
| -;; URL: https://github.com/secondplanet/elixir-mode |
| 4 | +;; Author: Humza Yaqoob, Andreas Fuchs <[email protected]> |
| 5 | +;; URL: https://github.com/elixir-lang/emacs-elixir |
6 | 6 | ;; Created: Mon Nov 7 2011
|
7 | 7 | ;; Keywords: languages elixir
|
8 |
| -;; Version: 1.0.0 |
| 8 | +;; Version: 1.1.0 |
9 | 9 |
|
10 | 10 | ;; This file is not a part of GNU Emacs.
|
11 | 11 |
|
|
26 | 26 | ;;; Commentary:
|
27 | 27 |
|
28 | 28 | ;; Provides font-locking, indentation support, and navigation for Elixir programs.
|
| 29 | +;; |
| 30 | +;; To install, add the put this directory on the `load-path', and load |
| 31 | +;; `elixir-mode-setup.el'. Then, run: |
| 32 | +;; |
| 33 | +;; (elixir-mode-setup) |
| 34 | +;; |
| 35 | +;; To auto-load the mode and set up file associations. |
29 | 36 |
|
30 | 37 | ;;; Code:
|
31 | 38 |
|
32 |
| -(require 'comint) ; for interactive REPL |
33 |
| -(require 'easymenu) ; for menubar features |
| 39 | +(require 'comint) ; for interactive REPL |
| 40 | +(require 'easymenu) ; for menubar features |
34 | 41 |
|
35 |
| -(defconst elixir-mode-version "1.0.0" |
36 |
| - "Elixir mode version number.") |
37 |
| -(defconst elixir-mode-date "2011-11-12" |
38 |
| - "Elixir mode version date.") |
| 42 | +(require 'elixir-smie) ; syntax and indentation support |
| 43 | +(require 'elixir-mode-setup) ; Contains only the elixir-mode-setup function. |
39 | 44 |
|
| 45 | +;;;###autoload |
40 | 46 | (defvar elixir-mode-hook nil)
|
| 47 | + |
| 48 | +;;;###autoload |
41 | 49 | (defvar elixir-mode-map (make-keymap)
|
42 | 50 | "Elixir mode keymap.")
|
43 | 51 |
|
44 | 52 | (defgroup elixir nil
|
45 |
| - "Elixir major mode." |
46 |
| - :group 'languages) |
| 53 | + "Elixir major mode." |
| 54 | + :group 'languages) |
47 | 55 |
|
48 | 56 | (defcustom elixir-compiler-command "elixirc"
|
49 |
| - "Elixir mode command to compile code. Must be in your path." |
50 |
| - :type 'string |
51 |
| - :group 'elixir) |
| 57 | + "Elixir mode command to compile code. Must be in your path." |
| 58 | + :type 'string |
| 59 | + :group 'elixir) |
52 | 60 |
|
53 | 61 | (defcustom elixir-iex-command "iex"
|
54 |
| - "Elixir mode command for interactive REPL. Must be in your path." |
55 |
| - :type 'string |
56 |
| - :group 'elixir) |
| 62 | + "Elixir mode command for interactive REPL. Must be in your path." |
| 63 | + :type 'string |
| 64 | + :group 'elixir) |
57 | 65 |
|
58 | 66 | (defcustom elixir-mode-highlight-operators t
|
59 |
| - "Elixir mode option for whether or not to highlight operators." |
60 |
| - :type 'boolean |
61 |
| - :group 'elixir) |
| 67 | + "Elixir mode option for whether or not to highlight operators." |
| 68 | + :type 'boolean |
| 69 | + :group 'elixir) |
62 | 70 |
|
63 | 71 | (defcustom elixir-mode-cygwin-paths t
|
64 |
| - "Elixir mode use Cygwin style paths on Windows operating systems." |
65 |
| - :type 'boolean |
66 |
| - :group 'elixir) |
| 72 | + "Elixir mode use Cygwin style paths on Windows operating systems." |
| 73 | + :type 'boolean |
| 74 | + :group 'elixir) |
67 | 75 |
|
68 | 76 | (defcustom elixir-mode-cygwin-prefix "/cygdrive/C"
|
69 |
| - "Elixir mode Cygwin prefix." |
70 |
| - :type 'string |
71 |
| - :group 'elixir) |
| 77 | + "Elixir mode Cygwin prefix." |
| 78 | + :type 'string |
| 79 | + :group 'elixir) |
72 | 80 |
|
73 | 81 | (defvar elixir-mode-define-names
|
74 | 82 | '("def"
|
|
207 | 215 |
|
208 | 216 | (defvar font-lock-operator-face 'font-lock-operator-face)
|
209 | 217 | (defface font-lock-operator-face
|
210 |
| - '((((type tty) (class color)) nil) |
211 |
| - (((class color) (background light)) |
212 |
| - (:foreground "darkred")) |
213 |
| - (t nil)) |
214 |
| - "For use with operators." |
215 |
| - :group 'font-lock-faces) |
| 218 | + '((((type tty) (class color)) nil) |
| 219 | + (((class color) (background light)) |
| 220 | + (:foreground "darkred")) |
| 221 | + (t nil)) |
| 222 | + "For use with operators." |
| 223 | + :group 'font-lock-faces) |
216 | 224 |
|
217 | 225 | (defconst elixir-mode-font-lock-defaults
|
218 | 226 | (list
|
219 |
| - '("#.*$" . font-lock-comment-face) ; comments |
220 |
| - `(,(concat "^\\s *\\<" (regexp-opt elixir-mode-define-names t) "\\>\\s +\\([^( \t\n]+\\)") 2 font-lock-function-name-face) ; methods |
221 |
| - `(,(concat "\\<" (regexp-opt elixir-mode-keyword-names t) "\\>") . font-lock-keyword-face) ; keywords |
222 |
| - `(,(concat "\\<" (regexp-opt elixir-mode-builtin-names t) "\\>") . font-lock-builtin-face) ; builtins |
223 |
| - `(,(concat "\\<" (regexp-opt elixir-mode-module-names t) "\\>") . font-lock-type-face) ; core modules |
224 |
| - (when elixir-mode-highlight-operators `(,(concat "\\<" (regexp-opt elixir-mode-operator-names t) "\\>") . font-lock-operator-face)) ; operators |
225 |
| - '("\\(\\w*\\)\\s-*:?=" . font-lock-variable-name-face) ; variables |
226 |
| - '("-[Rr].*[ \n\t]" . font-lock-constant-face) ; regexes |
227 |
| - '("\\<\\(true\\|false\\|nil\\)\\>" . font-lock-reference-face) ; atoms, boolean |
228 |
| - '("\\w*:\s" . font-lock-reference-face) |
229 |
| - '(":\\w*" . font-lock-reference-face)) ; atoms, generic |
230 |
| -"Highlighting for Elixir mode.") |
| 227 | + ;; comments: |
| 228 | + '("#.*$" . font-lock-comment-face) |
| 229 | + |
| 230 | + ;; methods: |
| 231 | + `(,(concat "^\\s *\\<" (regexp-opt elixir-mode-define-names t) "\\>\\s +\\([^( \t\n]+\\)") 2 font-lock-function-name-face) |
| 232 | + |
| 233 | + ;; keywords: |
| 234 | + `(,(concat "\\<" (regexp-opt elixir-mode-keyword-names t) "\\>") . font-lock-keyword-face) |
| 235 | + |
| 236 | + ;; builtins: |
| 237 | + `(,(concat "\\<" (regexp-opt elixir-mode-builtin-names t) "\\>") . font-lock-builtin-face) |
| 238 | + |
| 239 | + ;; core modules: |
| 240 | + `(,(concat "\\<" (regexp-opt elixir-mode-module-names t) "\\>") . font-lock-type-face) |
| 241 | + |
| 242 | + ;; operators: |
| 243 | + (when elixir-mode-highlight-operators |
| 244 | + `(,(concat "\\<" (regexp-opt elixir-mode-operator-names t) "\\>") . font-lock-operator-face)) |
| 245 | + |
| 246 | + ;; variables: |
| 247 | + '("\\(\\w*\\)\\s-*:?=" . font-lock-variable-name-face) |
| 248 | + |
| 249 | + ;; regexes: |
| 250 | + '("-[Rr].*[ \n\t]" . font-lock-constant-face) |
| 251 | + |
| 252 | + ;; atoms, boolean: |
| 253 | + '("\\<\\(true\\|false\\|nil\\)\\>" . font-lock-reference-face) |
| 254 | + |
| 255 | + ;; atoms, generic |
| 256 | + '(":\\w*" . font-lock-reference-face) |
| 257 | + '("\\w*:\s" . font-lock-reference-face) |
| 258 | + '(":\\w*" . font-lock-reference-face)) |
| 259 | + "Highlighting for Elixir mode.") |
231 | 260 |
|
232 | 261 | (defun elixir-mode-cygwin-path (expanded-file-name)
|
233 |
| - "Elixir mode get Cygwin absolute path name." |
234 |
| - (replace-regexp-in-string "^[a-zA-Z]:" elixir-mode-cygwin-prefix expanded-file-name t)) |
| 262 | + "Elixir mode get Cygwin absolute path name." |
| 263 | + (replace-regexp-in-string "^[a-zA-Z]:" elixir-mode-cygwin-prefix expanded-file-name t)) |
235 | 264 |
|
236 | 265 | (defun elixir-mode-universal-path (file-name)
|
237 |
| - "Elixir mode multi-OS path handler." |
238 |
| - (let ((full-file-name (expand-file-name file-name))) |
239 |
| - (if (and (equal system-type 'windows-nt) |
240 |
| - elixir-mode-cygwin-paths) |
241 |
| - (elixir-mode-cygwin-path full-file-name) |
242 |
| - full-file-name))) |
| 266 | + "Elixir mode multi-OS path handler." |
| 267 | + (let ((full-file-name (expand-file-name file-name))) |
| 268 | + (if (and (equal system-type 'windows-nt) |
| 269 | + elixir-mode-cygwin-paths) |
| 270 | + (elixir-mode-cygwin-path full-file-name) |
| 271 | + full-file-name))) |
243 | 272 |
|
244 | 273 | (defun elixir-mode-command-compile (file-name)
|
245 | 274 | "Elixir mode command to compile a file."
|
246 |
| - (let ((full-file-name (elixir-mode-universal-path file-name))) |
247 |
| - (mapconcat 'identity (append (list elixir-compiler-command) (list full-file-name)) " "))) |
| 275 | + (let ((full-file-name (elixir-mode-universal-path file-name))) |
| 276 | + (mapconcat 'identity (append (list elixir-compiler-command) (list full-file-name)) " "))) |
248 | 277 |
|
249 | 278 | (defun elixir-mode-compiled-file-name (&optional filename)
|
250 | 279 | "Elixir mode compiled filename."
|
251 |
| - (concat (file-name-sans-extension (or filename (buffer-file-name))) ".beam")) |
| 280 | + (concat (file-name-sans-extension (or filename (buffer-file-name))) ".beam")) |
252 | 281 |
|
253 | 282 | (defun elixir-mode-compile-file ()
|
254 | 283 | "Elixir mode compile and save current file."
|
255 | 284 | (interactive)
|
256 |
| - (let ((compiler-output (shell-command-to-string (elixir-mode-command-compile (buffer-file-name))))) |
257 |
| - (when (string= compiler-output "") |
258 |
| - (message "Compiled and saved as %s" (elixir-mode-compiled-file-name))))) |
| 285 | + (let ((compiler-output (shell-command-to-string (elixir-mode-command-compile (buffer-file-name))))) |
| 286 | + (when (string= compiler-output "") |
| 287 | + (message "Compiled and saved as %s" (elixir-mode-compiled-file-name))))) |
259 | 288 |
|
260 | 289 | (defun elixir-mode-iex ()
|
261 | 290 | "Elixir mode interactive REPL."
|
262 |
| - (interactive) |
263 |
| - (unless (comint-check-proc "*IEX*") |
264 |
| - (set-buffer |
265 |
| - (apply 'make-comint "IEX" |
| 291 | + (interactive) |
| 292 | + (unless (comint-check-proc "*IEX*") |
| 293 | + (set-buffer |
| 294 | + (apply 'make-comint "IEX" |
266 | 295 | elixir-iex-command nil '())))
|
267 |
| - (pop-to-buffer "*IEX*")) |
| 296 | + (pop-to-buffer "*IEX*")) |
268 | 297 |
|
269 | 298 | (defun elixir-mode-open-modegithub ()
|
270 | 299 | "Elixir mode open GitHub page."
|
271 | 300 | (interactive)
|
272 |
| - (browse-url "https://github.com/secondplanet/elixir-mode")) |
| 301 | + (browse-url "https://github.com/elixir-lang/emacs-elixir")) |
273 | 302 |
|
274 | 303 | (defun elixir-mode-open-elixir-home ()
|
275 | 304 | "Elixir mode go to language home."
|
276 | 305 | (interactive)
|
277 |
| - (browse-url "https://github.com/josevalim/elixir#README")) |
| 306 | + (browse-url "http://elixir-lang.org")) |
278 | 307 |
|
279 | 308 | (defun elixir-mode-show-version ()
|
280 | 309 | "Elixir mode print version."
|
281 |
| - (interactive) |
282 |
| - (message (concat "elixir-mode v" elixir-mode-version " " elixir-mode-date " by Humza Yaqoob"))) |
283 |
| - |
284 |
| -(defvar elixir-mode-syntax-table |
285 |
| - (let ((elixir-mode-syntax-table (make-syntax-table))) |
286 |
| - (modify-syntax-entry ?_ "w" elixir-mode-syntax-table) |
287 |
| - (modify-syntax-entry ?' "\"" elixir-mode-syntax-table) |
288 |
| - (modify-syntax-entry ?# "<" elixir-mode-syntax-table) |
289 |
| - (modify-syntax-entry ?\n ">" elixir-mode-syntax-table) |
290 |
| - (modify-syntax-entry ?\( "()" elixir-mode-syntax-table) |
291 |
| - (modify-syntax-entry ?\) ")(" elixir-mode-syntax-table) |
292 |
| - (modify-syntax-entry ?\{ "(}" elixir-mode-syntax-table) |
293 |
| - (modify-syntax-entry ?\} "){" elixir-mode-syntax-table) |
294 |
| - (modify-syntax-entry ?\[ "(]" elixir-mode-syntax-table) |
295 |
| - (modify-syntax-entry ?\] ")[" elixir-mode-syntax-table) |
296 |
| - (modify-syntax-entry ?\: "'" elixir-mode-syntax-table) |
297 |
| - elixir-mode-syntax-table) |
298 |
| -"Elixir mode syntax table.") |
| 310 | + (interactive) |
| 311 | + (message (concat "elixir-mode v" elixir-mode-version " " elixir-mode-date " by Humza Yaqoob"))) |
299 | 312 |
|
300 | 313 | (easy-menu-define elixir-mode-menu elixir-mode-map
|
301 | 314 | "Elixir mode menu."
|
|
309 | 322 | ["About" elixir-mode-show-version]
|
310 | 323 | ))
|
311 | 324 |
|
| 325 | +;;;###autoload |
312 | 326 | (defun elixir-mode ()
|
313 | 327 | "Major mode for editing Elixir files."
|
314 | 328 | (interactive)
|
|
328 | 342 | (run-hooks 'prog-mode-hook))
|
329 | 343 |
|
330 | 344 | (define-minor-mode elixir-cos-mode
|
331 |
| - "Elixir mode toggle compile on save." |
332 |
| - :group 'elixir-cos :lighter " CoS" |
333 |
| - (cond |
334 |
| - (elixir-cos-mode |
335 |
| - (add-hook 'after-save-hook 'elixir-mode-compile-file nil t)) |
336 |
| - (t |
337 |
| - (remove-hook 'after-save-hook 'elixir-mode-compile-file t)))) |
338 |
| - |
339 |
| -(require 'elixir-smie) |
| 345 | + "Elixir mode toggle compile on save." |
| 346 | + :group 'elixir-cos :lighter " CoS" |
| 347 | + (cond |
| 348 | + (elixir-cos-mode |
| 349 | + (add-hook 'after-save-hook 'elixir-mode-compile-file nil t)) |
| 350 | + (t |
| 351 | + (remove-hook 'after-save-hook 'elixir-mode-compile-file t)))) |
340 | 352 |
|
341 | 353 | (provide 'elixir-mode)
|
342 |
| - |
343 |
| -;; automatically opening ex and exs in elixir-mode |
344 |
| -;;;###autoload |
345 |
| -(add-to-list 'auto-mode-alist '("\\.ex\\'" . elixir-mode)) |
346 |
| -;;;###autoload |
347 |
| -(add-to-list 'auto-mode-alist '("\\.exs\\'" . elixir-mode)) |
348 |
| - |
349 |
| - |
| 354 | +;;;*** |
| 355 | + |
| 356 | +;; Local variables: |
| 357 | +;; generated-autoload-file: elixir-mode-setup.el |
350 | 358 | ;;; elixir-mode.el ends here
|
0 commit comments