Skip to content

elixir-editors/emacs-elixir

Folders and files

NameName
Last commit message
Last commit date

Latest commit

00d6580 · Jun 26, 2023
Feb 5, 2023
Mar 28, 2022
Mar 20, 2021
Jun 26, 2023
Mar 22, 2021
May 9, 2021
Jun 26, 2023
Feb 5, 2023
Jun 26, 2023
Mar 13, 2022

Repository files navigation

License GPL 3 Build Status NonGNU ELPA MELPA Stable MELPA

WARNING There is a built-in Elixir mode with tree-sitter support from Emacs 30+ that can also be used with Emacs 29 This repository is for an older elixir-mode built with SMIE (Simple Minded Indentation Engine) which is not as advanced as tree-sitter for a language like Elixir.

Elixir Mode

Provides font-locking, indentation and navigation support for the Elixir programming language.

Installation

elixir-mode is available on NON-GNU ELPA, MELPA STABLE and MELPA.

Via package.el

package.el is the built-in package manager in Emacs.

You can install elixir-mode with the following command:

M-x package-install [RET] elixir-mode [RET]

or by adding this bit of Emacs Lisp code to your Emacs initialization file (.emacs or init.el):

(unless (package-installed-p 'elixir-mode)
  (package-install 'elixir-mode))

If the installation doesn't work try refreshing the package list:

M-x package-refresh-contents [RET]

Keep in mind that MELPA packages are built automatically from the master branch, meaning bugs might creep in there from time to time. Never-the-less, installing from MELPA is the recommended way of obtaining Elixir-Mode.

MELPA Stable contains packages released from our tags.

Via use-package

Since Emacs 29, use-package is a built-in feature. For versions prior to 29 one can also install it from MELPA (and MELPA Stable).

To install elixir-mode using use-package one can:

(use-package elixir-mode
  :ensure t)

Usage

Interactive Commands

Command (For the M-x prompt.) Description
elixir-mode Switches to elixir-mode.
elixir-mode-open-github Open the GitHub page for Elixir.
elixir-mode-open-elixir-home Go to Elixir README in the browser.
elixir-mode-open-docs-master Open the Elixir documentation for the master.
elixir-mode-open-docs-stable Open the Elixir documentation for the latest stable release.
elixir-mode-show-version Print version info for elixir-mode.

Configuration

Any file that matches the glob *.ex[s] or *.elixir is automatically opened in elixir-mode, but you can change this functionality easily.

;; Highlights *.elixir2 as well
(add-to-list 'auto-mode-alist '("\\.elixir2\\'" . elixir-mode))

Keymapping

Keymaps can be added to the elixir-mode-map variable.

Pairing

Smartparens has direct support for Elixir.

Alternatively, if you want to use ruby-end-mode, you can add the following to your elixir-mode-hook:

(add-to-list 'elixir-mode-hook
             (defun auto-activate-ruby-end-mode-for-elixir-mode ()
               (set (make-variable-buffer-local 'ruby-end-expand-keywords-before-re)
                    "\\(?:^\\|\\s-+\\)\\(?:do\\)")
               (set (make-variable-buffer-local 'ruby-end-check-statement-modifiers) nil)
               (ruby-end-mode +1)))

Notes

This package is tested only with a single version of OTP and 3 versions of Elixir. Please, always report versions (Emacs, Elixir and Erlang/OTP) when raising issues.

Elixir Tooling Integration

You can use web-mode.el to edit elixir templates (eex files).

mix.el provides a minor mode for integration with Mix, a build tool that ships with Elixir.

exunit.el provides ExUnit integration.

Elixir Format

This mode can call mix for formatting code. When inside an elixir buffer, just type M-x elixir-format.

To automate that, you can add this command to the before-save hook.

;; Create a buffer-local hook to run elixir-format on save, only when we enable elixir-mode.
(add-hook 'elixir-mode-hook
          (lambda () (add-hook 'before-save-hook 'elixir-format nil t)))

To use a .formatter.exs you can either set elixir-format-arguments globally to a path like this:

(setq elixir-format-arguments (list "--dot-formatter" "/path/to/.formatter.exs"))

or you set elixir-format-arguments in a hook like this:

(add-hook 'elixir-format-hook (lambda ()
                                 (if (projectile-project-p)
                                      (setq elixir-format-arguments
                                            (list "--dot-formatter"
                                                  (concat (locate-dominating-file buffer-file-name ".formatter.exs") ".formatter.exs")))
                                   (setq elixir-format-arguments nil))))

In this example we use Projectile to determine if we are in a project and then set elixir-format-arguments accordingly.

Please note that this code snippet may cause unhappiness if there is no .formatter.exs file available.

Tips & Tricks

Prettify symbols

Emacs supports font ligatures. For enabling it for Elixir you can add it to your configuration:

(add-hook
 'elixir-mode-hook
 (lambda ()
   (push '(">=" . ?\u2265) prettify-symbols-alist)
   (push '("<=" . ?\u2264) prettify-symbols-alist)
   (push '("!=" . ?\u2260) prettify-symbols-alist)
   (push '("==" . ?\u2A75) prettify-symbols-alist)
   (push '("=~" . ?\u2245) prettify-symbols-alist)
   (push '("<-" . ?\u2190) prettify-symbols-alist)
   (push '("->" . ?\u2192) prettify-symbols-alist)
   (push '("<-" . ?\u2190) prettify-symbols-alist)
   (push '("|>" . ?\u25B7) prettify-symbols-alist)))
   
;; Or if you use use-packge

(use-package elixir-mode
 :hook (elixir-mode . (lambda ()
    (push '(">=" . ?\u2265) prettify-symbols-alist)
    (push '("<=" . ?\u2264) prettify-symbols-alist)
    (push '("!=" . ?\u2260) prettify-symbols-alist)
    (push '("==" . ?\u2A75) prettify-symbols-alist)
    (push '("=~" . ?\u2245) prettify-symbols-alist)
    (push '("<-" . ?\u2190) prettify-symbols-alist)
    (push '("->" . ?\u2192) prettify-symbols-alist)
    (push '("<-" . ?\u2190) prettify-symbols-alist)
    (push '("|>" . ?\u25B7) prettify-symbols-alist))))

Formatting

If you have issues with the formatter provided by this package, you can try using the format function of language servers. Elixir-ls supports this.

One way to configure this with eglot and use-package would be:

(use-package elixir-mode
 :hook (elixir-mode . eglot-ensure)
 (before-save . eglot-format))

Syntax highlighting for LiveView (and similar techniques for other syntaxes)

When you need different major modes in the SAME buffer, Emacs do not provide a standard way. There is an external package that can help here by adding more than one major mode called poly-mode.

A possible configuration would be:

;; Assumes web-mode and elixir-mode are already set up
;;
(use-package polymode
  :mode ("\.ex$" . poly-elixir-web-mode)
  :config
  (define-hostmode poly-elixir-hostmode :mode 'elixir-mode)
  (define-innermode poly-liveview-expr-elixir-innermode
    :mode 'web-mode
    :head-matcher (rx line-start (* space) "~H" (= 3 (char "\"'")) line-end)
    :tail-matcher (rx line-start (* space) (= 3 (char "\"'")) line-end)
    :head-mode 'host
    :tail-mode 'host
    :allow-nested nil
    :keep-in-mode 'host
    :fallback-mode 'host)
  (define-polymode poly-elixir-web-mode
    :hostmode 'poly-elixir-hostmode
    :innermodes '(poly-liveview-expr-elixir-innermode))
  )
(setq web-mode-engines-alist '(("elixir" . "\\.ex\\'")))

History

This mode is based on the Emacs mode by secondplanet.

Contributing

Please read CONTRIBUTING.md for guidelines on how to contribute to this project.

License

Copyright © 2011-2017 Samuel Tonini, Matt DeBoard, Andreas Fuchs, secondplanet and contributors.

Distributed under the GNU General Public License, version 3