about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2023-06-09 14:35:54 +0200
committerbptato <nincsnevem662@gmail.com>2023-06-09 14:35:54 +0200
commitb39e35e46773258cb103397b2372612308c22ae0 (patch)
treea0d0db4e9759ba750b565f337f97bfee346cb5d9 /src
parent00d7836d8a3d0101bd282e3acce58d65ed0220fe (diff)
downloadchawan-b39e35e46773258cb103397b2372612308c22ae0.tar.gz
Fix 'F' missing from fullwidth chars + display bugs
Diffstat (limited to 'src')
-rw-r--r--src/buffer/cell.nim1
-rw-r--r--src/data/charwidth.nim2
-rw-r--r--src/display/pager.nim19
-rw-r--r--src/display/term.nim63
4 files changed, 44 insertions, 41 deletions
diff --git a/src/buffer/cell.nim b/src/buffer/cell.nim
index 3d1d32fa..a147a420 100644
--- a/src/buffer/cell.nim
+++ b/src/buffer/cell.nim
@@ -62,6 +62,7 @@ proc `[]`*(grid: FixedGrid, i: BackwardsIndex): FixedCell = grid.cells[i]
 iterator items*(grid: FixedGrid): FixedCell {.inline.} =
   for cell in grid.cells: yield cell
 proc len*(grid: FixedGrid): int = grid.cells.len
+proc high*(grid: FixedGrid): int = grid.cells.high
 
 const FormatCodes*: array[FormatFlags, tuple[s: int, e: int]] = [
   FLAG_BOLD: (1, 22),
diff --git a/src/data/charwidth.nim b/src/data/charwidth.nim
index daec31ee..c19647f0 100644
--- a/src/data/charwidth.nim
+++ b/src/data/charwidth.nim
@@ -36,7 +36,7 @@ const (
         status &= line[i]
       inc i
     case status
-    of "W": add(firstcol, result[0])
+    of "W", "F": add(firstcol, result[0])
     of "A": add(firstcol, result[1])
     of "H": add(firstcol, result[2])
 )()
diff --git a/src/display/pager.nim b/src/display/pager.nim
index ad89d0d4..0dab3bf0 100644
--- a/src/display/pager.nim
+++ b/src/display/pager.nim
@@ -252,6 +252,7 @@ proc refreshDisplay(pager: Pager, container = pager.container) =
         pager.display[dls + i - startw].format = hlformat
     inc by
 
+# Note: this function doesn't work if start < i of last written char
 proc writeStatusMessage(pager: Pager, str: string,
                         format: Format = newFormat(), start = 0,
                         maxwidth = -1, clip = '$'): int {.discardable.} =
@@ -260,17 +261,23 @@ proc writeStatusMessage(pager: Pager, str: string,
     maxwidth = pager.statusgrid.len
   var i = start
   let e = min(start + maxwidth, pager.statusgrid.width)
+  if i >= e:
+    return e
   for r in str.runes:
+    let pi = i
+    i += r.twidth(i)
     if i >= e:
-      if e > start:
-        pager.statusgrid[e - 1].str = $clip
+      if i >= pager.statusgrid.width:
+        i = pi
+      pager.statusgrid[i].format = format
+      pager.statusgrid[i].str = $clip
+      inc i
       break
     if r.isControlChar():
-      pager.statusgrid[i].str = "^" & getControlLetter(char(r))
+      pager.statusgrid[pi].str = "^" & getControlLetter(char(r))
     else:
-      pager.statusgrid[i].str = $r
-    pager.statusgrid[i].format = format
-    i += r.twidth(i)
+      pager.statusgrid[pi].str = $r
+    pager.statusgrid[pi].format = format
   result = i
   var def = newFormat()
   while i < e:
diff --git a/src/display/term.nim b/src/display/term.nim
index 4f33ee1a..51ed21eb 100644
--- a/src/display/term.nim
+++ b/src/display/term.nim
@@ -355,6 +355,8 @@ proc generateFullOutput(term: Terminal, grid: FixedGrid): string =
   result &= term.resetFormat()
   result &= term.clearDisplay()
   for y in 0 ..< grid.height:
+    if y != 0:
+      result &= "\r\n"
     var w = 0
     for x in 0 ..< grid.width:
       while w < x:
@@ -363,41 +365,34 @@ proc generateFullOutput(term: Terminal, grid: FixedGrid): string =
       let cell = grid[y * grid.width + x]
       result &= term.processFormat(format, cell.format)
       result &= term.processOutputString(cell.str, w)
-    if y != grid.height - 1:
-      result &= "\r\n"
 
-proc generateSwapOutput(term: Terminal, grid: FixedGrid, prev: FixedGrid): string =
-  var format = newFormat()
-  var x = 0
-  var w = 0
-  var line = ""
-  var lr = false
-  for i in 0 ..< grid.cells.len:
-    let cell = grid.cells[i]
-    while w < x:
-      line &= " "
-      inc w
-    if x >= grid.width:
-      format = newFormat()
-      if lr:
-        result &= term.cursorGoto(0, i div grid.width - 1)
-        result &= term.resetFormat()
-        result &= line
-        if w != grid.width:
-          result &= term.clearEnd()
-        lr = false
-      x = 0
-      w = 0
-      line = ""
-    lr = lr or (grid[i] != prev[i])
-    line &= term.processFormat(format, cell.format)
-    line &= term.processOutputString(cell.str, w)
-    inc x
-  if lr:
-    result &= term.cursorGoto(0, grid.height - 1)
-    result &= term.resetFormat()
-    result &= term.clearEnd()
-    result &= line
+proc generateSwapOutput(term: Terminal, grid, prev: FixedGrid): string =
+  var vy = -1
+  for y in 0 ..< grid.height:
+    var w = 0
+    var change = false
+    # scan for changes, and set cx to x of the first change
+    var cx = 0
+    for x in 0 ..< grid.width:
+      if grid[y * grid.width + x] != prev[y * grid.width + x]:
+        change = true
+        cx = x
+        break
+    if change:
+      if cx == 0 and vy != -1:
+        while vy < y:
+          result &= "\r\n"
+          inc vy
+      else:
+        result &= term.cursorGoto(cx, y)
+        vy = y
+      result &= term.resetFormat()
+      var format = newFormat()
+      for x in cx ..< grid.width:
+        let cell = grid[y * grid.width + x]
+        result &= term.processFormat(format, cell.format)
+        result &= term.processOutputString(cell.str, w)
+      result &= term.clearEnd()
 
 proc hideCursor*(term: Terminal) =
   term.outfile.hideCursor()