diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/local/client.nim | 3 | ||||
-rw-r--r-- | src/local/container.nim | 79 | ||||
-rw-r--r-- | src/server/buffer.nim | 28 |
3 files changed, 51 insertions, 59 deletions
diff --git a/src/local/client.nim b/src/local/client.nim index d088982f..11b3a8f2 100644 --- a/src/local/client.nim +++ b/src/local/client.nim @@ -144,8 +144,7 @@ proc command0(client: Client, src: string, filename = "<command>", proc command(client: Client, src: string) = client.command0(src) let container = client.consoleWrapper.container - container.requestLines().then(proc() = - container.cursorLastLine()) + container.tailOnLoad = true proc suspend(client: Client) {.jsfunc.} = client.pager.term.quit() diff --git a/src/local/container.nim b/src/local/container.nim index 8008a896..ef14a303 100644 --- a/src/local/container.nim +++ b/src/local/container.nim @@ -137,6 +137,7 @@ type ishtml*: bool filter*: BufferFilter bgcolor*: CellColor + tailOnLoad*: bool jsDestructor(Highlight) jsDestructor(Container) @@ -461,6 +462,8 @@ proc setNumLines(container: Container, lines: int, finish = false) = container.startpos = none(CursorPosition) container.updateCursor() +proc cursorLastLine*(container: Container) + proc requestLines*(container: Container, w = container.lineWindow): EmptyPromise {.discardable.} = if container.iface == nil: @@ -473,13 +476,17 @@ proc requestLines*(container: Container, w = container.lineWindow): EmptyPromise for y in 0 ..< min(res.lines.len, w.len): container.lines[y] = res.lines[y] container.lines[y].str.mnormalize() - container.updateCursor() var isBgNew = container.bgcolor != res.bgcolor if isBgNew: container.bgcolor = res.bgcolor if res.numLines != container.numLines: container.setNumLines(res.numLines, true) container.triggerEvent(STATUS) + if res.numLines > 0: + container.updateCursor() + if container.tailOnLoad: + container.tailOnLoad = false + container.cursorLastLine() let cw = container.fromy ..< container.fromy + container.height if w.a in cw or w.b in cw or cw.a in w or cw.b in w or isBgNew: container.triggerEvent(UPDATE) @@ -1334,45 +1341,36 @@ proc setLoadInfo(container: Container, msg: string) = container.loadinfo = msg container.triggerEvent(STATUS) -#TODO TODO TODO this should be called with a timeout. -proc onload*(container: Container, res: LoadResult) = +#TODO this should be called with a timeout. +proc onload*(container: Container, res: int) = if container.canceled: container.setLoadInfo("") - #TODO we wouldn't need the then part if we had incremental rendering of - # HTML. - container.iface.cancel().then(proc(lines: int) = - if lines != container.numLines: - container.setNumLines(lines) - container.triggerEvent(STATUS) + container.iface.cancel().then(proc() = container.needslines = true ) - else: - if res.bytes == -1 or res.atend: - container.setLoadInfo("") - elif not res.atend: - container.setLoadInfo(convertSize(res.bytes) & " loaded") - if res.lines != container.numLines or res.atend: - container.setNumLines(res.lines, res.atend) - if res.atend: - container.triggerEvent(STATUS) - container.needslines = true - if not res.atend: - discard container.iface.load().then(proc(res: LoadResult) = - container.onload(res) - ) - else: - container.triggerEvent(LOADED) - container.iface.getTitle().then(proc(title: string) = - if title != "": - container.title = title - container.triggerEvent(TITLE) + elif res == -1: + container.setLoadInfo("") + container.triggerEvent(STATUS) + container.needslines = true + container.triggerEvent(LOADED) + container.iface.getTitle().then(proc(title: string) = + if title != "": + container.title = title + container.triggerEvent(TITLE) + ) + if not container.hasstart and container.location.anchor != "": + container.iface.gotoAnchor().then(proc(res: Opt[tuple[x, y: int]]) = + if res.isSome: + let res = res.get + container.setCursorXYCenter(res.x, res.y) ) - if not container.hasstart and container.location.anchor != "": - container.iface.gotoAnchor().then(proc(res: Opt[tuple[x, y: int]]) = - if res.isSome: - let res = res.get - container.setCursorXYCenter(res.x, res.y) - ) + elif res == -2: + container.setLoadInfo(convertSize(res) & " loaded") + else: + container.needslines = true + discard container.iface.load().then(proc(res: int) = + container.onload(res) + ) proc load(container: Container) = container.setLoadInfo("Connecting to " & container.location.host & "...") @@ -1420,9 +1418,9 @@ proc load(container: Container) = ) proc startload*(container: Container) = - container.iface.load() - .then(proc(res: tuple[atend: bool, lines, bytes: int]) = - container.onload(res)) + container.iface.load().then(proc(res: int) = + container.onload(res) + ) proc connect2*(container: Container): EmptyPromise = return container.iface.connect2(container.ishtml) @@ -1567,8 +1565,9 @@ proc setStream*(container: Container, stream: Stream) = else: container.iface = cloneInterface(stream) # Maybe we have to resume loading. Let's try. - discard container.iface.load().then(proc(res: LoadResult) = - container.onload(res)) + discard container.iface.load().then(proc(res: int) = + container.onload(res) + ) proc onreadline(container: Container, w: Slice[int], handle: (proc(line: SimpleFlexibleLine)), res: GetLinesResult) = diff --git a/src/server/buffer.nim b/src/server/buffer.nim index 6f8beb34..cfaa8b12 100644 --- a/src/server/buffer.nim +++ b/src/server/buffer.nim @@ -1137,16 +1137,15 @@ proc finishLoad(buffer: Buffer): EmptyPromise = buffer.loader.removeCachedURL($buffer.request.url) return buffer.loadResources() -type LoadResult* = tuple[ - atend: bool, - lines: int, - bytes: int -] - -proc load*(buffer: Buffer): LoadResult {.proxy, task.} = +# Returns: +# * -1 if loading is done +# * -2 if the page was partially rendered +# * a positive number for just reporting the number of bytes loaded. +proc load*(buffer: Buffer): int {.proxy, task.} = if buffer.state == bsLoaded: - return (true, buffer.lines.len, -1) + return -1 else: + # will be resolved in onload buffer.savetask = true proc resolveTask[T](buffer: Buffer, cmd: BufferCommand, res: T) = @@ -1161,12 +1160,11 @@ proc resolveTask[T](buffer: Buffer, cmd: BufferCommand, res: T) = buffer.pstream.flush() proc onload(buffer: Buffer) = - var res: LoadResult = (false, buffer.lines.len, -1) case buffer.state of bsConnecting: assert false of bsLoadingResources, bsLoaded: - buffer.resolveTask(LOAD, res) + buffer.resolveTask(LOAD, -1) return of bsLoadingPage: discard @@ -1178,7 +1176,6 @@ proc onload(buffer: Buffer) = if not reprocess: n = buffer.istream.recvData(addr iq[0], iq.len) buffer.bytesRead += n - res.lines = buffer.lines.len if n != 0: if not buffer.processData(iq.toOpenArray(0, n - 1)): if not buffer.firstBufferRead: @@ -1188,26 +1185,23 @@ proc onload(buffer: Buffer) = continue buffer.firstBufferRead = true reprocess = false - res.bytes = buffer.bytesRead - res.lines = buffer.lines.len else: # EOF - res.atend = true buffer.finishLoad().then(proc() = buffer.do_reshape() - res.lines = buffer.lines.len buffer.state = bsLoaded buffer.document.readyState = rsComplete buffer.dispatchLoadEvent() - buffer.resolveTask(LOAD, res) + buffer.resolveTask(LOAD, -1) ) return # skip incr render - buffer.resolveTask(LOAD, res) + buffer.resolveTask(LOAD, buffer.bytesRead) except ErrorAgain: break # incremental rendering: only if we cannot read the entire stream in one # pass #TODO this could be improved buffer.do_reshape() + buffer.resolveTask(LOAD, -2) proc getTitle*(buffer: Buffer): string {.proxy.} = if buffer.document != nil: |