
Given a port, I want to read
from it without consuming anything (a.k.a., just peek). Is there a way to do this?

Or if that’s too hard, the following constraint might help: read
is allowed consume things if it succeeds. It can’t consume anything only when the operation would fail.

#lang racket/base
(define (peek in)
(define amt 128)
(define out (open-output-string))
(let loop ([pos 0])
(define substr (peek-string amt pos in))
(cond
[(eof-object? substr) eof]
[else
(write-string substr out)
(with-handlers ([exn:fail?
(λ (_)
(loop (+ pos amt)))])
(read (open-input-string (get-output-string out)))
(read in))])))
This will do it, but may end up buffering so much data in RAM that it’ll crash your program. If you don’t want it to commit at the end then you can just drop the final (read in)
.

could it be as simple as this? or am I missing something? https://docs.racket-lang.org/reference/ports.html#(tech._peek)

and then using this for example https://docs.racket-lang.org/reference/Byte_and_String_Input.html#(def._((quote._~23~25kernel)._peek-string))

Yep, @popa.bogdanp’s idea will do the job. Thanks!

Just a quick headsup: the code doesn’t quite work for a port with 130 space followed by )
. This will make peek
skips )
and read whatever is after that, which is not what I want, but the main idea (peek-string
+ buffer string port) is what I need to do my work

okay so now I think I understand it: git uses zlib streams, not bare deflate. Racket stdlib only directly supports gzip and pkzip (aka bare deflate). @mflatt would it be possible to make zlib-inflate public? right now it’s private in net/git-checkout
, as Sam mentioned I see now there’s no zlib-deflate there, is it why it’s not public?

Call read
on a peeking-input-port
wrapper, and then commit the read on the original port afterwards.

Yes — It would make to finish an repackage that as a library that handles zlib headers and footers, but it doesn’t seem like a good idea to expose the zlib-inflate
internal to net/git-checkout
.

Thanks!

@sorawee I’m sure Ryan’s suggestion better, but something I had come up with was https://github.com/greghendershott/racket-mode/blob/master/racket/interactions.rkt#L38-L57

But it might just be a buggy re-invention of half of peeking-input-port
:smile:. Seriously, it’s only used to decide whether to show a REPL prompt.

Yes, that’s the case, but other things won’t work either for the same reason

How can I provide an additional binding while using make-meta-reader
? Usually I use #lang s-exp syntax/module-reader
which turns #lang foo
to (module ... /path/to/lib ...)
, so bindings from /path/to/lib
are available. However, with meta reader, this strategy doesn’t work.
I could wrap read-syntax
so that it inserts (require /path/to/lib)
, but then read-syntax
would always produce a module form. Not that I have any problem with it, but I wonder if I can avoid the restriction.

Hmm. Actually, inserting (require /path/to/lib)
doesn’t quite work either, because I want this additional binding to be shadowable by other require

@jmhimara has joined the channel