about summary refs log tree commit diff stats
path: root/src/display
diff options
context:
space:
mode:
Diffstat (limited to 'src/display')
-rw-r--r--src/display/client.nim37
-rw-r--r--src/display/pager.nim46
2 files changed, 47 insertions, 36 deletions
diff --git a/src/display/client.nim b/src/display/client.nim
index 24ea8183..3b56373e 100644
--- a/src/display/client.nim
+++ b/src/display/client.nim
@@ -47,6 +47,7 @@ type
     console {.jsget.}: Console
     pager {.jsget.}: Pager
     line {.jsget.}: LineEdit
+    sevent: seq[Container]
     config: Config
     jsrt: JSRuntime
     jsctx: JSContext
@@ -84,6 +85,7 @@ proc doRequest(client: Client, req: Request): Response {.jsfunc.} =
 
 proc interruptHandler(rt: JSRuntime, opaque: pointer): int {.cdecl.} =
   let client = cast[Client](opaque)
+  if client.console.tty == nil: return
   try:
     let c = client.console.tty.readChar()
     if c == char(3): #C-c
@@ -96,9 +98,11 @@ proc interruptHandler(rt: JSRuntime, opaque: pointer): int {.cdecl.} =
   return 0
 
 proc evalJS(client: Client, src, filename: string): JSObject =
-  unblockStdin(client.console.tty.getFileHandle())
+  if client.console.tty != nil:
+    unblockStdin(client.console.tty.getFileHandle())
   result = client.jsctx.eval(src, filename, JS_EVAL_TYPE_GLOBAL)
-  restoreStdin(client.console.tty.getFileHandle())
+  if client.console.tty != nil:
+    restoreStdin(client.console.tty.getFileHandle())
 
 proc evalJSFree(client: Client, src, filename: string) =
   free(client.evalJS(src, filename))
@@ -235,8 +239,7 @@ proc acceptBuffers(client: Client) =
     else:
       client.pager.procmap.del(pid)
     stream.close()
-  var i = 0
-  while i < client.pager.procmap.len:
+  while client.pager.procmap.len > 0:
     let stream = client.ssock.acceptSocketStream()
     var pid: Pid
     stream.sread(pid)
@@ -247,9 +250,10 @@ proc acceptBuffers(client: Client) =
       let fd = stream.source.getFd()
       client.fdmap[int(fd)] = container
       client.selector.registerHandle(fd, {Read}, nil)
-      inc i
+      client.sevent.add(container)
     else:
-      #TODO print an error?
+      #TODO uh what?
+      eprint "???"
       stream.close()
 
 proc log(console: Console, ss: varargs[string]) {.jsfunc.} =
@@ -264,7 +268,7 @@ proc inputLoop(client: Client) =
   let selector = client.selector
   selector.registerHandle(int(client.console.tty.getFileHandle()), {Read}, nil)
   let sigwinch = selector.registerSignal(int(SIGWINCH), nil)
-  client.acceptBuffers()
+  let redrawtimer = client.selector.registerTimer(1000, false, nil)
   while true:
     let events = client.selector.select(-1)
     for event in events:
@@ -286,9 +290,12 @@ proc inputLoop(client: Client) =
           client.pager.windowChange(client.attrs)
         else: assert false
       if Event.Timer in event.events:
-        if event.fd in client.interval_fdis:
+        if event.fd == redrawtimer:
+          if client.pager.container != nil:
+            client.pager.container.requestLines()
+        elif event.fd in client.interval_fdis:
           client.intervals[client.interval_fdis[event.fd]].handler()
-        if event.fd in client.timeout_fdis:
+        elif event.fd in client.timeout_fdis:
           let id = client.timeout_fdis[event.fd]
           let timeout = client.timeouts[id]
           timeout.handler()
@@ -313,8 +320,7 @@ proc writeFile(client: Client, path: string, content: string) {.jsfunc.} =
 
 proc newConsole(pager: Pager, tty: File): Console =
   new(result)
-  result.tty = tty
-  if tty != nil and false:
+  if tty != nil:
     var pipefd: array[0..1, cint]
     if pipe(pipefd) == -1:
       raise newException(Defect, "Failed to open console pipe.")
@@ -332,14 +338,10 @@ proc newConsole(pager: Pager, tty: File): Console =
     result.err = newFileStream(stderr)
 
 proc dumpBuffers(client: Client) =
-  client.acceptBuffers()
-  for container in client.pager.containers:
-    container.load()
   let ostream = newFileStream(stdout)
   for container in client.pager.containers:
-    container.reshape(true)
     client.pager.drawBuffer(container, ostream)
-  client.pager.dumpAlerts()
+    discard client.pager.handleEvents(container)
   stdout.close()
 
 proc launchClient*(client: Client, pages: seq[string], ctype: Option[string], dump: bool) =
@@ -372,7 +374,8 @@ proc launchClient*(client: Client, pages: seq[string], ctype: Option[string], du
 
   for page in pages:
     client.pager.loadURL(page, ctype = ctype)
-
+  client.acceptBuffers()
+  client.pager.refreshStatusMsg()
   if not dump:
     client.inputLoop()
   else:
diff --git a/src/display/pager.nim b/src/display/pager.nim
index 7bd50e6f..a50eb9a8 100644
--- a/src/display/pager.nim
+++ b/src/display/pager.nim
@@ -59,7 +59,8 @@ iterator containers*(pager: Pager): Container =
     var stack: seq[Container]
     stack.add(c)
     while stack.len > 0:
-      yield stack.pop()
+      c = stack.pop()
+      yield c
       for i in countdown(c.children.high, 0):
         stack.add(c.children[i])
 
@@ -152,7 +153,7 @@ proc launchPager*(pager: Pager, tty: File) =
 
 proc dumpAlerts*(pager: Pager) =
   for msg in pager.alerts:
-    eprint msg
+    eprint "cha: " & msg
 
 proc quit*(pager: Pager, code = 0) =
   pager.term.quit()
@@ -231,6 +232,7 @@ proc writeStatusMessage(pager: Pager, str: string, format: Format = Format()) =
 proc refreshStatusMsg*(pager: Pager) =
   let container = pager.container
   if container == nil: return
+  if pager.tty == nil: return
   if container.loadinfo != "":
     pager.writeStatusMessage(container.loadinfo)
   elif pager.alerts.len > 0:
@@ -343,10 +345,7 @@ proc lineInfo(pager: Pager) {.jsfunc.} =
   pager.alert(pager.container.lineInfo())
 
 proc deleteContainer(pager: Pager, container: Container) =
-  if container.parent == nil and
-      container.children.len == 0 and
-      container != pager.container:
-    return
+  container.cancel()
   if container.sourcepair != nil:
     container.sourcepair.sourcepair = nil
     container.sourcepair = nil
@@ -565,28 +564,37 @@ proc updateReadLine*(pager: Pager) =
       pager.clearLineEdit()
 
 # Open a URL prompt and visit the specified URL.
-proc changeLocation(pager: Pager) {.jsfunc.} =
-  var url = pager.container.source.location.serialize()
-  pager.setLineEdit(readLine("URL: ", pager.attrs.width, current = url, term = pager.term), LOCATION)
+proc load(pager: Pager, s = "") {.jsfunc.} =
+  if s.len > 0 and s[^1] == '\n':
+    pager.loadURL(s)
+  else:
+    var url = s
+    if url == "":
+      url = pager.container.source.location.serialize()
+    pager.setLineEdit(readLine("URL: ", pager.attrs.width, current = url, term = pager.term), LOCATION)
 
 # Reload the page in a new buffer, then kill the previous buffer.
 proc reload(pager: Pager) {.jsfunc.} =
   pager.gotoURL(newRequest(pager.container.source.location), none(URL), pager.container.contenttype, pager.container)
 
+# Cancel loading current page (if exists).
+proc cancel(pager: Pager) {.jsfunc.} =
+  pager.container.cancel()
+
 proc click(pager: Pager) {.jsfunc.} =
   pager.container.click()
 
 proc authorize*(pager: Pager) =
   pager.setLineEdit(readLine("Username: ", pager.attrs.width, term = pager.term), USERNAME)
 
-proc handleEvent0*(pager: Pager, container: Container, event: ContainerEvent): bool =
+proc handleEvent0(pager: Pager, container: Container, event: ContainerEvent): bool =
   case event.t
   of FAIL:
     pager.deleteContainer(container)
     if container.retry.len > 0:
       pager.gotoURL(newRequest(container.retry.pop()), ctype = container.contenttype)
     else:
-      pager.alert("Couldn't load " & $container.source.location & " (error code " & $container.code & ")")
+      pager.alert("Can't load " & $container.source.location & " (error code " & $container.code & ")")
       pager.refreshStatusMsg()
     if pager.container == nil:
       return false
@@ -631,19 +639,19 @@ proc handleEvent0*(pager: Pager, container: Container, event: ContainerEvent): b
   of NO_EVENT: discard
   return true
 
-proc handleEvent*(pager: Pager, container: Container): bool =
-  var event: ContainerEvent
-  try:
-    event = container.handleEvent()
-  except IOError:
-    return false
-  if not pager.handleEvent0(container, event):
-    return false
+proc handleEvents*(pager: Pager, container: Container): bool =
   while container.events.len > 0:
     let event = container.events.pop()
     if not pager.handleEvent0(container, event):
       return false
   return true
 
+proc handleEvent*(pager: Pager, container: Container): bool =
+  try:
+    container.handleEvent()
+  except IOError:
+    return false
+  return pager.handleEvents(container)
+
 proc addPagerModule*(ctx: JSContext) =
   ctx.registerType(Pager)