about summary refs log tree commit diff stats
path: root/src/io
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2021-12-21 17:11:58 +0100
committerbptato <nincsnevem662@gmail.com>2021-12-21 17:11:58 +0100
commit8a1611e1c6c81b4ee5b7f33f3f539ee1db53045e (patch)
tree998ca1deeb00092f70de183515b2df847e1dfaa0 /src/io
parentbbb14729f8b0c612f79ba96566d0118fc8c2290d (diff)
downloadchawan-8a1611e1c6c81b4ee5b7f33f3f539ee1db53045e.tar.gz
Honestly I'm not sure what I added here...
Diffstat (limited to 'src/io')
-rw-r--r--src/io/buffer.nim138
-rw-r--r--src/io/cell.nim29
-rw-r--r--src/io/term.nim4
3 files changed, 72 insertions, 99 deletions
diff --git a/src/io/buffer.nim b/src/io/buffer.nim
index 3180aa2b..775e6557 100644
--- a/src/io/buffer.nim
+++ b/src/io/buffer.nim
@@ -43,6 +43,7 @@ type
     showsource*: bool
     rootbox*: CSSBox
     prevnodes*: seq[Node]
+    sourcepair*: Buffer
 
 proc newBuffer*(): Buffer =
   new(result)
@@ -68,7 +69,6 @@ func generateFullOutput*(buffer: Buffer): string =
       x = 0
       w = 0
 
-
     result &= formatting.processFormatting(cell.formatting)
     result &= $cell.runes
 
@@ -82,7 +82,7 @@ func generateFullOutput*(buffer: Buffer): string =
 # generate a sequence of instructions to replace the previous frame with the
 # current one. ideally should be used when small changes are made (e.g. hover
 # changes underlining)
-func generateSwapOutput*(buffer: Buffer): string =
+func generateSwapOutput(buffer: Buffer): string =
   var formatting = newFormatting()
   let curr = buffer.display
   let prev = buffer.prevdisplay
@@ -151,17 +151,24 @@ func generateSwapOutput*(buffer: Buffer): string =
   #if text.len > 0:
   #  result &= $text
 
-func generateStatusMessage*(buffer: Buffer): string =
+func generateStatusMessage(buffer: Buffer): string =
+  result &= HVP(buffer.height + 1, 1)
+  result &= SGR()
+  var formatting = newFormatting()
+  var w = 0
   for cell in buffer.statusmsg:
-    for r in cell.runes:
-      if r != Rune(0):
-        result &= $r
+    result &= formatting.processFormatting(cell.formatting)
+    result &= $cell.runes
+    w += cell.width()
+  if w < buffer.width:
+    result &= EL()
+  result &= SGR()
 
-func numLines*(buffer: Buffer): int = buffer.lines.len
+func numLines(buffer: Buffer): int = buffer.lines.len
 
-func lastVisibleLine*(buffer: Buffer): int = min(buffer.fromy + buffer.height, buffer.numLines)
+func lastVisibleLine(buffer: Buffer): int = min(buffer.fromy + buffer.height, buffer.numLines)
 
-func currentLineWidth*(buffer: Buffer): int =
+func currentLineWidth(buffer: Buffer): int =
   if buffer.cursory > buffer.lines.len:
     return 0
   return buffer.lines[buffer.cursory].width()
@@ -224,33 +231,22 @@ func maxScreenWidth*(buffer: Buffer): int =
   for line in buffer.lines[buffer.fromy..buffer.lastVisibleLine - 1]:
     result = max(line.width(), result)
 
-func atPercentOf*(buffer: Buffer): int =
+func atPercentOf(buffer: Buffer): int =
   if buffer.lines.len == 0: return 100
   return (100 * (buffer.cursory + 1)) div buffer.numLines
 
-func canScroll*(buffer: Buffer): bool =
-  return buffer.numLines >= buffer.height
-
 proc addLine(buffer: Buffer) =
   buffer.lines.addLine()
 
-proc clearText*(buffer: Buffer) =
+proc clearText(buffer: Buffer) =
   buffer.lines.setLen(0)
   buffer.addLine()
 
-proc clearBuffer*(buffer: Buffer) =
-  buffer.clearText()
-  buffer.cursorx = 0
-  buffer.cursory = 0
-  buffer.fromx = 0
-  buffer.fromy = 0
-  buffer.hovertext = ""
-
-proc clearDisplay*(buffer: Buffer) =
+proc clearDisplay(buffer: Buffer) =
   buffer.prevdisplay = buffer.display
   buffer.display = newFixedGrid(buffer.width, buffer.height)
 
-proc refreshDisplay*(buffer: Buffer) =
+proc refreshDisplay(buffer: Buffer) =
   var r: Rune
   var y = 0
   buffer.clearDisplay()
@@ -297,33 +293,7 @@ proc refreshDisplay*(buffer: Buffer) =
 proc restoreCursorX(buffer: Buffer) =
   buffer.cursorx = max(min(buffer.currentLineWidth() - 1, buffer.xend), 0)
 
-proc scrollTo*(buffer: Buffer, y: int) =
-  if y == buffer.fromy:
-    return
-  buffer.fromy = min(max(buffer.numLines - buffer.height, 0), y)
-  buffer.cursory = min(max(buffer.fromy, buffer.cursory), buffer.fromy + buffer.height)
-  buffer.redraw = true
-  buffer.restoreCursorX()
-
-proc cursorTo*(buffer: Buffer, x, y: int) =
-  buffer.redraw = false
-  buffer.cursory = min(max(y, 0), buffer.numLines - 1)
-  if buffer.fromy > buffer.cursory:
-    buffer.fromy = max(buffer.cursory, 0)
-    buffer.redraw = true
-  elif buffer.fromy + buffer.height - 1 <= buffer.cursory:
-    buffer.fromy = max(buffer.cursory - buffer.height + 1, 0)
-    buffer.redraw = true
-
-  buffer.cursorx = min(max(x, 0), buffer.currentLineWidth())
-  if buffer.fromx < buffer.cursorx - buffer.width:
-    buffer.fromx = max(0, buffer.cursorx - buffer.width)
-    buffer.redraw = true
-  elif buffer.fromx > buffer.cursorx:
-    buffer.fromx = buffer.cursorx
-    buffer.redraw = true
-
-proc setCursorXB*(buffer: Buffer, byte: int) =
+proc setCursorXB(buffer: Buffer, byte: int) =
   var b = buffer.currentCursorBytes()
   if byte == b:
     return
@@ -352,8 +322,7 @@ proc setCursorXB*(buffer: Buffer, byte: int) =
     buffer.redraw = true
   buffer.xend = buffer.cursorx
 
-
-proc setCursorX*(buffer: Buffer, x: int) =
+proc setCursorX(buffer: Buffer, x: int) =
   if buffer.cursorx == x:
     return
   var b = buffer.currentCursorBytes()
@@ -380,7 +349,7 @@ proc setCursorX*(buffer: Buffer, x: int) =
     buffer.redraw = true
   buffer.xend = buffer.cursorx
 
-proc setCursorY*(buffer: Buffer, y: int) =
+proc setCursorY(buffer: Buffer, y: int) =
   if buffer.cursory == y:
     return
   if y - buffer.fromy >= 0 and y - buffer.height < buffer.fromy:
@@ -394,6 +363,18 @@ proc setCursorY*(buffer: Buffer, y: int) =
     buffer.redraw = true
   buffer.restoreCursorX()
 
+proc setCursorXY*(buffer: Buffer, x, y: int) =
+  buffer.setCursorY(max(min(y, buffer.numLines - 1), 0))
+  buffer.setCursorX(max(min(buffer.currentLineWidth(), x), 0))
+
+proc setFromXY*(buffer: Buffer, x, y: int) =
+  buffer.fromy = max(min(y, buffer.maxfromy), 0)
+  buffer.fromx = max(min(x, buffer.maxfromx), 0)
+
+proc setCursorXBY(buffer: Buffer, x, y: int) =
+  buffer.setCursorY(y)
+  buffer.setCursorXB(x)
+
 proc cursorDown*(buffer: Buffer) =
   if buffer.cursory < buffer.numLines - 1:
     buffer.setCursorY(buffer.cursory + 1)
@@ -507,8 +488,7 @@ proc cursorNextLink*(buffer: Buffer) =
       let format = line.formats[i]
       let fl = format.nodes.getLink()
       if fl != nil and fl != link:
-        buffer.setCursorY(y)
-        buffer.setCursorXB(format.pos)
+        buffer.setCursorXBY(format.pos, y)
         return
       inc i
 
@@ -548,8 +528,7 @@ proc cursorPrevLink*(buffer: Buffer) =
               ly = iy
               lx = format.pos
             dec i
-        buffer.setCursorY(ly)
-        buffer.setCursorXB(lx)
+        buffer.setCursorXBY(lx, ly)
         return
       dec i
 
@@ -794,7 +773,8 @@ proc updateHover(buffer: Buffer) =
         elem.refreshStyle()
     let link = nodes.getLink()
     if link != nil:
-      buffer.hovertext = "(link)"
+      if link.tagType == TAG_A:
+        buffer.hovertext = HTMLAnchorElement(link).href
     else:
       buffer.hovertext = ""
     for node in buffer.prevnodes:
@@ -857,7 +837,7 @@ let ua_stylesheet = newStringStream(css).parseStylesheet()
 #TODO refactor
 var ss_init = false
 var user_stylesheet: CSSStylesheet
-proc renderDocument*(buffer: Buffer) =
+proc renderDocument(buffer: Buffer) =
   buffer.clearText()
 
   if not ss_init:
@@ -866,8 +846,6 @@ proc renderDocument*(buffer: Buffer) =
 
   buffer.document.applyStylesheets(ua_stylesheet, user_stylesheet)
   buffer.rootbox = buffer.document.alignBoxes(buffer.attrs)
-  if buffer.rootbox == nil:
-    return
   var stack: seq[CSSBox]
   stack.add(buffer.rootbox)
   while stack.len > 0:
@@ -888,7 +866,7 @@ proc render*(buffer: Buffer) =
   else:
     buffer.renderDocument()
 
-proc cursorBufferPos*(buffer: Buffer) =
+proc cursorBufferPos(buffer: Buffer) =
   let x = max(buffer.cursorx - buffer.fromx, 0)
   let y = buffer.cursory - buffer.fromy
   print(HVP(y + 1, x + 1))
@@ -896,27 +874,33 @@ proc cursorBufferPos*(buffer: Buffer) =
 proc clearStatusMessage(buffer: Buffer) =
   buffer.statusmsg = newFixedGrid(buffer.width)
 
-proc setStatusMessage*(buffer: Buffer, str: string) =
+proc writeStatusMessage(buffer: Buffer, str: string, formatting: Formatting = Formatting()) =
   buffer.clearStatusMessage()
-  let text = str.toRunes()
   var i = 0
-  var n = 0
-  while i < text.len:
-    if text[i].width() == 0:
-      inc n
-    buffer.statusmsg[i - n].runes.add(text[i])
-    inc i
+  for r in str.runes:
+    i += r.width()
+    if i >= buffer.statusmsg.len:
+      buffer.statusmsg[^1].runes.setLen(0)
+      buffer.statusmsg[^1].runes.add(Rune('$'))
+      break
+    buffer.statusmsg[i].runes.add(r)
+    buffer.statusmsg[i].formatting = formatting
 
 proc statusMsgForBuffer(buffer: Buffer) =
   var msg = $(buffer.cursory + 1) & "/" & $buffer.numLines & " (" &
             $buffer.atPercentOf() & "%) " & "<" & buffer.title & ">"
   if buffer.hovertext.len > 0:
     msg &= " " & buffer.hovertext
-  buffer.setStatusMessage(msg.ansiStyle(styleReverse).ansiReset())
+  var formatting: Formatting
+  formatting.reverse_on
+  buffer.writeStatusMessage(msg, formatting)
+
+proc setStatusMessage*(buffer: Buffer, str: string) =
+  buffer.writeStatusMessage(str)
+  buffer.nostatus = true
 
 proc lineInfo*(buffer: Buffer) =
     buffer.setStatusMessage("line " & $(buffer.cursory + 1) & "/" & $buffer.numLines & " col " & $(buffer.cursorx + 1) & "/" & $buffer.currentLineWidth() & " cell width: " & $buffer.currentDisplayCell().width())
-    buffer.nostatus = true
 
 proc displayBufferSwapOutput(buffer: Buffer) =
   print(buffer.generateSwapOutput())
@@ -925,15 +909,7 @@ proc displayBuffer(buffer: Buffer) =
   print(buffer.generateFullOutput())
 
 proc displayStatusMessage*(buffer: Buffer) =
-  print(HVP(buffer.height + 1, 1))
-  print(SGR())
   print(buffer.generateStatusMessage())
-  print(EL())
-
-proc toggleSource*(buffer: Buffer) =
-  buffer.showsource = not buffer.showsource
-  buffer.reshape = true
-  buffer.redraw = true
 
 proc click*(buffer: Buffer): string =
   let link = buffer.getCursorLink()
diff --git a/src/io/cell.nim b/src/io/cell.nim
index f8b2b3cb..a4f56d61 100644
--- a/src/io/cell.nim
+++ b/src/io/cell.nim
@@ -14,6 +14,7 @@ type
     FLAG_UNDERLINE
     FLAG_STRIKE
     FLAG_OVERLINE
+    FLAG_REVERSE
 
   Formatting* = object
     fgcolor*: CellColor
@@ -42,6 +43,7 @@ type
 func italic(formatting: Formatting): bool = FLAG_ITALIC in formatting.flags
 func bold(formatting: Formatting): bool = FLAG_BOLD in formatting.flags
 func underline(formatting: Formatting): bool = FLAG_UNDERLINE in formatting.flags
+func reverse(formatting: Formatting): bool = FLAG_REVERSE in formatting.flags
 func strike(formatting: Formatting): bool = FLAG_STRIKE in formatting.flags
 func overline(formatting: Formatting): bool = FLAG_OVERLINE in formatting.flags
 
@@ -54,28 +56,15 @@ proc bold_off*(formatting: var Formatting) = formatting.flags.excl(FLAG_BOLD)
 proc underline_on*(formatting: var Formatting) = formatting.flags.incl(FLAG_UNDERLINE)
 proc underline_off*(formatting: var Formatting) = formatting.flags.excl(FLAG_UNDERLINE)
 
+proc reverse_on*(formatting: var Formatting) = formatting.flags.incl(FLAG_REVERSE)
+proc reverse_off*(formatting: var Formatting) = formatting.flags.excl(FLAG_REVERSE)
+
 proc strike_on*(formatting: var Formatting) = formatting.flags.incl(FLAG_STRIKE)
 proc strike_off*(formatting: var Formatting) = formatting.flags.excl(FLAG_STRIKE)
 
 proc overline_on*(formatting: var Formatting) = formatting.flags.incl(FLAG_OVERLINE)
 proc overline_off*(formatting: var Formatting) = formatting.flags.excl(FLAG_OVERLINE)
 
-proc `bold=`*(formatting: var Formatting, b: bool) =
-  if b: formatting.flags.incl(FLAG_BOLD)
-  else: formatting.flags.excl(FLAG_BOLD)
-
-proc `underline=`*(formatting: var Formatting, b: bool) =
-  if b: formatting.flags.incl(FLAG_UNDERLINE)
-  else: formatting.flags.excl(FLAG_UNDERLINE)
-
-proc `strike=`*(formatting: var Formatting, b: bool) =
-  if b: formatting.flags.incl(FLAG_STRIKE)
-  else: formatting.flags.excl(FLAG_STRIKE)
-
-proc `overline=`*(formatting: var Formatting, b: bool) =
-  if b: formatting.flags.incl(FLAG_OVERLINE)
-  else: formatting.flags.excl(FLAG_OVERLINE)
-
 #TODO ?????
 func `==`*(a: FixedCell, b: FixedCell): bool =
   return a.formatting == b.formatting and
@@ -215,12 +204,16 @@ proc parseAnsiCode*(formatting: var Formatting, buf: string, fi: int): int =
             formatting.italic_on
           of 4:
             formatting.underline_on
+          of 7:
+            formatting.reverse_on
           of 9:
             formatting.strike_on
           of 22:
             formatting.bold_off
           of 23:
             formatting.italic_off
+          of 27:
+            formatting.reverse_off
           of 29:
             formatting.strike_off
           of 30..37:
@@ -285,6 +278,8 @@ proc processFormatting*(formatting: var Formatting, cellf: Formatting): string =
       result &= SGR(23)
     if formatting.underline and not cellf.underline:
       result &= SGR(24)
+    if formatting.reverse and not cellf.reverse:
+      result &= SGR(27)
     if formatting.strike and not cellf.strike:
       result &= SGR(29)
     if formatting.overline and not cellf.overline:
@@ -318,6 +313,8 @@ proc processFormatting*(formatting: var Formatting, cellf: Formatting): string =
       result &= SGR(3)
     if not formatting.underline and cellf.underline:
       result &= SGR(4)
+    if not formatting.reverse and cellf.reverse:
+      result &= SGR(7)
     if not formatting.strike and cellf.strike:
       result &= SGR(9)
     if not formatting.overline and cellf.overline:
diff --git a/src/io/term.nim b/src/io/term.nim
index a51b2a56..2e859d66 100644
--- a/src/io/term.nim
+++ b/src/io/term.nim
@@ -16,7 +16,7 @@ proc getTermAttributes*(): TermAttributes =
     when defined(posix):
       var win: IOctl_WinSize
       if ioctl(cint(getOsFileHandle(stdout)), TIOCGWINSZ, addr win) != -1:
-        result.width = int(win.ws_col)
+        result.width = int(win.ws_col) - 1
         result.height = int(win.ws_row)
         result.width_px = int(win.ws_xpixel)
         result.height_px = int(win.ws_ypixel)
@@ -24,7 +24,7 @@ proc getTermAttributes*(): TermAttributes =
         result.ppl = int(win.ws_ypixel) div int(win.ws_row)
         return
   #fail
-  result.width = terminalWidth()
+  result.width = terminalWidth() - 1
   result.height = terminalHeight()
   if result.height == 0:
     result.height = 24