Plaster

common-lisp
#| So for example: > (print 1) 1 ⇒ 1 > (progn (print 1) (prin1 2)) 1 2 ⇒ 2 > Instead of like SLIME, clim-listener, or CLISP, ...: CL-USER> (print 1) 1 1 CL-USER> (progn (print 1) (princ 2)) 1 2 2 CL-USER> |# ;; Try to make a REPL that doesn't fight with ‘print’. (defun print-respecting-repl () (loop :with line :while (string/= "exit" (prog2 (fresh-line) (setf line (fake-rl)))) :do (if (zerop (length line)) (terpri) (format t "~%⇒ ~s" (eval (read-from-string line)))))) ;; This is just a sketch for explanation of what accept-does-newline = nil ;; for rl means. The real culprit is Unix. (defun fake-rl () #+has-rl (rl:rl :accept-does-newline nil) #-has-rl (let* ((result (make-array 80 :element-type 'character :adjustable t :fill-pointer 0)) (stream *terminal-io*) (tty (nos:stream-system-handle stream)) (c #\🐷)) (setf (fill-pointer result) 0) (princ "> " stream) (finish-output stream) (nos:with-terminal-mode (tty) (nos:set-terminal-mode tty :echo nil :line nil) ;; <-- the tricky part (loop (setf c (read-char)) (case c ((#\return #\newline) (return)) ;; <-- don't echo it ((#\rubout #\backspace) (when (/= 0 (fill-pointer result)) (decf (fill-pointer result)) (format stream "~{~c~}" '(#\backspace #\space #\backspace)))) (t (vector-push-extend c result) (princ c stream))) (finish-output stream))) result))