;;; auctex-lua.el --- Lua editing support for AUCTeX ;; ;; Copyright (C) 2013 Sean Allred ;; ;; Author: Sean Allred (seallred@smcm.edu) ;; Version: 1.0 ;; Package-Requires: ((auctex "11.86") (lua-mode "20130419")) ;; URL: http://github.com/vermiculus/auctex-lua ;; ;; This file is NOT part of Emacs. ;; ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the GNU General Public License ;; as published by the Free Software Foundation; either version 2 ;; of the License, or (at your option) any later version. ;; ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; ;; You should have received a copy of the GNU General Public License ;; along with this program; if not, write to ;; ;; The Free Software Foundation, Inc. ;; 51 Franklin Street, Fifth Floor ;; Boston, MA, 02110-1301 ;; USA. ;; ;; Keywords: latex, lua ;; ;;; Commentary: ;; ;; This package provides some basic utilities for working with Lua ;; code from within AUCTeX. `LaTeX-edit-Lua-code-start' is the entry ;; point of this package; bind it to your favorite key and use it ;; inside of any environment in `LaTeX-Lua-environments'. To commit ;; your changes to the parent buffer and return to it, simply use ;; `save-buffer' (or whichever key it is bound to). The contents of ;; the parent buffer will be updated and the Lua buffer will be killed. ;; ;; Beware! Editing embedded Lua code is asynchronous. If you kill ;; the buffer that was editing it, your changes will be lost! In a ;; future update I will add a `yes-or-no-p' confirmation to killing ;; the buffer, but I've yet to figure that one out. ;;; Code: (require 'lua-mode) (defgroup LaTeX-lua nil "Lua support in AUCTeX." :group 'LaTeX) ;;;###autoload (defcustom LaTeX-Lua-environments '("luacode" "luacode*") "List of environments that will contain Lua code." :group 'LaTeX-lua :type '(repeat (string))) (defvar LaTeX-edit-Lua-code-parent-buffer) (defvar LaTeX-edit-Lua-code-parent-buffer-point) (defun LaTeX-mark-environment-contents () "Mark the contents of the innermost LaTeX environment. See also `LaTeX-find-matching-begin' and `LaTeX-find-matching-end'." (interactive) ;; Search for the end of the current environment. (LaTeX-find-matching-end) ;; Then place a mark. (push-mark (search-backward "\\end")) ;; Search for the beginning of the current environment. (LaTeX-find-matching-begin) ;; Search for the end of the \begin{...} (search-forward "}")) ;;;###autoload (defun LaTeX-edit-Lua-code-start () "Place Lua code in a separate buffer in `lua-mode'." (interactive) ;; If we are in a Lua environment, (if (member (LaTeX-current-environment) LaTeX-Lua-environments) ;; Make a few notes about where we are and what we're looking at (let* ((lua-parent-buffer (current-buffer)) (lua-where-edit-started (point)) (lua-buffer-name (format "*%s [Lua]*" (buffer-name))) (lua-buffer (get-buffer-create lua-buffer-name)) ; prepare buffer (lua-code (progn (LaTeX-mark-environment-contents) ; get lua code (buffer-substring-no-properties (point) (mark))))) ;; Switch to the Lua buffer we just created. (switch-to-buffer-other-window lua-buffer) ;; Record some buffer-local variables (setq LaTeX-edit-Lua-code-parent-buffer lua-parent-buffer) (setq LaTeX-edit-Lua-code-parent-buffer-point lua-where-edit-started) ;; and switch this buffer to `lua-mode' (lua-mode) ;; Set key bindings. (local-set-key [remap save-buffer] 'LaTeX-edit-Lua-code-finish) ;; Fill the buffer with the Lua code. (insert lua-code)) (message "Not in a Lua code environment."))) (defun LaTeX-edit-Lua-code-finish () "Dump the contents of the current buffer into the buffer/environment it was called from, replacing what is currently in that environment. Note that this function isn't too smart yet; it does not intelligently handle a scenario where other editing has taken place in the parent buffer. If point has moved into a different environment, that environment will be replaced instead of its original one. Remember, you can always `undo' your changes. See `LaTeX-mark-environment-contents'." (interactive) ;; 'Ensure' this is a Lua code buffer that was made with `LaTeX-edit-Lua-code-start' (if (bufferp LaTeX-edit-Lua-code-parent-buffer) ;; Grab the Lua code (let* ((lua-code (progn (widen) (LaTeX-edit-Lua--chomp (buffer-substring (point-min) (point-max)))))) ;; Kill the Lua buffer (kill-buffer-and-window) ;; and switch to its parent (switch-to-buffer LaTeX-edit-Lua-code-parent-buffer) (save-excursion ;; Mark the current environment (LaTeX-mark-environment-contents) ;; and replace it (delete-region (point) (mark)) ;; with the Lua code (insert lua-code)) ;; and return point to its rightful place (goto-char LaTeX-edit-Lua-code-parent-buffer-point)) (message "%s %s" "Something went wrong." "Am I *really* in a buffer created with `LaTeX-edit-Lua-code-finish'?"))) ;; Adapted from the Elisp Cookbook: ;; http://www.emacswiki.org/emacs/ElispCookbook#toc6 (defun LaTeX-edit-Lua--chomp (str) "Chomp leading and tailing whitespace from STR." (while (string-match "\\s*.*\\s*" str) (setq str (replace-match "" t t str))) str) (provide 'auctex-lua) ;;; auctex-lua.el ends here