summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael W <gcr@sneakygcr.net>2012-08-12 12:32:03 -0600
committerMichael W <gcr@sneakygcr.net>2012-08-12 12:32:03 -0600
commit998e709f65a8bd9acfd1917d0ac4aaa47f67030b (patch)
tree5bc68e8fffb4a5aea1e9e206d768a505e4b0f279
parent540293601e7dcac9eb193d529d7b2413765f3c72 (diff)
downloadgeiser-guile-998e709f65a8bd9acfd1917d0ac4aaa47f67030b.tar.gz
geiser-guile-998e709f65a8bd9acfd1917d0ac4aaa47f67030b.tar.bz2
[WIP] Draw images inline in the Racket REPL.
On the racket side, we use a custom print handler to print images (convertible? values; see file/convertible) in a special format: #<Image: filename> On the geiser side, we add a comint post-output hook to search for that filename and replace it with inline images.
-rw-r--r--elisp/geiser-repl.el11
-rw-r--r--scheme/racket/geiser/user.rkt28
2 files changed, 37 insertions, 2 deletions
diff --git a/elisp/geiser-repl.el b/elisp/geiser-repl.el
index 14d71cc..05d4775 100644
--- a/elisp/geiser-repl.el
+++ b/elisp/geiser-repl.el
@@ -266,8 +266,19 @@ module command as a string")
(geiser-repl--host)
(geiser-repl--port)))))
+(defun geiser-repl--replace-images ()
+ "Replace all image patterns with actual images"
+ (with-silent-modifications
+ (save-excursion
+ (goto-char (point-min))
+ (while (re-search-forward "#<Image: \\([-+./_0-9a-zA-Z]+\\)>" nil t)
+ (let ((file (match-string 1)))
+ (replace-match "")
+ (insert-image (create-image file) "[image]"))))))
+
(defun geiser-repl--output-filter (txt)
(geiser-con--connection-update-debugging geiser-repl--connection txt)
+ (geiser-repl--replace-images)
(when (string-match-p (geiser-con--connection-prompt geiser-repl--connection)
txt)
(geiser-autodoc--disinhibit-autodoc)))
diff --git a/scheme/racket/geiser/user.rkt b/scheme/racket/geiser/user.rkt
index c8cca24..38eefd8 100644
--- a/scheme/racket/geiser/user.rkt
+++ b/scheme/racket/geiser/user.rkt
@@ -14,7 +14,10 @@
(provide init-geiser-repl run-geiser-server start-geiser)
(require (for-syntax racket/base)
+ file/convertible
mzlib/thread
+ racket/file
+ racket/pretty
racket/tcp
geiser
geiser/enter
@@ -88,10 +91,30 @@
(define (geiser-prompt-read prompt)
(make-repl-reader (geiser-read prompt)))
+(define (geiser-save-tmpimage imgbytes)
+ ;; Save imgbytes to a new temporary file and return the filename
+ (define filename (make-temporary-file "geiser-img-~a.png"))
+ (with-output-to-file filename #:exists 'truncate
+ (lambda () (display imgbytes)))
+ filename)
+
+(define (geiser-maybe-print-image value)
+ (cond
+ [(and (convertible? value)
+ (convert value 'png-bytes))
+ => (lambda (pngbytes)
+ ;; (The above could be problematic if a future version of racket
+ ;; suddenly decides it can "convert" strings to picts)
+ (printf "#<Image: ~a>\n" (geiser-save-tmpimage pngbytes)))]
+ [else
+ (unless (void? value)
+ (pretty-print value))]))
+
(define (init-geiser-repl)
(compile-enforce-module-constants #f)
(current-load/use-compiled geiser-loader)
- (current-prompt-read (geiser-prompt-read geiser-prompt)))
+ (current-prompt-read (geiser-prompt-read geiser-prompt))
+ (current-print geiser-maybe-print-image))
(define (run-geiser-repl in out enforce-module-constants)
(parameterize [(compile-enforce-module-constants enforce-module-constants)
@@ -99,7 +122,8 @@
(current-output-port out)
(current-error-port out)
(current-load/use-compiled geiser-loader)
- (current-prompt-read (geiser-prompt-read geiser-prompt))]
+ (current-prompt-read (geiser-prompt-read geiser-prompt))
+ (current-print geiser-maybe-print-image)]
(read-eval-print-loop)))
(define server-channel (make-channel))