about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2022-07-30 13:20:26 +0200
committerbptato <nincsnevem662@gmail.com>2022-07-30 13:20:26 +0200
commitf08b26d932d57e76a01e800371a27275961419d2 (patch)
treef5aaf3476b61a1b7a70f42b04ebee63e422abdc2
parentca81bbcecd3777e8b20e12332ef813b874dd7fa5 (diff)
downloadchawan-f08b26d932d57e76a01e800371a27275961419d2.tar.gz
Enable raw mode during rendering
So that non-processed characters aren't displayed on the screen
-rw-r--r--src/client.nim6
-rw-r--r--src/io/buffer.nim11
-rw-r--r--src/io/term.nim21
3 files changed, 32 insertions, 6 deletions
diff --git a/src/client.nim b/src/client.nim
index 6d729572..2ab6281b 100644
--- a/src/client.nim
+++ b/src/client.nim
@@ -11,6 +11,7 @@ import io/buffer
 import io/cell
 import io/lineedit
 import io/loader
+import io/term
 import js/javascript
 import js/regex
 import types/url
@@ -468,7 +469,10 @@ proc launchClient*(client: Client, pages: seq[string], ctype: string, dump: bool
     eprint e.msg
     quit(1)
 
-  if stdout.isatty and not dump: client.inputLoop()
+  if stdout.isatty and not dump:
+    when defined(posix):
+      enableRawMode()
+    client.inputLoop()
   else:
     var buffer = client.buffer
     while buffer.next != nil:
diff --git a/src/io/buffer.nim b/src/io/buffer.nim
index 7bc181a5..5652e84c 100644
--- a/src/io/buffer.nim
+++ b/src/io/buffer.nim
@@ -93,7 +93,7 @@ func generateFullOutput(buffer: Buffer): string =
   for cell in buffer.display:
     if x >= buffer.width:
       result &= EL()
-      result &= '\n'
+      result &= "\r\n"
       x = 0
       w = 0
 
@@ -104,7 +104,7 @@ func generateFullOutput(buffer: Buffer): string =
     inc x
 
   result &= EL()
-  result &= '\n'
+  result &= "\r\n"
 
 # 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
@@ -1178,13 +1178,14 @@ proc drawBuffer*(buffer: Buffer) =
   var format = newFormat()
   for line in buffer.lines:
     if line.formats.len == 0:
-      print(line.str & '\n')
+      print(line.str & "\r\n")
     else:
       var x = 0
       var i = 0
       for f in line.formats:
         var outstr = ""
-        assert f.pos < line.str.width(), "fpos " & $f.pos & "\nstr" & line.str & "\n"
+        #TODO TODO TODO renderhtml has broken format outputting
+        #assert f.pos < line.str.width(), "fpos " & $f.pos & "\nstr" & line.str & "\n"
         while x < f.pos:
           var r: Rune
           fastRuneAt(line.str, i, r)
@@ -1194,7 +1195,7 @@ proc drawBuffer*(buffer: Buffer) =
         print(format.processFormat(f.format))
       print(line.str.substr(i))
       print(format.processFormat(newFormat()))
-      print('\n')
+      print("\r\n")
 
 proc refreshBuffer*(buffer: Buffer, peek = false) =
   buffer.title = buffer.getTitle()
diff --git a/src/io/term.nim b/src/io/term.nim
index 8424ee10..914b5398 100644
--- a/src/io/term.nim
+++ b/src/io/term.nim
@@ -1,4 +1,5 @@
 import terminal
+import std/exitprocs
 when defined(posix):
   import termios
 
@@ -12,6 +13,26 @@ type
     width_px*: int
     height_px*: int
 
+when defined(posix):
+  # see https://viewsourcecode.org/snaptoken/kilo/02.enteringRawMode.html
+  let stdin_fileno = stdin.getFileHandle()
+  var orig_termios: Termios
+  proc disableRawMode*() {.noconv.} =
+    discard tcSetAttr(stdin_fileno, TCSAFLUSH, addr orig_termios)
+
+  proc enableRawMode*() =
+    addExitProc(disableRawMode)
+    discard tcGetAttr(stdin_fileno, addr orig_termios)
+    var raw = orig_termios
+    raw.c_iflag = raw.c_iflag and not (BRKINT or ICRNL or INPCK or ISTRIP or IXON)
+    raw.c_oflag = raw.c_oflag and not (OPOST)
+    raw.c_cflag = raw.c_cflag or CS8
+    # we do not currently set ISIG, so that ctrl+c can be used to
+    # immediately return to the input loop.
+    #TODO set it once we have separated i/o from layout
+    raw.c_lflag = raw.c_lflag and not (ECHO or ICANON or IEXTEN)
+    discard tcSetAttr(stdin_fileno, TCSAFLUSH, addr raw)
+
 proc getTermAttributes*(): TermAttributes =
   if stdin.isatty():
     when defined(posix):