about summary refs log tree commit diff stats
path: root/src/display
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2024-01-17 14:08:50 +0100
committerbptato <nincsnevem662@gmail.com>2024-01-17 14:25:23 +0100
commit0bcaa12bb343bfc7b7c1fe70649a378d8647b256 (patch)
tree0dd01b9f6ac0bfd72a42b420edcd56ff09efe96d /src/display
parentc20df592ada6f699389f62d57aae196b5580ed89 (diff)
downloadchawan-0bcaa12bb343bfc7b7c1fe70649a378d8647b256.tar.gz
Remove std/terminal dependency
It is mostly unnecessary, and conflicts with our use of termcap anyway.
Diffstat (limited to 'src/display')
-rw-r--r--src/display/term.nim44
-rw-r--r--src/display/winattrs.nim74
2 files changed, 65 insertions, 53 deletions
diff --git a/src/display/term.nim b/src/display/term.nim
index 3bcfbf4f..b3f98230 100644
--- a/src/display/term.nim
+++ b/src/display/term.nim
@@ -4,7 +4,6 @@ import std/posix
 import std/streams
 import std/strutils
 import std/tables
-import std/terminal
 import std/termios
 import std/unicode
 
@@ -21,6 +20,8 @@ import chakasu/charset
 import chakasu/decoderstream
 import chakasu/encoderstream
 
+export isatty
+
 #TODO switch from termcap...
 
 type
@@ -40,6 +41,9 @@ type
     me # end all formatting modes
     LE # cursor left %1 characters
     RI # cursor right %1 characters
+    vs # enhance cursor
+    vi # make cursor invisible
+    ve # reset cursor to normal
 
   Termcap = ref object
     bp: array[1024, uint8]
@@ -85,14 +89,19 @@ when not termcap_found:
   # DEC reset
   template DECRST(s: varargs[string, `$`]): string =
     "\e[?" & s.join(';') & 'l'
-  template SMCUP(): string = DECSET(1049)
-  template RMCUP(): string = DECRST(1049)
+  const SMCUP = DECSET(1049)
+  const RMCUP = DECRST(1049)
+  const CNORM = DECSET(25)
+  const CIVIS = DECRST(25)
   template HVP(s: varargs[string, `$`]): string =
     CSI(s) & "f"
   template EL(): string =
     CSI() & "K"
   template ED(): string =
     CSI() & "J"
+
+  proc write(term: Terminal, s: string) =
+    term.outfile.write(s)
 else:
   func hascap(term: Terminal, c: TermcapCap): bool = term.tc.caps[c] != nil
   func cap(term: Terminal, c: TermcapCap): string = $term.tc.caps[c]
@@ -102,6 +111,12 @@ else:
   proc putc(c: char): cint {.cdecl.} =
     goutfile.write(c)
 
+  proc write(term: Terminal, s: cstring) =
+    discard tputs(s, 1, putc)
+
+  proc write(term: Terminal, s: string) =
+    term.write(cstring(s))
+
 template SGR*(s: varargs[string, `$`]): string =
   CSI(s) & "m"
 
@@ -116,12 +131,6 @@ const ANSIColorMap = [
   ColorsRGB["white"],
 ]
 
-proc write(term: Terminal, s: string) =
-  when termcap_found:
-    discard tputs(cstring(s), cint(s.len), putc)
-  else:
-    term.outfile.write(s)
-
 proc flush*(term: Terminal) =
   term.outfile.flushFile()
 
@@ -184,14 +193,14 @@ proc enableAltScreen(term: Terminal): string =
     if term.hascap ti:
       term.write($term.cap ti)
   else:
-    return SMCUP()
+    return SMCUP
 
 proc disableAltScreen(term: Terminal): string =
   when termcap_found:
     if term.hascap te:
       term.write($term.cap te)
   else:
-    return RMCUP()
+    return RMCUP
 
 func defaultBackground(term: Terminal): RGBColor =
   return term.config.display.default_background_color
@@ -444,10 +453,16 @@ proc generateSwapOutput(term: Terminal, grid, prev: FixedGrid): string =
         result &= term.clearEnd()
 
 proc hideCursor*(term: Terminal) =
-  term.outfile.hideCursor()
+  when termcap_found:
+    term.write(term.ccap vi)
+  else:
+    term.write(CIVIS)
 
 proc showCursor*(term: Terminal) =
-  term.outfile.showCursor()
+  when termcap_found:
+    term.write(term.ccap ve)
+  else:
+    term.write(CNORM)
 
 func emulateOverline(term: Terminal): bool =
   term.config.display.emulate_overline and
@@ -623,7 +638,8 @@ proc restart*(term: Terminal) =
   if term.smcup:
     term.write(term.enableAltScreen())
 
-proc newTerminal*(outfile: File, config: Config, attrs: WindowAttributes): Terminal =
+proc newTerminal*(outfile: File, config: Config, attrs: WindowAttributes):
+    Terminal =
   let term = Terminal(
     outfile: outfile,
     config: config
diff --git a/src/display/winattrs.nim b/src/display/winattrs.nim
index 3c453871..06666263 100644
--- a/src/display/winattrs.nim
+++ b/src/display/winattrs.nim
@@ -1,5 +1,3 @@
-import std/terminal
-
 when defined(posix):
   import std/termios
 
@@ -12,44 +10,42 @@ type
     width_px*: int
     height_px*: int
 
+proc isatty(fd: FileHandle): cint {.importc: "isatty", header: "<unistd.h>".}
+proc isatty*(f: File): bool =
+  return isatty(f.getFileHandle()) != 0
+
 proc getWindowAttributes*(tty: File): WindowAttributes =
-  when defined(posix):
-    if tty.isatty():
-      var win: IOctl_WinSize
-      if ioctl(cint(getOsFileHandle(tty)), TIOCGWINSZ, addr win) != -1:
-        var cols = int(win.ws_col)
-        var rows = int(win.ws_row)
-        if cols == 0:
-          cols = 80
-        if rows == 0:
-          rows = 24
-        var ppc = int(win.ws_xpixel) div cols
-        var ppl = int(win.ws_ypixel) div rows
-        # some terminal emulators (aka vte) don't set ws_xpixel or ws_ypixel.
-        # solution: use xterm.
-        if ppc == 0:
-          ppc = 9
-        if ppl == 0:
-          ppl = 18
-        # Filling the last row without raw mode breaks things. However,
-        # not supporting Windows means we can always have raw mode, so we can
-        # use all available columns.
-        return WindowAttributes(
-          width: cols,
-          height: rows,
-          ppc: ppc,
-          ppl: ppl,
-          width_px: cols * ppc,
-          height_px: rows * ppl
-        )
-  # For Windows, which is no longer supported. We keep it as a fallback for
-  # when ioctl fails.
-  var height = terminalHeight()
-  if height == 0:
-    height = 24
-  # Windows has no raw mode afaik, so we do not fill the last column to
-  # prevent line wrapping.
-  let width = terminalWidth() - 1
+  if tty.isatty():
+    var win: IOctl_WinSize
+    if ioctl(cint(getOsFileHandle(tty)), TIOCGWINSZ, addr win) != -1:
+      var cols = int(win.ws_col)
+      var rows = int(win.ws_row)
+      if cols == 0:
+        cols = 80
+      if rows == 0:
+        rows = 24
+      var ppc = int(win.ws_xpixel) div cols
+      var ppl = int(win.ws_ypixel) div rows
+      # some terminal emulators (aka vte) don't set ws_xpixel or ws_ypixel.
+      # solution: use xterm.
+      if ppc == 0:
+        ppc = 9
+      if ppl == 0:
+        ppl = 18
+      # Filling the last row without raw mode breaks things. However,
+      # not supporting Windows means we can always have raw mode, so we can
+      # use all available columns.
+      return WindowAttributes(
+        width: cols,
+        height: rows,
+        ppc: ppc,
+        ppl: ppl,
+        width_px: cols * ppc,
+        height_px: rows * ppl
+      )
+  # Fallback for ioctl failure
+  let height = 24
+  let width = 80
   let ppc = 9
   let ppl = 18
   return WindowAttributes(