| 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 2 | ;;;; What this code does: put your cursor at a ParenScript expression |
| 3 | ;;;; in a ParenScript file and type 'C-c j' to bring up a buffer with |
| 4 | ;;;; the resulting Javascript code. This feature depends on Slime (and |
| 5 | ;;;; your ParenScript buffer being in slime-mode; it doesn't work in |
| 6 | ;;;; slime-repl-mode, which is intentional). It is inspired (and works |
| 7 | ;;;; like) the Slime 'C-c M-m' macroexpansion feature. |
| 8 | |
| 9 | ;;;; Copyright 2007, Vladimir Sedach. See the COPYING file in the |
| 10 | ;;;; above directory for licensing information. |
| 11 | |
| 12 | ;;; The code below is a generic facility for adding "macroexpand-like" buffer expansion to Slime |
| 13 | (defun slime-eval-custom-expand (expander exp-str package buffer-name buffer-mode printer) |
| 14 | (lexical-let ((package package) |
| 15 | (buffer-name buffer-name) |
| 16 | (buffer-mode buffer-mode) |
| 17 | (printer printer)) |
| 18 | (slime-eval-async |
| 19 | (list 'swank:eval-and-grab-output (format "(%s %s)" expander exp-str)) |
| 20 | (lambda (expansion) |
| 21 | (slime-with-popup-buffer (buffer-name) |
| 22 | (funcall buffer-mode) |
| 23 | (setq buffer-read-only nil) |
| 24 | (erase-buffer) |
| 25 | (insert (funcall printer (second expansion))) |
| 26 | (setq buffer-read-only t) |
| 27 | (font-lock-fontify-buffer))) |
| 28 | package))) |
| 29 | |
| 30 | (defun* slime-add-custom-expander (key expander buffer-name &optional (buffer-mode 'slime-mode) (printer #'identity)) |
| 31 | (define-key slime-parent-map (concat "\C-c" key) |
| 32 | (lexical-let ((expander expander) |
| 33 | (buffer-name buffer-name) |
| 34 | (buffer-mode buffer-mode) |
| 35 | (printer printer)) |
| 36 | (lambda (&rest _) |
| 37 | (interactive "P") |
| 38 | (slime-eval-custom-expand expander |
| 39 | (first (slime-sexp-at-point-for-macroexpansion)) |
| 40 | (slime-current-package) |
| 41 | buffer-name |
| 42 | buffer-mode |
| 43 | printer))))) |
| 44 | |
| 45 | ;;; This actually defines the expander. If the code above belongs in slime.el, the code below would go into .emacs |
| 46 | (map nil (lambda (x) |
| 47 | (slime-add-custom-expander (car x) |
| 48 | (cdr x) |
| 49 | "*Parenscript generated Javascript*" |
| 50 | (if (featurep 'javascript-mode) 'javascript-mode 'c-mode) |
| 51 | #'read)) |
| 52 | '(("j" . ps:ps) ("d" . ps:ps-doc))) |