parley previous input issue pasted by alaricsp on Tue Apr 17 14:18:03 2012

here's my .csirc:

(system "sleep 1")
(use parley)
(parley-debug #t)
(let ((old (current-input-port)))
     (current-input-port (make-parley-port old)))

I've put some extra debugging in parley.scm (I will put that in an annotation):

If I start csi and then start typing "abcdefgh" while it's still sleeping, I see the likes of:

alaric@ubuntu:~$ csi

CHICKEN
(c)2008-2011 The Chicken Team
(c)2000-2007 Felix L. Winkelmann
Version 4.7.0.3-st 
linux-unix-gnu-x86-64 [ 64bit manyargs dload ptables ]
compiled 2011-10-11 on ubuntu (Linux)

; loading ./.csirc ...
abcde; loading /usr/local/lib/chicken/6/parley.import.so ...
; loading /usr/local/lib/chicken/6/chicken.import.so ...
; loading /usr/local/lib/chicken/6/scheme.import.so ...
; loading /usr/local/lib/chicken/6/data-structures.import.so ...
; loading /usr/local/lib/chicken/6/extras.import.so ...
; loading /usr/local/lib/chicken/6/ports.import.so ...
; loading /usr/local/lib/chicken/6/posix.import.so ...
; loading /usr/local/lib/chicken/6/srfi-1.import.so ...
; loading /usr/local/lib/chicken/6/srfi-13.import.so ...
; loading /usr/local/lib/chicken/6/srfi-18.import.so ...
; loading /usr/local/lib/chicken/6/stty.import.so ...
; loading /usr/local/lib/chicken/6/srfi-69.import.so ...
; loading /usr/local/lib/chicken/6/foreign.import.so ...
; loading /usr/local/lib/chicken/6/foreigners.import.so ...
; loading /usr/local/lib/chicken/6/parley.so ...
; loading /usr/local/lib/chicken/6/stty.so ...
prev input: (#\a #\b #\c #\d #\e)
loop: ()
Entering read-raw
#;1> abcde
Read raw: "abcde"
loop: ("abcde")
So far: '("abcde")' '"abcde"' '"abcde"'

Error: unbound variable: abcde
prev input: (#\f)
loop: ()
Entering read-raw
#;1> f
Read raw: "f"
loop: ("f")
So far: '("f")' '"f"' '"f"'

Error: unbound variable: f
prev input: (#\g)
loop: ()
Entering read-raw
#;1> g
Read raw: "g"
loop: ("g")
So far: '("g")' '"g"' '"g"'

Error: unbound variable: g
prev input: (#\h)
loop: ()
Entering read-raw
#;1> h

parley.scm debuggery additions pasted by alaricsp on Tue Apr 17 14:19:17 2012

(define (read-raw prompt in out offset)
  (dbg "Entering read-raw\n")
  (let ((l (call-with-current-continuation
            (lambda (return)
              (prompt-loop prompt in out "" 0 return offset)))))
    (dbg "Read raw: ~s\n" l)
    (history-add! l)))



(define (parley prompt #!key (in ##sys#standard-input) (out (current-output-port)))
  (set-buffering-mode! out #:none)
  (let* ((parley-port (parley? in))
         (real-in-port (first-usable-port in port-list))
         (useful-term (terminal-supported? real-in-port (get-environment-variable "TERM")))
         (old-attrs (and useful-term (enable-raw-mode real-in-port))))
    (let ((lines (if useful-term
                     (begin
                       (history-init!)
                       (unless (member in port-list)
                         (set! port-list (cons in port-list)))
                       (let* ((prev-input (and (char-ready? in) (slurp-all-input in)))
                              (offset (if parley-port 1 (get-column real-in-port))))
                         (dbg "prev input: ~s\n" prev-input)
                         (if prev-input
                             (call-with-input-string
                                 (list->string prev-input)
                               (lambda (in)
                                 (let loop ((r '()))
                                   (dbg "loop: ~s\n" r)
                                   (if (eof-object? (peek-char in))
                                       (reverse r)
                                       (loop (cons (read-raw prompt in out offset) r))))))
                             (read-raw prompt real-in-port out offset))))
                     (begin
                       (dbg "; Warning: dumb terminal")
                       (set-buffering-mode! real-in-port #:none)
                       (when (or (terminal-port? in)
                                 parley-port)
                         (display prompt out))
                       (flush-output out)
                       (let ((l (read-one-line real-in-port)))
                         l)))))
      (if old-attrs (restore-terminal-settings real-in-port old-attrs))
      lines)))

(define (make-parley-port in #!optional prompt prompt2)
  (let ((l "")
        (handle #f)
        (p1 prompt)
        (p2 (or prompt2 "> "))
        (pos 0))
    (unless (member in port-list)
      (set! port-list (cons in port-list)))
    (letrec ((append-while-incomplete
              (lambda (start)
                (let* ((lines (parley (if (string-null? start)
                                          (or p1 ((repl-prompt)))
                                          p2)
                                      in: in))
                       (line (if (list? lines) (string-intersperse lines (string #\newline)) lines))
                       (res (and (string? line) (string-append start line))))
                  (dbg "So far: '~s' '~s' '~s'\n" lines line res)
                  (cond ((and (eof-object? line) (string-null? start)) line)
                        ((eof-object? line) start)
                        ((input-missing? res)
                         (append-while-incomplete res))
                        (else res)))))
             (char-ready?
              (lambda ()
                (and (string? l)
                     (< pos (string-length l)))))
             (get-next-char!
              (lambda ()
                (cond ((not l)
                       #!eof)
                      ((char-ready?)
                       (let ((ch (string-ref l pos)))
                         (set! pos (+ 1 pos))
                         ch))
                      (else
                       (set! pos 0)
                       (set! l
                             (append-while-incomplete ""))
                       (if (and (useful-term? in) (string? l))
                           (set! l (string-append l "\n")))
                       (if (not (eof-object? l))
                           (get-next-char!)
                           l))))))
      (set! handle (lambda (s)
                     (print-call-chain)
                     (set! pos 0)
                     (set! l "")
                     (##sys#user-interrupt-hook)))
      (set-signal-handler! signal/int handle)
      (let ((p (make-input-port
                get-next-char!
                char-ready?
                (lambda ()
                  (set-signal-handler! signal/int #f)
                  'closed-parley-port))))
        (set-port-name! p "(parley)")
        p))))

parley loop added by C-Keen on Tue Apr 17 14:32:40 2012

#;3> ^Dr: (#!eof)

Error: (string-intersperse) bad argument type - not a string: #!eof

	Call history:

	parley.scm:52: string-null?	  
	parley.scm:52: display	  
	parley.scm:52: return	  
	parley.scm:52: history-add!	  
	parley.scm:52: history	  
	parley.scm:52: syntax-check	  
	parley.scm:52: history-max-lines	  
	parley.scm:52: loop	  
	parley.scm:52: print	  
	parley.scm:52: peek-char	  
	parley.scm:52: reverse	  
	parley.scm:52: restore-terminal-settings	  
	parley.scm:52: stty#set-terminal-attributes!	  
	stty.scm:66: port?	  
	stty.scm:66: port->fileno	  
	parley.scm:52: string-intersperse