public inbox for guile-emacs@sourceware.org
 help / color / mirror / Atom feed
* patch: some macros and symbol completion
@ 2000-03-16 16:57 Kalle Olavi Niemitalo
  2000-03-17  9:45 ` Keisuke Nishida
  0 siblings, 1 reply; 3+ messages in thread
From: Kalle Olavi Niemitalo @ 2000-03-16 16:57 UTC (permalink / raw)
  To: guile-emacs

Here's a patch for guile-emacs 0.2.  It adds a new module (emacs
macro), more imports in (emacs import), some documentation
strings and symbol completion with Tab.

2000-03-17  Kalle Olavi Niemitalo  <tosi@stekt.oulu.fi>

	* emacs.scm: Changed GNU Emacs to Guile Emacs in license notice.
	(lisp-variable-ref, lisp-variable-set!): Added docstring.
	(lisp-variable-set!): Return *unspecified*.
	(import-lisp-variable, import-lisp-function, define-variable,
	define-command): Documented with comments.
	(define-command): Propagate the docstring to the Lisp side.

	* guile.scm: Changed GNU Emacs to Guile Emacs in license notice.
	Also use modules (emacs macro), (ice-9 session) and (ice-9 regex).
	(guile-scheme-mode, scheme-set-module, scheme-eval-expression,
	scheme-eval-region, scheme-eval-last-sexp,
	scheme-eval-print-last-sexp): Added docstring.
	(scheme-interaction-mode): Extended docstring.
	(scheme-set-module, scheme-eval-define): Use `save-excursion'.
	(scheme-complete-symbol): New function.
	(scheme-eval-define): Use (interactive), not (interactive ()).

	* import.scm: Changed GNU Emacs to Guile Emacs in license notice.
	Also import these functions: mark-marker, set-marker (as
	set-marker!), make-marker, skip-syntax-forward, try-completion,
	delete-region, display-completion-list, ding, get-buffer-create,
	erase-buffer, set-buffer-modified-p (as set-buffer-modified?!),
	display-buffer, select-window.

	* macro.scm: New file.

diff -xCVS -bruNF^( /home/kalle/src/FOREIGN-CVS/guile-emacs/emacs/emacs.scm /home/kalle/share/emacs/site-scheme/emacs/emacs.scm
--- /home/kalle/src/FOREIGN-CVS/guile-emacs/emacs/emacs.scm	Thu Mar 16 05:16:38 2000
+++ /home/kalle/share/emacs/site-scheme/emacs/emacs.scm	Thu Mar 16 20:55:59 2000
@@ -7,18 +7,18 @@
 
 ;; This file is part of Guile Emacs.
 
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; Guile Emacs 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, or (at your option)
 ;; any later version.
 
-;; GNU Emacs is distributed in the hope that it will be useful,
+;; Guile Emacs 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 GNU Emacs; see the file COPYING.  If not, write to the
+;; along with Guile Emacs; see the file COPYING.  If not, write to the
 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 ;; Boston, MA 02111-1307, USA.
 
@@ -33,11 +33,29 @@ (define-public (lisp-false? obj) (or (eq
 (define-public (lisp-true? obj) (not (lisp-false? obj)))
 
 (define-public (lisp-variable-ref symbol)
+  "Return the value of Lisp variable SYMBOL."
   (lisp-eval symbol))
 
 (define-public (lisp-variable-set! symbol value)
-  (lisp-eval `(setq ,symbol ',value)))
-
+  "Set the Lisp variable SYMBOL to VALUE."
+  (lisp-eval `(setq ,symbol ',value))
+  ;; In Scheme, *-set! functions return an unspecified value.
+  *unspecified*)
+
+;; (import-lisp-variable VARIABLE [SCHEME-NAME])
+;; Import the Lisp variable VARIABLE to Scheme as SCHEME-NAME.
+;; Both arguments are unevaluated symbols.
+;; If SCHEME-NAME is omitted, it defaults to VARIABLE.
+;;
+;; The value bound to SCHEME-NAME is actually a procedure.
+;; To get the value of the variable, call the procedure:
+;;
+;; (import-lisp-variable baud-rate)
+;; (baud-rate)
+;;   => 38400
+;; (set! (baud-rate) 115200)
+;; (baud-rate)
+;;   => 115200
 (define-macro (import-lisp-variable variable . rest)
   (let ((name (if (pair? rest) (car rest) variable)))
     `(define-public ,name
@@ -48,6 +66,11 @@ (define-macro (import-lisp-variable vari
 	 ptr))))
 (export import-lisp-variable)
 
+;; (import-lisp-function FUNCTION [SCHEME-NAME])
+;; Import the Lisp function FUNCTION to Scheme as SCHEME-NAME.
+;; Both arguments are unevaluated symbols.
+;; If SCHEME-NAME is omitted, it defaults to FUNCTION.
+;; The new Scheme function is always public.
 (define-macro (import-lisp-function func . rest)
   (if (lisp-true? (lisp-apply 'functionp (list func)))
       (let ((name (if (pair? rest) (car rest) func)))
@@ -55,21 +78,36 @@ (define-macro (import-lisp-function func
       (lisp-apply 'error (list "No such function: %s" func))))
 (export import-lisp-function)
 
+;; (define-variable VAR VAL DOC)
+;; Define a Lisp variable VAR with value VAL and docstring DOC.
+;; Then import it to Scheme with `import-lisp-variable'.
 (define-macro (define-variable var val doc)
   (lisp-eval (list 'defvar var val doc))
   `(import-lisp-variable ,var))
 (export define-variable)
 
+;; (define-command (COMMAND [ARG...]) [DOCSTRING] INTERACTIVE BODY...)
+;; Define COMMAND as an interactive editor command.
+;; It can be called from both Scheme and Lisp.
+;; [ARG...] is a Scheme argument list.
+;; [DOCSTRING] is an optional documentation string.
+;; INTERACTIVE is a call of the Lisp function `interactive'.
+;; It is only used in the Lisp part of the command.
+;; BODY... is a list of Scheme forms to evaluate when the command is run.
 (define-macro (define-command form . args)
-  (let ((name (car form)) (iarg (car args)))
+  (let ((name (car form))
+	(iarg (car args))
+	(docl '()))
     (if (string? iarg)
-	(begin (set! args (cdr args))
+	(begin (set! docl (list iarg))
+	       (set! args (cdr args))
 	       (set! iarg (car args))))
     (if (not (and (pair? iarg) (eq? (car iarg) 'interactive)))
 	(lisp-apply 'error (list "Command must begin with (interactive...)")))
     `(begin
        (define-public ,form ,@(cdr args))
        (lisp-eval '(defun ,name (&rest args)
+		     ,@docl
 		     ,iarg
 		     (scheme-eval '(set-current-module the-root-module))
 		     (scheme-apply ',name args))))))
diff -xCVS -bruNF^( /home/kalle/src/FOREIGN-CVS/guile-emacs/emacs/guile.scm /home/kalle/share/emacs/site-scheme/emacs/guile.scm
--- /home/kalle/src/FOREIGN-CVS/guile-emacs/emacs/guile.scm	Thu Mar 16 05:16:38 2000
+++ /home/kalle/share/emacs/site-scheme/emacs/guile.scm	Fri Mar 17 01:17:05 2000
@@ -7,18 +7,18 @@
 
 ;; This file is part of Guile Emacs.
 
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; Guile Emacs 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, or (at your option)
 ;; any later version.
 
-;; GNU Emacs is distributed in the hope that it will be useful,
+;; Guile Emacs 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 GNU Emacs; see the file COPYING.  If not, write to the
+;; along with Guile Emacs; see the file COPYING.  If not, write to the
 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 ;; Boston, MA 02111-1307, USA.
 
@@ -26,7 +26,10 @@
 
 (define-module (emacs guile)
   :use-module (emacs emacs)
-  :use-module (emacs import))
+  :use-module (emacs import)
+  :use-module (emacs macro)
+  :use-module (ice-9 session)
+  :use-module (ice-9 regex))
 
 (require 'scheme)
 
@@ -55,6 +58,9 @@ (if (lisp-false? (guile-scheme-mode-map)
       ))
 
 (define-command (guile-scheme-mode)
+  "Major mode for Guile Scheme programs.
+
+\\{guile-scheme-mode-map}"
   (interactive)
   (kill-all-local-variables)
   (set! (major-mode) 'guile-scheme-mode)
@@ -81,7 +87,9 @@ (if (lisp-false? (scheme-interaction-mod
       ))
 
 (define-command (scheme-interaction-mode)
-  "Scheme Interaction mode."
+  "Major mode for evaluating Scheme expressions with Guile.
+
+\\{scheme-interaction-mode-map}"
   (interactive)
   (kill-all-local-variables)
   (use-local-map scheme-interaction-mode-map)
@@ -96,14 +104,14 @@ (define-command (scheme-interaction-mode
 ;;;
 
 (define (scheme-set-module)
-  (let ((pos (point)))
+  "Evaluate any (define-module ...) form in the buffer."
+  (save-excursion
     (goto-char (point-min))
     (if (lisp-true? (re-search-forward "^(define-module " nil t))
 	(let ((start (match-beginning 0)))
 	  (goto-char start)
 	  (forward-sexp)
-	  (eval-string (buffer-substring start (point)))))
-    (goto-char pos)))
+	  (eval-string (buffer-substring start (point)))))))
 
 (define (scheme-show-result value flag)
   (set! value (if (unspecified? value)
@@ -119,16 +127,22 @@ (define (scheme-show-result value flag)
 ;;;
 
 (define-command (scheme-eval-expression string)
+  "Evaluate the expressions in STRING and show value in echo area."
   (interactive "SEval: ")
   (scheme-set-module)
   (scheme-show-result (eval-string string) nil))
 
 (define-command (scheme-eval-region start end)
+  "Execute the region as Scheme code."
   (interactive "r")
   (scheme-set-module)
   (scheme-eval-expression (buffer-substring start end)))
 
 (define-command (scheme-eval-last-sexp arg)
+  ;; The documentation of `eval-last-sexp' talks about printing the
+  ;; value in the minibuffer, but that's just wrong.
+  "Evaluate sexp before point; show value in echo area.
+With argument, print output into current buffer."
   (interactive "P")
   (scheme-set-module)
   (let ((stab (syntax-table)) (pos (point)) (value #f))
@@ -142,20 +156,61 @@ (define-command (scheme-eval-last-sexp a
     (scheme-show-result (eval-string value) arg)))
 
 (define-command (scheme-eval-print-last-sexp)
-  (interactive ())
+  "Evaluate sexp before point; print value into current buffer."
+  (interactive)
   (insert "\n")
   (scheme-eval-last-sexp t)
   (insert "\n"))
 
 (define-command (scheme-eval-define)
-  (interactive ())
+  (interactive)
   (scheme-set-module)
-  (let ((pos (point)))
-    (scheme-eval-expression (buffer-substring
-			     (begin (beginning-of-defun) (point))
-			     (begin (end-of-defun) (point))))
-    (goto-char pos)))
+  (scheme-eval-expression
+   (save-excursion
+    (buffer-substring (begin (beginning-of-defun) (point))
+		      (begin (end-of-defun) (point))))))
+
+;; This is mostly copied from lisp-complete-symbol in emacs-lisp/lisp.el,
+;; (c) 1985, 1986, 1994 FSF.
+(define-command (scheme-complete-symbol)
+  (interactive)
+  (scheme-set-module)
+  (let* ((end (point))
+	 (beg (save-excursion
+	       (save-syntax-table
+		(set-syntax-table scheme-mode-syntax-table)
+		(backward-sexp 1)
+		(skip-syntax-forward "'")
+		(point))))
+	 (pattern (buffer-substring beg end))
+	 (matches (apropos-internal
+		   (string-append "^" (regexp-quote pattern))))
+	 ;; This is wasteful...
+	 (alist (map (lambda (sym) (list (symbol->string sym)))
+		     matches))
+	 (completion (try-completion pattern alist)))
+    (cond ((eq? completion 't))
+	  ((lisp-false? completion)
+	   (message "Can't find completion for \"%s\"" pattern)
+	   (ding))
+	  ((not (string=? pattern completion))
+	   (delete-region beg end)
+	   (insert completion))
+	  (else
+	   (message "Making completion list...")
+	   ;; No need to call all-completions; the list was already
+	   ;; filtered by apropos.
+	   (with-output-to-temp-buffer "*Completions*"
+	      (display-completion-list
+	       (map (lambda (sym)
+		      (let ((str (symbol->string sym))
+			    (val (eval sym)))
+			(cond ((procedure? val) (list str " <f>"))
+			      ((macro?     val) (list str " <m>"))
+			      (else str))))
+		    (sort matches string<?))))
+	   (message "Making completion list...%s" "done")))))
 
 (provide 'guile)
 
-;;; guile.el ends here
+;;; guile.scm ends here
diff -xCVS -bruNF^( /home/kalle/src/FOREIGN-CVS/guile-emacs/emacs/import.scm /home/kalle/share/emacs/site-scheme/emacs/import.scm
--- /home/kalle/src/FOREIGN-CVS/guile-emacs/emacs/import.scm	Thu Mar 16 05:16:38 2000
+++ /home/kalle/share/emacs/site-scheme/emacs/import.scm	Fri Mar 17 01:11:13 2000
@@ -7,18 +7,18 @@
 
 ;; This file is part of Guile Emacs.
 
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; Guile Emacs 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, or (at your option)
 ;; any later version.
 
-;; GNU Emacs is distributed in the hope that it will be useful,
+;; Guile Emacs 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 GNU Emacs; see the file COPYING.  If not, write to the
+;; along with Guile Emacs; see the file COPYING.  If not, write to the
 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 ;; Boston, MA 02111-1307, USA.
 
@@ -52,5 +52,18 @@ (import-lisp-function match-beginning)
 (import-lisp-function forward-sexp)
 (import-lisp-function set-buffer)
 (import-lisp-function current-buffer)
+(import-lisp-function mark-marker)
+(import-lisp-function set-marker set-marker!)
+(import-lisp-function make-marker)
+(import-lisp-function skip-syntax-forward)
+(import-lisp-function try-completion)
+(import-lisp-function delete-region)
+(import-lisp-function display-completion-list)
+(import-lisp-function ding)
+(import-lisp-function get-buffer-create)
+(import-lisp-function erase-buffer)
+(import-lisp-function set-buffer-modified-p set-buffer-modified?!)
+(import-lisp-function display-buffer)
+(import-lisp-function select-window)
 
 ;;; import.scm ends here
diff -xCVS -bruNF^( /home/kalle/src/FOREIGN-CVS/guile-emacs/emacs/macro.scm /home/kalle/share/emacs/site-scheme/emacs/macro.scm
--- /home/kalle/src/FOREIGN-CVS/guile-emacs/emacs/macro.scm	Thu Jan  1 02:00:00 1970
+++ /home/kalle/share/emacs/site-scheme/emacs/macro.scm	Fri Mar 17 02:37:19 2000
@@ -0,0 +1,241 @@
+;;; macro.scm --- reimplementation of some Emacs macros and special forms
+
+;; Copyright (C) 2000 Kalle Olavi Niemitalo
+;; (If the FSF wants the copyright, that can be arranged.)
+
+;; Maintainer: none
+;; Keywords: extensions, scheme
+
+;; This file is part of Guile Emacs.
+
+;; Guile Emacs 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, or (at your option)
+;; any later version.
+
+;; Guile Emacs 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 Guile Emacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; Emacs Lisp macros and special forms cannot be imported to Scheme
+;; as easily as functions.  Therefore this module reimplements some
+;; of them in Scheme.
+
+;; Beware: these macros are not completely hygienic!  When you use
+;; them, you must not rebind any syntactic keywords defined in R5RS or
+;; in this module.  The macros are however hygienic in their use of
+;; external functions.  This is accomplished with ', quoting.  Local
+;; variables used in macro expansions have names generated with
+;; (gensym) so they should be safe too.  In the macros themselves,
+;; generated symbols are kept in variables whose names begin with an
+;; equals sign.
+
+;;; Code:
+
+(define-module (emacs macro)
+  :use-module (emacs emacs)
+  :use-module (emacs import))
+
+\f
+;; Trivial macros
+
+(define-macro (when test . body)
+  `(cond (,test ,@body)))
+(export when)
+
+(define-macro (unless test . body)
+  `(cond ((',not ,test) ,@body)))
+(export unless)
+
+;; This must be a macro because otherwise the order of evaluation
+;; would be unspecified.
+(define-macro (prog1 first . body)
+  (let ((=saved (gensym)))
+    `(let ((,=saved ,first))
+       ,@body
+       ,=saved)))
+(export prog1)
+
+(define-macro (prog2 x y . body)
+  (let ((=saved (gensym)))
+    `(let ((,=saved (begin ,x ,y)))
+       ,@body
+       ,=saved)))
+(export prog2)
+
+\f
+;; save-*
+
+;; Like the Emacs Lisp special form with the same name.
+;; This also saves and restores the inner state if you jump
+;; out and back in with continuations.
+(define-macro (save-excursion . body)
+  `(',save-excursion-1 (lambda () ,@body)))
+(export save-excursion)
+
+(define (save-excursion-1 thunk)
+  (let ((outer-buffer *unspecified*)
+	(outer-point (make-marker))
+	(outer-mark (make-marker))
+	(outer-mark-active *unspecified*)
+	(been-there #f)
+	(inner-buffer *unspecified*)
+	(inner-point (make-marker))
+	(inner-mark (make-marker))
+	(inner-mark-active *unspecified*))
+     (dynamic-wind
+	 (lambda ()
+	   ;; save outer state
+	   (set! outer-buffer (current-buffer))
+	   (set-marker! outer-point (point))
+	   (set-marker! outer-mark (mark-marker))
+	   (set! outer-mark-active (lisp-variable-ref 'mark-active))
+	   ;; restore inner state, if any
+	   (when been-there
+	     (set-buffer inner-buffer)
+	     (goto-char inner-point)
+	     (set-marker! (mark-marker) inner-mark)
+	     (lisp-variable-set! 'mark-active inner-mark-active)))
+	 thunk
+	 (lambda ()
+	   ;; save inner state
+	   (set! inner-buffer (current-buffer))
+	   (set-marker! inner-point (point))
+	   (set-marker! inner-mark (mark-marker))
+	   (set! inner-mark-active (lisp-variable-ref 'mark-active))
+	   (set! been-there #t)
+	   ;; restore outer state
+	   (set-buffer outer-buffer)
+	   (goto-char outer-point)
+	   (set-marker! (mark-marker) outer-mark)
+	   (lisp-variable-set! 'mark-active outer-mark-active)))))
+
+;; (save-syntax-table BODYFORMS...)
+;; Save and restore the current syntax table.
+;; This is something Emacs doesn't have :-)
+;; FIXME: remember which buffer the syntax table was taken from!
+(define-macro (save-syntax-table . body)
+  `(',save-syntax-table-1 (lambda () ,@body)))
+(export save-syntax-table)
+
+(define (save-syntax-table-1 thunk)
+  (let ((outer-table *unspecified*)
+	(been-there #f)
+	(inner-table *unspecified*))
+       (dynamic-wind
+	   (lambda ()
+	     (set! outer-table (syntax-table))
+	     (when been-there
+	       (set-syntax-table inner-table)))
+	   thunk
+	   (lambda ()
+	     (set! inner-table (syntax-table))
+	     (set! been-there #t)
+	     (set-syntax-table outer-table)))))
+
+(define-macro (save-current-buffer . body)
+  `(',save-current-buffer-1 (lambda () ,@body)))
+(export save-current-buffer)
+
+(define (save-current-buffer-1 thunk)
+  (let ((outer-buffer *unspecified*)
+	(been-there #f)
+	(inner-buffer *unspecified*))
+    (dynamic-wind
+	(lambda ()
+	  (set! outer-buffer (current-buffer))
+	  (when been-there
+	    (set-buffer inner-buffer)))
+	thunk
+	(lambda ()
+	  (set! inner-buffer (current-buffer))
+	  (set! been-there #t)
+	  (set-buffer outer-buffer)))))
+
+;; Used in this module only.
+(define (save-lisp-variable var thunk)
+  (let* ((other-value (lisp-variable-ref var))
+	 (swap (lambda ()
+		 (set! other-value
+		       (prog1 (lisp-variable-ref var)
+			      (lisp-variable-set! var other-value))))))
+    (dynamic-wind swap thunk swap)))
+
+\f
+;; with-*
+
+(define-macro (with-current-buffer buffer . body)
+  `(save-current-buffer
+      (',set-buffer buffer)
+      ,@body))
+(export with-current-buffer)
+
+(define-macro (with-output-to-temp-buffer buffer . body)
+  `(',with-output-to-temp-buffer-1 ,buffer (lambda () ,@body)))
+(export with-output-to-temp-buffer)
+
+(define (with-output-to-temp-buffer-1 bufspec thunk)
+  (let ((buffer (get-buffer-create bufspec))
+	(result *unspecified*))
+    (with-current-buffer buffer
+      (erase-buffer)
+      (run-hooks 'temp-buffer-setup-hook))
+    (save-lisp-variable 'standard-output
+      (lambda ()
+	(lisp-variable-set! 'standard-output buffer)
+	(set! result (thunk))))
+    (with-current-buffer buffer
+      (set-buffer-modified?! #f))
+    (if (lisp-true? (lisp-variable-ref 'temp-buffer-show-function))
+	(lisp-apply (lisp-variable-ref 'temp-buffer-show-function)
+		    (list buffer))
+	(let ((window (display-buffer buffer)))
+	  (save-excursion
+	    (select-window window)
+	    (set-buffer buffer)
+	    (run-hooks 'temp-buffer-show-hook))))
+    result))
+
+\f
+;; lisp-wrap
+;; This is quite unreliable :-(
+
+;; Convert BODY to a form which Emacs Lisp can evaluate.
+;; This can be used when importing macros.
+;; Due to the way this works, only the values returned from
+;; the last saved-thunk-max calls are usable.
+(define-macro (lisp-wrap . body)
+  `(',lisp-wrap-thunk (lambda () ,@body)))
+(export lisp-wrap)
+
+(define-public (run-saved-thunk id)
+  "Called from Emacs Lisp to run a body saved by `lisp-wrap'."
+  ((vector-ref saved-thunks id)))
+
+;; Because garbage collection issues prevent us from having references
+;; to Scheme values on the Emacs heap, we use integers instead.
+(define saved-thunk-max 10)
+(define saved-thunks (make-vector saved-thunk-max))
+(define saved-thunk-next-id 0)
+
+(define-public (lisp-wrap-thunk thunk)
+  "Convert THUNK to a form which Emacs Lisp can evaluate.
+Due to the way this works, only the values returned from
+the last `saved-thunk-max' calls are usable."
+  (let ((id saved-thunk-next-id))
+    (vector-set! saved-thunks id thunk)
+    (set! saved-thunk-next-id (modulo (+ saved-thunk-next-id 1)
+				      saved-thunk-max))
+    ;; FIXME: This should always use the run-saved-thunk in (emacs macro).
+    ;; This version fails if the current module doesn't use (emacs macro).
+    `(scheme-eval '(run-saved-thunk ,id))))
+
+;;; macro.scm ends here

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2000-03-18  4:16 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-03-16 16:57 patch: some macros and symbol completion Kalle Olavi Niemitalo
2000-03-17  9:45 ` Keisuke Nishida
2000-03-18  4:16   ` Kalle Olavi Niemitalo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).