about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2022-12-11 02:14:33 +0100
committerbptato <nincsnevem662@gmail.com>2022-12-11 02:16:13 +0100
commit087227028f85db2fd5878caf87e3032302c95a30 (patch)
tree9ed59704bdb157d662a6f69db71894a4cd9827e5
parentc4b421daf0a516852fc670826dceffb5c0d38ea8 (diff)
downloadchawan-087227028f85db2fd5878caf87e3032302c95a30.tar.gz
Fixes & QOL improvements
* fix infinite loop after closing buffer
* fix setx not triggering hover updates
* fix D not going back to PREV but to parent
* add M-d, M-,, M-., M-/ for old D behavior, cycle through siblings,
  back to parent
-rw-r--r--res/config.toml6
-rw-r--r--src/buffer/buffer.nim40
-rw-r--r--src/buffer/container.nim2
-rw-r--r--src/display/pager.nim45
-rw-r--r--src/ips/socketstream.nim13
5 files changed, 75 insertions, 31 deletions
diff --git a/res/config.toml b/res/config.toml
index fa641f25..bf2d231c 100644
--- a/res/config.toml
+++ b/res/config.toml
@@ -61,7 +61,7 @@ C-k = 'pager.load("ddg:")'
 U = 'pager.reload()'
 r = 'pager.redraw()'
 R = 'pager.reshape()'
-C-cC-c = 'pager.cancel()'
+C-c = 'pager.cancel()'
 1G = 'pager.cursorFirstLine()'
 g = 'pager.cursorFirstLine()'
 G = 'pager.cursorLastLine()'
@@ -69,8 +69,12 @@ z = 'pager.centerLine()'
 C-g = 'pager.lineInfo()'
 v = 'pager.toggleSource()'
 D = 'pager.discardBuffer()'
+M-d = 'pager.discardBuffer(true)'
 ',' = 'pager.prevBuffer()'
+'M-,' = 'pager.prevSiblingBuffer()'
 '.' = 'pager.nextBuffer()'
+'M-.' = 'pager.nextSiblingBuffer()'
+'M-/' = 'pager.parentBuffer()'
 M-c = 'pager.command()'
 C = 'pager.commandMode();console.show()'
 '/' = 'pager.isearchForward()'
diff --git a/src/buffer/buffer.nim b/src/buffer/buffer.nim
index 0f425ecc..9f699ca3 100644
--- a/src/buffer/buffer.nim
+++ b/src/buffer/buffer.nim
@@ -75,8 +75,7 @@ type
     istream: Stream
     sstream: Stream
     available: int
-    pistream: Stream # for input pipe
-    postream: Stream # for output pipe
+    pstream: Stream # pipe stream
     srenderer: StreamRenderer
     streamclosed: bool
     loaded: bool
@@ -994,7 +993,7 @@ proc getLines*(buffer: Buffer, w: Slice[int]): tuple[numLines: int, lines: seq[S
   result.numLines = buffer.lines.len
 
 proc passFd*(buffer: Buffer) {.proxy.} =
-  let fd = SocketStream(buffer.pistream).recvFileHandle()
+  let fd = SocketStream(buffer.pstream).recvFileHandle()
   buffer.source.fd = fd
 
 proc getSource*(buffer: Buffer) {.proxy.} =
@@ -1021,7 +1020,7 @@ macro bufferDispatcher(funs: static ProxyMap, buffer: Buffer, cmd: BufferCommand
         let typ = param[^2]
         stmts.add(quote do:
           var `id`: `typ`
-          `buffer`.pistream.sread(`id`))
+          `buffer`.pstream.sread(`id`))
         call.add(id)
     var rval: NimNode
     if v.params[0].kind == nnkEmpty:
@@ -1036,35 +1035,34 @@ macro bufferDispatcher(funs: static ProxyMap, buffer: Buffer, cmd: BufferCommand
           let fdi = buffer.selector.registerTimer(buffer.timeout, true, 0)
           buffer.timeouts[fdi] = (proc() =
             let len = slen(`packetid`) + slen(`rval`)
-            buffer.postream.swrite(len)
-            buffer.postream.swrite(`packetid`)
-            buffer.postream.swrite(`rval`)
-            buffer.postream.flush())
+            buffer.pstream.swrite(len)
+            buffer.pstream.swrite(`packetid`)
+            buffer.pstream.swrite(`rval`)
+            buffer.pstream.flush())
           buffer.timeout = 0
           return)
     if rval == nil:
       stmts.add(quote do:
         let len = slen(`packetid`)
-        buffer.postream.swrite(len)
-        buffer.postream.swrite(`packetid`)
-        buffer.postream.flush())
+        buffer.pstream.swrite(len)
+        buffer.pstream.swrite(`packetid`)
+        buffer.pstream.flush())
     else:
       stmts.add(quote do:
         let len = slen(`packetid`) + slen(`rval`)
-        buffer.postream.swrite(len)
-        buffer.postream.swrite(`packetid`)
-        buffer.postream.swrite(`rval`)
-        buffer.postream.flush())
+        buffer.pstream.swrite(len)
+        buffer.pstream.swrite(`packetid`)
+        buffer.pstream.swrite(`rval`)
+        buffer.pstream.flush())
     ofbranch.add(stmts)
     switch.add(ofbranch)
   return switch
 
 proc readCommand(buffer: Buffer) =
-  let istream = buffer.pistream
   var cmd: BufferCommand
-  istream.sread(cmd)
+  buffer.pstream.sread(cmd)
   var packetid: int
-  istream.sread(packetid)
+  buffer.pstream.sread(packetid)
   bufferDispatcher(ProxyFunctions, buffer, cmd, packetid)
 
 proc runBuffer(buffer: Buffer, rfd: int) =
@@ -1095,8 +1093,7 @@ proc runBuffer(buffer: Buffer, rfd: int) =
             break loop
           else:
             assert false
-  buffer.pistream.close()
-  buffer.postream.close()
+  buffer.pstream.close()
   buffer.loader.quit()
   quit(0)
 
@@ -1121,8 +1118,7 @@ proc launchBuffer*(config: BufferConfig, source: BufferSource,
   buffer.srenderer = newStreamRenderer(buffer.sstream)
   let socks = connectSocketStream(mainproc, false)
   socks.swrite(getpid())
-  buffer.pistream = socks
-  buffer.postream = socks
+  buffer.pstream = socks
   let rfd = int(socks.source.getFd())
   buffer.selector.registerHandle(rfd, {Read}, 0)
   buffer.runBuffer(rfd)
diff --git a/src/buffer/container.nim b/src/buffer/container.nim
index 2a68a24b..691be89e 100644
--- a/src/buffer/container.nim
+++ b/src/buffer/container.nim
@@ -347,8 +347,8 @@ proc setCursorY*(container: Container, y: int) {.jsfunc.} =
     else:
       container.setFromY(y)
     container.pos.cursory = y
-  container.sendCursorPosition()
   container.restoreCursorX()
+  container.sendCursorPosition()
 
 proc centerLine*(container: Container) {.jsfunc.} =
   container.setFromY(container.cursory - container.height div 2)
diff --git a/src/display/pager.nim b/src/display/pager.nim
index 7123ea97..eff8c322 100644
--- a/src/display/pager.nim
+++ b/src/display/pager.nim
@@ -236,7 +236,6 @@ proc writeStatusMessage(pager: Pager, str: string, format: Format = Format()) =
   pager.clearStatusMessage()
   var i = 0
   for r in str.runes:
-    i += r.width()
     if i >= pager.statusgrid.len:
       pager.statusgrid[^1].str = "$"
       break
@@ -246,6 +245,7 @@ proc writeStatusMessage(pager: Pager, str: string, format: Format = Format()) =
     else:
       pager.statusgrid[i].str &= r
     pager.statusgrid[i].format = format
+    i += r.width()
 
 proc refreshStatusMsg*(pager: Pager) =
   let container = pager.container
@@ -357,13 +357,45 @@ proc nextBuffer(pager: Pager): bool {.jsfunc.} =
     return true
   return false
 
+proc parentBuffer(pager: Pager): bool {.jsfunc.} =
+  if pager.container == nil:
+    return false
+  if pager.container.parent == nil:
+    return false
+  pager.setContainer(pager.container.parent)
+  return true
+
+proc prevSiblingBuffer(pager: Pager): bool {.jsfunc.} =
+  if pager.container == nil:
+    return false
+  if pager.container.parent == nil:
+    return false
+  var n = pager.container.parent.children.find(pager.container)
+  assert n != -1, "Container not a child of its parent"
+  if n == 0:
+    n = pager.container.parent.children.len
+  pager.setContainer(pager.container.parent.children[n - 1])
+  return true
+
+proc nextSiblingBuffer(pager: Pager): bool {.jsfunc.} =
+  if pager.container == nil:
+    return false
+  if pager.container.parent == nil:
+    return false
+  var n = pager.container.parent.children.find(pager.container)
+  assert n != -1, "Container not a child of its parent"
+  if n == pager.container.parent.children.high:
+    n = -1
+  pager.setContainer(pager.container.parent.children[n + 1])
+  return true
+
 proc alert*(pager: Pager, msg: string) {.jsfunc.} =
   pager.alerts.add(msg)
 
 proc lineInfo(pager: Pager) {.jsfunc.} =
   pager.alert(pager.container.lineInfo())
 
-proc deleteContainer(pager: Pager, container: Container) =
+proc deleteContainer(pager: Pager, container: Container, prevlevel = false) =
   container.cancel()
   if container.sourcepair != nil:
     container.sourcepair.sourcepair = nil
@@ -378,7 +410,10 @@ proc deleteContainer(pager: Pager, container: Container) =
       parent.children.insert(child, n + 1)
     parent.children.delete(n)
     if container == pager.container:
-      pager.setContainer(parent)
+      if prevlevel or n == 0:
+        pager.setContainer(parent)
+      else:
+        pager.setContainer(parent.children[n - 1])
   elif container.children.len > 0:
     let parent = container.children[0]
     parent.parent = nil
@@ -397,12 +432,12 @@ proc deleteContainer(pager: Pager, container: Container) =
   pager.unreg.add((container.process, SocketStream(container.iface.stream)))
   pager.dispatcher.forkserver.removeChild(container.process)
 
-proc discardBuffer(pager: Pager) {.jsfunc.} =
+proc discardBuffer(pager: Pager, prevlevel = false) {.jsfunc.} =
   if pager.container == nil or pager.container.parent == nil and
       pager.container.children.len == 0:
     pager.alert("Cannot discard last buffer!")
   else:
-    pager.deleteContainer(pager.container)
+    pager.deleteContainer(pager.container, prevlevel)
 
 proc toggleSource*(pager: Pager) {.jsfunc.} =
   if pager.container.sourcepair != nil:
diff --git a/src/ips/socketstream.nim b/src/ips/socketstream.nim
index 5d0485fa..e411956c 100644
--- a/src/ips/socketstream.nim
+++ b/src/ips/socketstream.nim
@@ -18,7 +18,13 @@ proc sockReadData(s: Stream, buffer: pointer, len: int): int =
   let s = SocketStream(s)
   if s.blk:
     while result < len:
-      result += s.source.recv(cast[pointer](cast[int](buffer) + result), len - result)
+      let n = s.source.recv(cast[pointer](cast[int](buffer) + result), len - result)
+      result += n
+      if n == 0:
+        raise newException(EOFError, "")
+      if n < 0:
+        result = n
+        break
   else:
     result = s.source.recv(buffer, len)
   if result < 0:
@@ -37,7 +43,10 @@ proc sockWriteData(s: Stream, buffer: pointer, len: int) =
   #TODO maybe don't block if blk is false?
   var i = 0
   while i < len:
-    i += SocketStream(s).source.send(cast[pointer](cast[int](buffer) + i), len - i)
+    let n = SocketStream(s).source.send(cast[pointer](cast[int](buffer) + i), len - i)
+    if n < 0:
+      raise newException(IOError, $strerror(errno))
+    i += n
 
 proc sockAtEnd(s: Stream): bool =
   SocketStream(s).isend