about summary refs log tree commit diff stats
path: root/src/buffer
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2022-12-15 21:02:59 +0100
committerbptato <nincsnevem662@gmail.com>2022-12-15 21:02:59 +0100
commit609e628a39043179c937a20ab5a1dbd0505be5ea (patch)
tree984e350270108ae4148bb1b5aaa631dd374e3070 /src/buffer
parent5d8500c7169c60fe2ba3ee62f64514a65608d2c7 (diff)
downloadchawan-609e628a39043179c937a20ab5a1dbd0505be5ea.tar.gz
container: do not load all lines at once in readLines
Diffstat (limited to 'src/buffer')
-rw-r--r--src/buffer/buffer.nim12
-rw-r--r--src/buffer/container.nim24
2 files changed, 26 insertions, 10 deletions
diff --git a/src/buffer/buffer.nim b/src/buffer/buffer.nim
index cba31dbb..8bfd3f6e 100644
--- a/src/buffer/buffer.nim
+++ b/src/buffer/buffer.nim
@@ -140,7 +140,8 @@ proc then*[T](promise: Promise[T], cb: (proc(x: T))): EmptyPromise {.discardable
       promise.stream.sread(promise.res)
     cb(promise.res))
 
-proc then*[T](promise: EmptyPromise, cb: (proc(): Promise[T])): Promise[T] {.discardable.} =
+# Warning: we assume these aren't discarded.
+proc then*[T](promise: EmptyPromise, cb: (proc(): Promise[T])): Promise[T] =
   if promise == nil: return
   let next = Promise[T]()
   promise.then(proc() =
@@ -151,7 +152,7 @@ proc then*[T](promise: EmptyPromise, cb: (proc(): Promise[T])): Promise[T] {.dis
         next.cb()))
   return next
 
-proc then*[T, U](promise: Promise[T], cb: (proc(x: T): Promise[U])): Promise[U] {.discardable.} =
+proc then*[T, U](promise: Promise[T], cb: (proc(x: T): Promise[U])): Promise[U] =
   if promise == nil: return
   let next = Promise[U]()
   promise.then(proc(x: T) =
@@ -1041,7 +1042,12 @@ proc readCanceled*(buffer: Buffer): bool {.proxy.} =
 proc findAnchor*(buffer: Buffer, anchor: string): bool {.proxy.} =
   return buffer.document != nil and buffer.document.getElementById(anchor) != nil
 
-proc getLines*(buffer: Buffer, w: Slice[int]): tuple[numLines: int, lines: seq[SimpleFlexibleLine]] {.proxy.} =
+type GetLinesResult* = tuple[
+  numLines: int,
+  lines: seq[SimpleFlexibleLine]
+]
+
+proc getLines*(buffer: Buffer, w: Slice[int]): GetLinesResult {.proxy.} =
   var w = w
   if w.b < 0 or w.b > buffer.lines.high:
     w.b = buffer.lines.high
diff --git a/src/buffer/container.nim b/src/buffer/container.nim
index 85c3b9e8..80044b60 100644
--- a/src/buffer/container.nim
+++ b/src/buffer/container.nim
@@ -774,18 +774,28 @@ proc setStream*(container: Container, stream: Stream) =
     stream.flush()
   container.load()
 
+proc onreadline(container: Container, w: Slice[int], handle: (proc(line: SimpleFlexibleLine)), res: GetLinesResult) =
+  for line in res.lines:
+    handle(line)
+  if res.numLines > w.b + 1:
+    var w = w
+    w.a = w.b
+    w.b += 24
+    container.iface.getLines(w).then(proc(res: GetLinesResult) =
+      container.onreadline(w, handle, res))
+  else:
+    container.setNumLines(res.numLines, true)
+
 # Synchronously read all lines in the buffer.
-iterator readLines*(container: Container): SimpleFlexibleLine {.inline.} =
+proc readLines*(container: Container, handle: (proc(line: SimpleFlexibleLine))) =
   if container.code == 0:
     # load succeded
-    container.iface.getLines(0 .. -1).then(proc(res: tuple[numLines: int, lines: seq[SimpleFlexibleLine]]) =
-      container.lines = res.lines
-      container.setNumLines(res.numLines, true))
+    let w = 0 .. 24
+    container.iface.getLines(w).then(proc(res: GetLinesResult) =
+      container.onreadline(w, handle, res))
     while container.iface.hasPromises:
-      # receive all lines
+      # fulfill all promises
       container.handleCommand()
-    for line in container.lines:
-      yield line
 
 proc handleEvent*(container: Container) =
   container.handleCommand()