use linenoise instead of GNU readline
This commit is contained in:
parent
87f65f5e72
commit
aa8b470cf6
10 changed files with 1351 additions and 66 deletions
|
|
@ -9,13 +9,14 @@
|
|||
|
||||
## Low-level streams for high performance.
|
||||
|
||||
import
|
||||
import
|
||||
strutils
|
||||
|
||||
when not defined(windows) and defined(useGnuReadline):
|
||||
# support '-d:useGnuReadline' for backwards compatibility:
|
||||
when not defined(windows) and (defined(useGnuReadline) or defined(useLinenoise)):
|
||||
import rdstdin
|
||||
|
||||
type
|
||||
type
|
||||
TLLStreamKind* = enum # enum of different stream implementations
|
||||
llsNone, # null stream: reading and writing has no effect
|
||||
llsString, # stream encapsulates a string
|
||||
|
|
@ -27,42 +28,42 @@ type
|
|||
s*: string
|
||||
rd*, wr*: int # for string streams
|
||||
lineOffset*: int # for fake stdin line numbers
|
||||
|
||||
|
||||
PLLStream* = ref TLLStream
|
||||
|
||||
proc llStreamOpen*(data: string): PLLStream =
|
||||
proc llStreamOpen*(data: string): PLLStream =
|
||||
new(result)
|
||||
result.s = data
|
||||
result.kind = llsString
|
||||
|
||||
proc llStreamOpen*(f: File): PLLStream =
|
||||
proc llStreamOpen*(f: File): PLLStream =
|
||||
new(result)
|
||||
result.f = f
|
||||
result.kind = llsFile
|
||||
|
||||
proc llStreamOpen*(filename: string, mode: FileMode): PLLStream =
|
||||
proc llStreamOpen*(filename: string, mode: FileMode): PLLStream =
|
||||
new(result)
|
||||
result.kind = llsFile
|
||||
if not open(result.f, filename, mode): result = nil
|
||||
|
||||
proc llStreamOpen*(): PLLStream =
|
||||
|
||||
proc llStreamOpen*(): PLLStream =
|
||||
new(result)
|
||||
result.kind = llsNone
|
||||
|
||||
proc llStreamOpenStdIn*(): PLLStream =
|
||||
proc llStreamOpenStdIn*(): PLLStream =
|
||||
new(result)
|
||||
result.kind = llsStdIn
|
||||
result.s = ""
|
||||
result.lineOffset = -1
|
||||
|
||||
proc llStreamClose*(s: PLLStream) =
|
||||
proc llStreamClose*(s: PLLStream) =
|
||||
case s.kind
|
||||
of llsNone, llsString, llsStdIn:
|
||||
of llsNone, llsString, llsStdIn:
|
||||
discard
|
||||
of llsFile:
|
||||
of llsFile:
|
||||
close(s.f)
|
||||
|
||||
when not declared(readLineFromStdin):
|
||||
when not declared(readLineFromStdin):
|
||||
# fallback implementation:
|
||||
proc readLineFromStdin(prompt: string, line: var string): bool =
|
||||
stdout.write(prompt)
|
||||
|
|
@ -77,7 +78,7 @@ proc endsWith*(x: string, s: set[char]): bool =
|
|||
if i >= 0 and x[i] in s:
|
||||
result = true
|
||||
|
||||
const
|
||||
const
|
||||
LineContinuationOprs = {'+', '-', '*', '/', '\\', '<', '>', '!', '?', '^',
|
||||
'|', '%', '&', '$', '@', '~', ','}
|
||||
AdditionalLineContinuationOprs = {'#', ':', '='}
|
||||
|
|
@ -104,31 +105,31 @@ proc llReadFromStdin(s: PLLStream, buf: pointer, bufLen: int): int =
|
|||
s.rd = 0
|
||||
var line = newStringOfCap(120)
|
||||
var triples = 0
|
||||
while readLineFromStdin(if s.s.len == 0: ">>> " else: "... ", line):
|
||||
while readLineFromStdin(if s.s.len == 0: ">>> " else: "... ", line):
|
||||
add(s.s, line)
|
||||
add(s.s, "\n")
|
||||
inc triples, countTriples(line)
|
||||
if not continueLine(line, (triples and 1) == 1): break
|
||||
inc(s.lineOffset)
|
||||
result = min(bufLen, len(s.s) - s.rd)
|
||||
if result > 0:
|
||||
if result > 0:
|
||||
copyMem(buf, addr(s.s[s.rd]), result)
|
||||
inc(s.rd, result)
|
||||
|
||||
proc llStreamRead*(s: PLLStream, buf: pointer, bufLen: int): int =
|
||||
proc llStreamRead*(s: PLLStream, buf: pointer, bufLen: int): int =
|
||||
case s.kind
|
||||
of llsNone:
|
||||
of llsNone:
|
||||
result = 0
|
||||
of llsString:
|
||||
of llsString:
|
||||
result = min(bufLen, len(s.s) - s.rd)
|
||||
if result > 0:
|
||||
if result > 0:
|
||||
copyMem(buf, addr(s.s[0 + s.rd]), result)
|
||||
inc(s.rd, result)
|
||||
of llsFile:
|
||||
of llsFile:
|
||||
result = readBuffer(s.f, buf, bufLen)
|
||||
of llsStdIn:
|
||||
of llsStdIn:
|
||||
result = llReadFromStdin(s, buf, bufLen)
|
||||
|
||||
|
||||
proc llStreamReadLine*(s: PLLStream, line: var string): bool =
|
||||
setLen(line, 0)
|
||||
case s.kind
|
||||
|
|
@ -152,60 +153,60 @@ proc llStreamReadLine*(s: PLLStream, line: var string): bool =
|
|||
result = readLine(s.f, line)
|
||||
of llsStdIn:
|
||||
result = readLine(stdin, line)
|
||||
|
||||
proc llStreamWrite*(s: PLLStream, data: string) =
|
||||
|
||||
proc llStreamWrite*(s: PLLStream, data: string) =
|
||||
case s.kind
|
||||
of llsNone, llsStdIn:
|
||||
of llsNone, llsStdIn:
|
||||
discard
|
||||
of llsString:
|
||||
of llsString:
|
||||
add(s.s, data)
|
||||
inc(s.wr, len(data))
|
||||
of llsFile:
|
||||
of llsFile:
|
||||
write(s.f, data)
|
||||
|
||||
proc llStreamWriteln*(s: PLLStream, data: string) =
|
||||
|
||||
proc llStreamWriteln*(s: PLLStream, data: string) =
|
||||
llStreamWrite(s, data)
|
||||
llStreamWrite(s, "\n")
|
||||
|
||||
proc llStreamWrite*(s: PLLStream, data: char) =
|
||||
proc llStreamWrite*(s: PLLStream, data: char) =
|
||||
var c: char
|
||||
case s.kind
|
||||
of llsNone, llsStdIn:
|
||||
of llsNone, llsStdIn:
|
||||
discard
|
||||
of llsString:
|
||||
of llsString:
|
||||
add(s.s, data)
|
||||
inc(s.wr)
|
||||
of llsFile:
|
||||
of llsFile:
|
||||
c = data
|
||||
discard writeBuffer(s.f, addr(c), sizeof(c))
|
||||
|
||||
proc llStreamWrite*(s: PLLStream, buf: pointer, buflen: int) =
|
||||
proc llStreamWrite*(s: PLLStream, buf: pointer, buflen: int) =
|
||||
case s.kind
|
||||
of llsNone, llsStdIn:
|
||||
of llsNone, llsStdIn:
|
||||
discard
|
||||
of llsString:
|
||||
if buflen > 0:
|
||||
of llsString:
|
||||
if buflen > 0:
|
||||
setLen(s.s, len(s.s) + buflen)
|
||||
copyMem(addr(s.s[0 + s.wr]), buf, buflen)
|
||||
inc(s.wr, buflen)
|
||||
of llsFile:
|
||||
of llsFile:
|
||||
discard writeBuffer(s.f, buf, buflen)
|
||||
|
||||
proc llStreamReadAll*(s: PLLStream): string =
|
||||
const
|
||||
|
||||
proc llStreamReadAll*(s: PLLStream): string =
|
||||
const
|
||||
bufSize = 2048
|
||||
case s.kind
|
||||
of llsNone, llsStdIn:
|
||||
of llsNone, llsStdIn:
|
||||
result = ""
|
||||
of llsString:
|
||||
of llsString:
|
||||
if s.rd == 0: result = s.s
|
||||
else: result = substr(s.s, s.rd)
|
||||
s.rd = len(s.s)
|
||||
of llsFile:
|
||||
of llsFile:
|
||||
result = newString(bufSize)
|
||||
var bytes = readBuffer(s.f, addr(result[0]), bufSize)
|
||||
var i = bytes
|
||||
while bytes == bufSize:
|
||||
while bytes == bufSize:
|
||||
setLen(result, i + bufSize)
|
||||
bytes = readBuffer(s.f, addr(result[i + 0]), bufSize)
|
||||
inc(i, bytes)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue