├── .gitignore ├── README.org └── ob-elixir.el /.gitignore: -------------------------------------------------------------------------------- 1 | *.elc -------------------------------------------------------------------------------- /README.org: -------------------------------------------------------------------------------- 1 | * ob-elixir 2 | 3 | ** setup 4 | 5 | To use =ob-elixir= in an =org-babel= source block, the elixir language 6 | must be enabled in the custom =org-babel-load-languages= 7 | alist. Alternatively, running the following snippet during 8 | initialization will enable the mode. 9 | 10 | #+BEGIN_SRC emacs-lisp 11 | (org-babel-do-load-languages 12 | 'org-babel-load-languages 13 | '((emacs-lisp . t) 14 | (elixir . t))) 15 | #+END_SRC 16 | 17 | ** supported header arguments 18 | 19 | - cookie 20 | - name 21 | - remsh 22 | - sname 23 | - session 24 | 25 | ** examples 26 | 27 | *** connect to remote shell 28 | 29 | : #+BEGIN_SRC elixir :remsh name@node :sname console 30 | : Node.self 31 | : #+END_SRC 32 | : 33 | : #+RESULTS: 34 | : : :name@node 35 | -------------------------------------------------------------------------------- /ob-elixir.el: -------------------------------------------------------------------------------- 1 | ;;; ob-elixir.el --- org-babel functions for elixir evaluation 2 | 3 | ;; Copyright (C) 2015 ZHOU Feng 4 | 5 | ;; Author: ZHOU Feng 6 | ;; URL: http://github.com/zweifisch/ob-elixir 7 | ;; Keywords: org babel elixir 8 | ;; Version: 0.0.1 9 | ;; Created: 28th Sep 2015 10 | ;; Package-Requires: ((org "8")) 11 | 12 | ;; This file is free software; you can redistribute it and/or modify 13 | ;; it under the terms of the GNU General Public License as published by 14 | ;; the Free Software Foundation; either version 3, or (at your option) 15 | ;; any later version. 16 | 17 | ;; This file is distributed in the hope that it will be useful, 18 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | ;; GNU General Public License for more details. 21 | 22 | ;; You should have received a copy of the GNU General Public License 23 | ;; along with this program. If not, see . 24 | 25 | ;;; Commentary: 26 | ;; 27 | ;; org-babel functions for elixir evaluation 28 | ;; 29 | 30 | ;;; Code: 31 | (require 'ob) 32 | 33 | (defvar ob-elixir-process-output "") 34 | 35 | (defconst org-babel-header-args:elixir 36 | '((cookie . :any) 37 | (name . :any) 38 | (remsh . :any) 39 | (sname . :any)) 40 | "elixir header arguments") 41 | 42 | (defvar ob-elixir-eoe "\u2029") 43 | 44 | (add-to-list 'org-babel-tangle-lang-exts '("elixir" . "ex")) 45 | 46 | (defun org-babel-execute:elixir (body params) 47 | (let ((session (cdr (assoc :session params))) 48 | (tmp (org-babel-temp-file "elixir-"))) 49 | (ob-elixir-ensure-session session params) 50 | (with-temp-file tmp (insert body)) 51 | (ob-elixir-eval session (format "import_file(\"%s\")" tmp)))) 52 | 53 | (defun ob-elixir-eval (session body) 54 | (let ((result (ob-elixir-eval-in-repl session body))) 55 | (replace-regexp-in-string 56 | "^\\(import_file([^)]+)\\)+\n" "" 57 | (replace-regexp-in-string 58 | "\r" "" 59 | (replace-regexp-in-string 60 | "\n\\(\\(iex\\|[.]+\\)\\(([^@]+@[^)]+)[0-9]+\\|([0-9]+)\\)> \\)+" "" 61 | (replace-regexp-in-string 62 | "\e\\[[0-9;]*[A-Za-z]" "" 63 | (replace-regexp-in-string 64 | "\"\\\\u2029\"" "" 65 | result))))))) 66 | 67 | (defun ob-elixir-ensure-session (session params) 68 | (let ((name (format "*elixir-%s*" session))) 69 | (unless (and (get-process name) 70 | (process-live-p (get-process name))) 71 | (with-current-buffer (get-buffer-create name) 72 | (make-local-variable 'process-environment) 73 | (setq process-environment (cons "TERM=vt100" process-environment)) 74 | (apply 'start-process name name "iex" 75 | (append (when (assoc :sname params) 76 | (list "--sname" (assoc-default :sname params))) 77 | (when (assoc :name params) 78 | (list "--name" (assoc-default :name params))) 79 | (when (assoc :cookie params) 80 | (list "--cookie" (assoc-default :cookie params))) 81 | (when (assoc :remsh params) 82 | (list "--remsh" (assoc-default :remsh params)))))) 83 | (sit-for 0.5) 84 | (set-process-filter (get-process name) 'ob-elixir-process-filter) 85 | (ob-elixir-eval-in-repl session "IEx.configure(colors: [enabled: false], inspect: [pretty: false])") 86 | (sit-for 0.2)))) 87 | 88 | (defun ob-elixir-process-filter (process output) 89 | (setq ob-elixir-process-output (concat ob-elixir-process-output output))) 90 | 91 | (defun ob-elixir-wait () 92 | (while (not (string-match-p ob-elixir-eoe ob-elixir-process-output)) 93 | (sit-for 0.2))) 94 | 95 | (defun ob-elixir-eval-in-repl (session body) 96 | (let ((name (format "*elixir-%s*" session))) 97 | (setq ob-elixir-process-output "") 98 | (process-send-string name (format "%s\n" body)) 99 | (accept-process-output (get-process name) nil nil 1) 100 | (process-send-string name (format "\"%s\"\n" ob-elixir-eoe)) 101 | (ob-elixir-wait) 102 | (replace-regexp-in-string 103 | (regexp-quote (format "\"%s\"" ob-elixir-eoe)) "" 104 | ob-elixir-process-output))) 105 | 106 | (provide 'ob-elixir) 107 | ;;; ob-elixir.el ends here 108 | --------------------------------------------------------------------------------