Wednesday, March 11, 2015

Automagically update erlang -export in emacs

Elisp code to automatically update the first -export expression in an erlang module.

To use, when in a particular function that you want to add to your -export clause, simply press C-c-4 and the first -export clause that is found will have the function added to the clause. It knows if the function has already been added in one of any of the potential other -export clauses and wont update if the function is already there.

;; erl-mode: Generate export string from list
(defun erlang-generate-export-string (export_list)
  (let ((result ""))
    (dolist (fn_def export_list)
      (setq result
            (concat result
                    (concat (car fn_def) "/" (number-to-string (cdr fn_def)) ", "))))
    result))

;; erl-mode: Update export with given value
(defun erlang-update-export (function_arity)
  (let ((export_list (save-excursion
                       (erlang-get-export))))
      (if (not (member function_arity export_list))
          (save-excursion
            (goto-char (point-min))
            (let ((matched (match-data))
                  (res '()))
              (unwind-protect
                  (progn
                    ;; Simply find the first -export and append there
                    (re-search-forward "^-export\\s *(\\s *[\\[]" (point-max) t)
                    (insert (erlang-generate-export-string (list function_arity)))
                    (message "Updated -export clause.")
                (store-match-data matched)))))
        (message "Function already exists in -export clause."))))

;; erl-mode: Pull function into export with param count
(defun erlang-add-to-export ()
  (interactive)
  (let ((name (save-excursion
                (and (erlang-beginning-of-clause)
                     (erlang-get-function-name nil))))
        (arg_count (save-excursion
                     (erlang-beginning-of-clause)
                     (erlang-get-function-arity))))
    (save-excursion
      (erlang-update-export (cons name arg_count)))))
      ;; (beginning-of-buffer)
      ;; (search-forward-regexp "^-export\\s *(\\s *\[[\]")
      ;; (insert (concat name "/" (number-to-string arg_count) ", ")))))

(add-hook 'erlang-mode-hook (lambda () (local-set-key "\C-c4" 'erlang-add-to-export)))

No comments:

Post a Comment