about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2021-08-06 17:38:40 +0200
committerbptato <nincsnevem662@gmail.com>2021-08-06 17:38:40 +0200
commit56b308e71f20dd6563634867e698e5c8d3290f58 (patch)
tree0cebb2740f344ad4f2262ccb3f5fff4e58e9c16d
parent6d50a0f7d1af3da77fcea7290ac02a43e8f454e4 (diff)
downloadchawan-56b308e71f20dd6563634867e698e5c8d3290f58.tar.gz
Refactor display.nim and twtio.nim
-rw-r--r--res/config6
-rw-r--r--src/config.nim11
-rw-r--r--src/html/dom.nim2
-rw-r--r--src/html/htmlparser.nim2
-rw-r--r--src/io/buffer.nim147
-rw-r--r--src/io/display.nim374
-rw-r--r--src/io/lineedit.nim (renamed from src/io/twtio.nim)25
-rw-r--r--src/main.nim6
-rw-r--r--src/utils/eprint.nim13
9 files changed, 170 insertions, 416 deletions
diff --git a/res/config b/res/config
index c9a7c099..f059898e 100644
--- a/res/config
+++ b/res/config
@@ -27,10 +27,10 @@ nmap > PAGE_RIGHT
 nmap < PAGE_LEFT
 nmap C-e SCROLL_DOWN
 nmap C-y SCROLL_UP
-nmap zh SCROLL_LEFT
-nmap zl SCROLL_RIGHT
 nmap J SCROLL_DOWN
 nmap K SCROLL_UP
+nmap ( SCROLL_LEFT
+nmap ) SCROLL_RIGHT
 nmap C-m CLICK
 nmap C-j CLICK
 nmap C-l CHANGE_LOCATION
@@ -41,7 +41,7 @@ nmap gg CURSOR_FIRST_LINE
 nmap G CURSOR_LAST_LINE
 nmap M-[H CURSOR_FIRST_LINE
 nmap M-[F CURSOR_LAST_LINE
-nmap zz CENTER_LINE
+nmap z CENTER_LINE
 nmap C-g LINE_INFO
 
 #line editing keybindings
diff --git a/src/config.nim b/src/config.nim
index 4713db07..1d2e2a46 100644
--- a/src/config.nim
+++ b/src/config.nim
@@ -151,3 +151,14 @@ proc readConfig*() =
   when defined(debug):
     readConfig("res" / "config")
   readConfig(getConfigDir() / "twt" / "config")
+
+proc getNormalAction*(s: string): TwtAction =
+  if gconfig.nmap.hasKey(s):
+    return gconfig.nmap[s]
+  return NO_ACTION
+
+proc getLinedAction*(s: string): TwtAction =
+  if gconfig.lemap.hasKey(s):
+    return gconfig.lemap[s]
+  return NO_ACTION
+
diff --git a/src/html/dom.nim b/src/html/dom.nim
index 2227aece..b1e1af4c 100644
--- a/src/html/dom.nim
+++ b/src/html/dom.nim
@@ -16,8 +16,6 @@ import ../types/enums
 
 import ../utils/twtstr
 
-import ../io/twtio
-
 const css = staticRead"../../res/default.css"
 let stylesheet = parseCSS(newStringStream(css))
 
diff --git a/src/html/htmlparser.nim b/src/html/htmlparser.nim
index 94c474f0..f5a8190b 100644
--- a/src/html/htmlparser.nim
+++ b/src/html/htmlparser.nim
@@ -10,8 +10,6 @@ import ../types/tagtypes
 import ../utils/twtstr
 import ../utils/radixtree
 
-import ../io/twtio
-
 import dom
 import entity
 
diff --git a/src/io/buffer.nim b/src/io/buffer.nim
index 5eb2c71b..7032a138 100644
--- a/src/io/buffer.nim
+++ b/src/io/buffer.nim
@@ -1,4 +1,5 @@
 import options
+import terminal
 import uri
 import tables
 import strutils
@@ -12,8 +13,10 @@ import ../utils/eprint
 
 import ../html/dom
 
-import ./twtio
+import ../config
+
 import ./term
+import ./lineedit
 
 type
   Cell = object of RootObj
@@ -52,7 +55,6 @@ type
     elements*: seq[Element]
     idelements*: Table[string, Element]
     selectedlink*: Node
-    printwrite*: bool
     attrs*: TermAttributes
     document*: Document
     displaycontrols*: bool
@@ -187,7 +189,7 @@ proc clearBuffer*(buffer: Buffer) =
   buffer.selectedlink = nil
 
 proc restoreCursorX(buffer: Buffer) =
-  buffer.cursorx = min(buffer.currentLineWidth() - 1, buffer.xend)
+  buffer.cursorx = max(min(buffer.currentLineWidth() - 1, buffer.xend), 0)
 
 proc scrollTo*(buffer: Buffer, y: int) =
   if y == buffer.fromy:
@@ -206,8 +208,14 @@ proc cursorTo*(buffer: Buffer, x: int, y: int) =
   elif buffer.fromy + buffer.height - 1 <= buffer.cursory:
     buffer.fromy = max(buffer.cursory - buffer.height + 2, 0)
     buffer.redraw = true
+
   buffer.cursorx = min(max(x, 0), buffer.currentLineWidth())
-  #buffer.fromX = min(max(buffer.currentLineWidth() - buffer.width + 1, 0), 0) #TODO
+  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 cursorDown*(buffer: Buffer) =
   if buffer.cursory < buffer.lastLine():
@@ -273,12 +281,12 @@ proc cursorNextWord*(buffer: Buffer) =
   var y = buffer.cursory
   if llen >= 0:
 
-    while buffer.lines[y][x].rune != Rune(' '):
+    while not buffer.lines[y][x].rune.breaksWord():
       if x >= llen:
         break
       inc x
 
-    while buffer.lines[y][x].rune == Rune(' '):
+    while buffer.lines[y][x].rune.breaksWord():
       if x >= llen:
         break
       inc x
@@ -293,12 +301,12 @@ proc cursorPrevWord*(buffer: Buffer) =
   var x = buffer.cursorx
   var y = buffer.cursory
   if buffer.currentLineWidth() > 0:
-    while buffer.lines[y][x].rune != Rune(' '):
+    while not buffer.lines[y][x].rune.breaksWord():
       if x == 0:
         break
       dec x
 
-    while buffer.lines[y][x].rune == Rune(' '):
+    while buffer.lines[y][x].rune.breaksWord():
       if x == 0:
         break
       dec x
@@ -520,3 +528,126 @@ proc renderPlainText*(buffer: Buffer, text: string) =
     buffer.setText(0, y, line.toRunes())
 
   buffer.refreshDisplay()
+
+proc cursorBufferPos(buffer: Buffer) =
+  var x = max(buffer.cursorx - buffer.fromx, 0)
+  var y = buffer.cursory - buffer.fromy
+  termGoto(x, y)
+
+proc clearStatusMsg*(at: int) =
+  setCursorPos(0, at)
+  eraseLine()
+
+proc statusMsg*(str: string, at: int) =
+  clearStatusMsg(at)
+  print(str.ansiStyle(styleReverse).ansiReset())
+
+proc statusMsgForBuffer(buffer: Buffer) =
+  var msg = $(buffer.cursory + 1) & "/" & $(buffer.lastLine() + 1) & " (" &
+            $buffer.atPercentOf() & "%) " &
+            "<" & buffer.title & ">"
+  if buffer.hovertext.len > 0:
+    msg &= " " & buffer.hovertext
+  statusMsg(msg.maxString(buffer.width), buffer.height)
+
+proc displayBuffer(buffer: Buffer) =
+  eraseScreen()
+  termGoto(0, 0)
+
+  print(buffer.generateFullOutput().ansiReset())
+
+proc inputLoop(attrs: TermAttributes, buffer: Buffer): bool =
+  var s = ""
+  var feedNext = false
+  while true:
+    buffer.redraw = false
+    stdout.showCursor()
+    buffer.cursorBufferPos()
+    if not feedNext:
+      s = ""
+    else:
+      feedNext = false
+    let c = getch()
+    s &= c
+    let action = getNormalAction(s)
+    var redraw = false
+    var reshape = false
+    var nostatus = false
+    case action
+    of ACTION_QUIT:
+      eraseScreen()
+      setCursorPos(0, 0)
+      return false
+    of ACTION_CURSOR_LEFT: buffer.cursorLeft()
+    of ACTION_CURSOR_DOWN: buffer.cursorDown()
+    of ACTION_CURSOR_UP: buffer.cursorUp()
+    of ACTION_CURSOR_RIGHT: buffer.cursorRight()
+    of ACTION_CURSOR_LINEBEGIN: buffer.cursorLineBegin()
+    of ACTION_CURSOR_LINEEND: buffer.cursorLineEnd()
+    of ACTION_CURSOR_NEXT_WORD: buffer.cursorNextWord()
+    of ACTION_CURSOR_PREV_WORD: buffer.cursorPrevWord()
+    of ACTION_CURSOR_NEXT_LINK: buffer.cursorNextLink()
+    of ACTION_CURSOR_PREV_LINK: buffer.cursorPrevLink()
+    of ACTION_PAGE_DOWN: buffer.pageDown()
+    of ACTION_PAGE_UP: buffer.pageUp()
+    of ACTION_PAGE_RIGHT: buffer.pageRight()
+    of ACTION_PAGE_LEFT: buffer.pageLeft()
+    of ACTION_HALF_PAGE_DOWN: buffer.halfPageDown()
+    of ACTION_HALF_PAGE_UP: buffer.halfPageUp()
+    of ACTION_CURSOR_FIRST_LINE: buffer.cursorFirstLine()
+    of ACTION_CURSOR_LAST_LINE: buffer.cursorLastLine()
+    of ACTION_CURSOR_TOP: buffer.cursorTop()
+    of ACTION_CURSOR_MIDDLE: buffer.cursorMiddle()
+    of ACTION_CURSOR_BOTTOM: buffer.cursorBottom()
+    of ACTION_CENTER_LINE: buffer.centerLine()
+    of ACTION_SCROLL_DOWN: buffer.scrollDown()
+    of ACTION_SCROLL_UP: buffer.scrollUp()
+    of ACTION_SCROLL_LEFT: buffer.scrollLeft()
+    of ACTION_SCROLL_RIGHT: buffer.scrollRight()
+    of ACTION_CLICK:
+      discard
+    of ACTION_CHANGE_LOCATION:
+      var url = $buffer.location
+
+      clearStatusMsg(buffer.height)
+      let status = readLine("URL: ", url, buffer.width)
+      if status:
+        buffer.setLocation(parseUri(url))
+        return true
+    of ACTION_LINE_INFO:
+      statusMsg("line " & $buffer.cursory & "/" & $buffer.lastLine() & " col " & $(buffer.cursorx + 1) & "/" & $buffer.currentLineWidth() & " cell width: " & $buffer.currentCellWidth(), buffer.width)
+      nostatus = true
+    of ACTION_FEED_NEXT:
+      feedNext = true
+    of ACTION_RELOAD: return true
+    of ACTION_RESHAPE:
+      reshape = true
+      redraw = true
+    of ACTION_REDRAW: redraw = true
+    else: discard
+    stdout.hideCursor()
+
+    if buffer.refreshTermAttrs():
+      redraw = true
+      reshape = true
+
+    if buffer.redraw:
+      redraw = true
+
+    if reshape:
+      buffer.reshape()
+    if redraw:
+      buffer.refreshDisplay()
+      buffer.displayBuffer()
+
+    if not nostatus:
+      buffer.statusMsgForBuffer()
+    else:
+      nostatus = false
+
+proc displayPage*(attrs: TermAttributes, buffer: Buffer): bool =
+  discard buffer.gotoAnchor()
+  buffer.displayBuffer()
+  buffer.statusMsgForBuffer()
+  return inputLoop(attrs, buffer)
+
diff --git a/src/io/display.nim b/src/io/display.nim
deleted file mode 100644
index f5c9f645..00000000
--- a/src/io/display.nim
+++ /dev/null
@@ -1,374 +0,0 @@
-import terminal
-import options
-import uri
-import strutils
-import unicode
-
-import ../types/enums
-
-import ../utils/twtstr
-
-import ../html/dom
-
-import ../config
-
-import ./buffer
-import ./twtio
-import ./term
-
-proc clearStatusMsg*(at: int) =
-  setCursorPos(0, at)
-  eraseLine()
-
-proc statusMsg*(str: string, at: int) =
-  clearStatusMsg(at)
-  print(str.ansiStyle(styleReverse).ansiReset())
-
-type
-  RenderState = object
-    x: int
-    y: int
-    lastwidth: int
-    fmtline: string
-    rawline: string
-    centerqueue: seq[Node]
-    centerlen: int
-    blanklines: int
-    blankspaces: int
-    nextspaces: int
-    docenter: bool
-    indent: int
-    listval: int
-    lastelem: Element
-
-func newRenderState(): RenderState =
-  return RenderState(blanklines: 1)
-
-proc write(state: var RenderState, s: string) =
-  state.fmtline &= s
-  state.rawline &= s
-
-proc write(state: var RenderState, fs: string, rs: string) =
-  state.fmtline &= fs
-  state.rawline &= rs
-
-proc flushLine(buffer: Buffer, state: var RenderState) =
-  if state.rawline.len == 0:
-    inc state.blanklines
-  assert(state.rawline.runeLen() < buffer.width, "line too long: (for node " &
-         $state.lastelem & " " & $state.lastelem.style.display & ")\n" & state.rawline)
-  buffer.writefmt(state.fmtline)
-  buffer.writeraw(state.rawline)
-  state.x = 0
-  inc state.y
-  state.nextspaces = 0
-  state.fmtline = ""
-  state.rawline = ""
-
-proc addSpaces(buffer: Buffer, state: var RenderState, n: int) =
-  if state.x + n > buffer.width:
-    buffer.flushLine(state)
-    return
-  state.blankspaces += n
-  state.write(' '.repeat(n))
-  state.x += n
-
-proc writeWrappedText(buffer: Buffer, state: var RenderState, node: Node) =
-  state.lastwidth = 0
-  var n = 0
-  var fmtword = ""
-  var rawword = ""
-  var prevl = false
-  let fmttext = node.getFmtText()
-  for w in fmttext:
-    if w.len > 0 and w[0] == '\e':
-      fmtword &= w
-      continue
-
-    for r in w.runes:
-      if r == Rune(' '):
-        if rawword.len > 0 and rawword[0] == ' ' and prevl:
-          fmtword = fmtword.substr(1)
-          rawword = rawword.substr(1)
-          state.x -= 1
-          prevl = false
-        state.write(fmtword, rawword)
-        fmtword = ""
-        rawword = ""
-
-      if r == Rune('\n'):
-        state.write(fmtword, rawword)
-        buffer.flushLine(state)
-        rawword = ""
-        fmtword = ""
-      else:
-        fmtword &= r
-        rawword &= r
-
-      state.x += r.width()
-
-      if state.x >= buffer.width:
-        state.lastwidth = max(state.lastwidth, state.x)
-        buffer.flushLine(state)
-        state.x = rawword.width()
-        prevl = true
-      else:
-        state.lastwidth = max(state.lastwidth, state.x)
-
-      inc n
-
-  state.write(fmtword, rawword)
-  if prevl:
-    state.x += rawword.width()
-    prevl = false
-
-  state.lastwidth = max(state.lastwidth, state.x)
-
-proc preAlignNode(buffer: Buffer, node: Node, state: var RenderState) =
-  let style = node.getStyle()
-  if state.rawline.len > 0 and node.firstNode() and state.blanklines == 0:
-    buffer.flushLine(state)
-
-  if node.firstNode():
-    #while state.blanklines < max(style.margin, style.margintop):
-    #  buffer.flushLine(state)
-    state.indent += style.indent
-
-  if state.rawline.len > 0 and state.blanklines == 0 and node.displayed():
-    buffer.addSpaces(state, state.nextspaces)
-    state.nextspaces = 0
-    #if state.blankspaces < max(style.margin, style.marginleft):
-    #  buffer.addSpaces(state, max(style.margin, style.marginleft) - state.blankspaces)
-
-  if style.centered and state.rawline.len == 0 and node.displayed():
-    buffer.addSpaces(state, max(buffer.width div 2 - state.centerlen div 2, 0))
-    state.centerlen = 0
-  
-  if node.isElemNode() and style.display == DISPLAY_LIST_ITEM and state.indent > 0:
-    if state.blanklines == 0:
-      buffer.flushLine(state)
-    var listchar = "•"
-    #case elem.parentElement.tagType
-    #of TAG_UL:
-    #  listchar = "•"
-    #of TAG_OL:
-    #  inc state.listval
-    #  listchar = $state.listval & ")"
-    #else:
-    #  return
-    buffer.addSpaces(state, state.indent)
-    state.write(listchar)
-    state.x += listchar.runeLen()
-    buffer.addSpaces(state, 1)
-
-proc postAlignNode(buffer: Buffer, node: Node, state: var RenderState) =
-  let style = node.getStyle()
-
-  if node.getRawLen() > 0:
-    state.blanklines = 0
-    state.blankspaces = 0
-
-  #if state.rawline.len > 0 and state.blanklines == 0:
-  #  state.nextspaces += max(style.margin, style.marginright)
-  #  if node.lastNode() and (node.isTextNode() or elem.childNodes.len == 0):
-  #    buffer.flushLine(state)
-
-  if node.lastNode():
-    #while state.blanklines < max(style.margin, style.marginbottom):
-    #  buffer.flushLine(state)
-    state.indent -= style.indent
-
-  if style.display == DISPLAY_LIST_ITEM and node.lastNode():
-    buffer.flushLine(state)
-
-proc renderNode(buffer: Buffer, node: Node, state: var RenderState) =
-  if not (node.nodeType in {ELEMENT_NODE, TEXT_NODE}):
-    return
-  let style = node.getStyle()
-  if node.nodeType == ELEMENT_NODE:
-    if Element(node).tagType in {TAG_SCRIPT, TAG_STYLE, TAG_NOSCRIPT, TAG_TITLE}:
-      return
-  if style.hidden or style.display == DISPLAY_NONE: return
-  if node.nodeType == ELEMENT_NODE:
-    state.lastelem = (Element)node
-  else:
-    state.lastelem = node.parentElement
-
-  if not state.docenter:
-    if style.centered:
-      state.centerqueue.add(node)
-      if node.lastNode():
-        state.docenter = true
-        state.centerlen = 0
-        for node in state.centerqueue:
-          state.centerlen += node.getRawLen()
-        for node in state.centerqueue:
-          buffer.renderNode(node, state)
-        state.centerqueue.setLen(0)
-        state.docenter = false
-        return
-      else:
-        return
-    if state.centerqueue.len > 0:
-      state.docenter = true
-      state.centerlen = 0
-      for node in state.centerqueue:
-        state.centerlen += node.getRawLen()
-      for node in state.centerqueue:
-        buffer.renderNode(node, state)
-      state.centerqueue.setLen(0)
-      state.docenter = false
-
-  buffer.preAlignNode(node, state)
-
-  node.x = state.x
-  node.y = state.y
-  buffer.writeWrappedText(state, node)
-  node.ex = state.x
-  node.ey = state.y
-  node.width = state.lastwidth - node.x - 1
-  node.height = state.y - node.y + 1
-
-  buffer.postAlignNode(node, state)
-
-proc setLastHtmlLine(buffer: Buffer, state: var RenderState) =
-  if state.rawline.len != 0:
-    buffer.flushLine(state)
-
-proc renderHtml*(buffer: Buffer) =
-  var stack: seq[Node]
-  let first = buffer.document.root
-  stack.add(first)
-
-  var state = newRenderState()
-  while stack.len > 0:
-    let currElem = stack.pop()
-    buffer.renderNode(currElem, state)
-    var i = currElem.childNodes.len - 1
-    while i >= 0:
-      stack.add(currElem.childNodes[i])
-      i -= 1
-
-  buffer.setLastHtmlLine(state)
-
-proc drawHtml(buffer: Buffer) =
-  var state = newRenderState()
-  for node in buffer.nodes:
-    buffer.renderNode(node, state)
-  buffer.setLastHtmlLine(state)
-
-proc statusMsgForBuffer(buffer: Buffer) =
-  var msg = $(buffer.cursory + 1) & "/" & $(buffer.lastLine() + 1) & " (" &
-            $buffer.atPercentOf() & "%) " &
-            "<" & buffer.title & ">"
-  if buffer.hovertext.len > 0:
-    msg &= " " & buffer.hovertext
-  statusMsg(msg.maxString(buffer.width), buffer.height)
-
-proc cursorBufferPos(buffer: Buffer) =
-  var x = max(buffer.cursorx - buffer.fromx, 0)
-  var y = buffer.cursory - buffer.fromy
-  termGoto(x, y)
-
-proc displayBuffer(buffer: Buffer) =
-  eraseScreen()
-  termGoto(0, 0)
-
-  print(buffer.generateFullOutput().ansiReset())
-
-proc inputLoop(attrs: TermAttributes, buffer: Buffer): bool =
-  var s = ""
-  var feedNext = false
-  while true:
-    buffer.redraw = false
-    stdout.showCursor()
-    buffer.cursorBufferPos()
-    if not feedNext:
-      s = ""
-    else:
-      feedNext = false
-    let c = getch()
-    s &= c
-    let action = getNormalAction(s)
-    var redraw = false
-    var reshape = false
-    var nostatus = false
-    case action
-    of ACTION_QUIT:
-      eraseScreen()
-      setCursorPos(0, 0)
-      return false
-    of ACTION_CURSOR_LEFT: buffer.cursorLeft()
-    of ACTION_CURSOR_DOWN: buffer.cursorDown()
-    of ACTION_CURSOR_UP: buffer.cursorUp()
-    of ACTION_CURSOR_RIGHT: buffer.cursorRight()
-    of ACTION_CURSOR_LINEBEGIN: buffer.cursorLineBegin()
-    of ACTION_CURSOR_LINEEND: buffer.cursorLineEnd()
-    of ACTION_CURSOR_NEXT_WORD: buffer.cursorNextWord()
-    of ACTION_CURSOR_PREV_WORD: buffer.cursorPrevWord()
-    of ACTION_CURSOR_NEXT_LINK: buffer.cursorNextLink()
-    of ACTION_CURSOR_PREV_LINK: buffer.cursorPrevLink()
-    of ACTION_PAGE_DOWN: buffer.pageDown()
-    of ACTION_PAGE_UP: buffer.pageUp()
-    of ACTION_PAGE_RIGHT: buffer.pageRight()
-    of ACTION_PAGE_LEFT: buffer.pageLeft()
-    of ACTION_HALF_PAGE_DOWN: buffer.halfPageDown()
-    of ACTION_HALF_PAGE_UP: buffer.halfPageUp()
-    of ACTION_CURSOR_FIRST_LINE: buffer.cursorFirstLine()
-    of ACTION_CURSOR_LAST_LINE: buffer.cursorLastLine()
-    of ACTION_CURSOR_TOP: buffer.cursorTop()
-    of ACTION_CURSOR_MIDDLE: buffer.cursorMiddle()
-    of ACTION_CURSOR_BOTTOM: buffer.cursorBottom()
-    of ACTION_CENTER_LINE: buffer.centerLine()
-    of ACTION_SCROLL_DOWN: buffer.scrollDown()
-    of ACTION_SCROLL_UP: buffer.scrollUp()
-    of ACTION_SCROLL_LEFT: buffer.scrollLeft()
-    of ACTION_SCROLL_RIGHT: buffer.scrollRight()
-    of ACTION_CLICK:
-      discard
-    of ACTION_CHANGE_LOCATION:
-      var url = $buffer.location
-
-      clearStatusMsg(buffer.height)
-      let status = readLine("URL: ", url, buffer.width)
-      if status:
-        buffer.setLocation(parseUri(url))
-        return true
-    of ACTION_LINE_INFO:
-      statusMsg("line " & $buffer.cursory & "/" & $buffer.lastLine() & " col " & $(buffer.cursorx + 1) & "/" & $buffer.currentLineWidth() & " cell width: " & $buffer.currentCellWidth(), buffer.width)
-      nostatus = true
-    of ACTION_FEED_NEXT:
-      feedNext = true
-    of ACTION_RELOAD: return true
-    of ACTION_RESHAPE:
-      reshape = true
-      redraw = true
-    of ACTION_REDRAW: redraw = true
-    else: discard
-    stdout.hideCursor()
-
-    if buffer.refreshTermAttrs():
-      redraw = true
-      reshape = true
-
-    if buffer.redraw:
-      redraw = true
-
-    if reshape:
-      buffer.reshape()
-    if redraw:
-      buffer.refreshDisplay()
-      buffer.displayBuffer()
-
-    if not nostatus:
-      buffer.statusMsgForBuffer()
-    else:
-      nostatus = false
-
-proc displayPage*(attrs: TermAttributes, buffer: Buffer): bool =
-  #buffer.printwrite = true
-  discard buffer.gotoAnchor()
-  buffer.displayBuffer()
-  buffer.statusMsgForBuffer()
-  return inputLoop(attrs, buffer)
-
diff --git a/src/io/twtio.nim b/src/io/lineedit.nim
index 26c5be02..c1c5c187 100644
--- a/src/io/twtio.nim
+++ b/src/io/lineedit.nim
@@ -1,4 +1,4 @@
-import std/terminal
+import terminal
 import tables
 import unicode
 import strutils
@@ -7,33 +7,12 @@ import sugar
 
 import ../utils/twtstr
 import ../utils/radixtree
+import ../utils/eprint
 
 import ../config
 
 import ./terminal
 
-template print*(s: varargs[string, `$`]) =
-  for x in s:
-    stdout.write(x)
-
-template printesc*(s: string) =
-  for r in s.runes:
-    if r.isControlChar():
-      stdout.write(('^' & $($r)[0].getControlLetter())
-                   .ansiFgColor(fgBlue).ansiStyle(styleBright).ansiReset())
-    else:
-      stdout.write($r)
-
-proc getNormalAction*(s: string): TwtAction =
-  if gconfig.nmap.hasKey(s):
-    return gconfig.nmap[s]
-  return NO_ACTION
-
-proc getLinedAction*(s: string): TwtAction =
-  if gconfig.lemap.hasKey(s):
-    return gconfig.lemap[s]
-  return NO_ACTION
-
 type LineState = object
   news: seq[Rune]
   s: string
diff --git a/src/main.nim b/src/main.nim
index 8394b5ab..198eedb8 100644
--- a/src/main.nim
+++ b/src/main.nim
@@ -8,7 +8,6 @@ import utils/eprint
 import html/dom
 import html/htmlparser
 
-import io/display
 import io/buffer
 import io/term
 
@@ -47,11 +46,10 @@ proc main*() =
   let buffer = newBuffer(attrs)
   let uri = parseUri(paramStr(1))
   buffers.add(buffer)
-  buffer.renderPlainText(getPageUri(uri).readAll())
   #buffer.document = parseHtml(getPageUri(uri))
   #buffer.setLocation(uri)
   #buffer.document.applyDefaultStylesheet()
-  #buffer.renderHtml()
+  buffer.renderPlainText(getPageUri(uri).readAll())
   var lastUri = uri
   while displayPage(attrs, buffer):
     statusMsg("Loading...", buffer.height)
@@ -64,6 +62,6 @@ proc main*() =
         discard
       else:
         buffer.document = parseHtml(getPageUri(buffer.location))
-      buffer.renderHtml()
+      buffer.renderPlainText(getPageUri(uri).readAll())
     lastUri = newUri
 main()
diff --git a/src/utils/eprint.nim b/src/utils/eprint.nim
index 23248363..128d34d9 100644
--- a/src/utils/eprint.nim
+++ b/src/utils/eprint.nim
@@ -9,3 +9,16 @@ template eprint*(s: varargs[string, `$`]) = {.cast(noSideEffect).}:
       stderr.write(' ')
     stderr.write(x)
   stderr.write('\n')
+
+template print*(s: varargs[string, `$`]) =
+  for x in s:
+    stdout.write(x)
+
+template printesc*(s: string) =
+  for r in s.runes:
+    if r.isControlChar():
+      stdout.write(('^' & $($r)[0].getControlLetter())
+                   .ansiFgColor(fgBlue).ansiStyle(styleBright).ansiReset())
+    else:
+      stdout.write($r)
+