jal3/renderer.nim

68 lines
1.8 KiB
Nim

# takes a text buffer and a terminal buffer (terminalUtils/buffer)
# when render() is called, rewrites the terminal buffer completely as a function of
# of the text buffer
import strutils
import textBuffer
import terminalUtils/buffer
import terminalUtils/terminalGetInfo
type Scroll* = ref object
x, y: int
proc render*(textBuffer: TextBuffer, termBuffer: Buffer, prompt: string, scroll: Scroll) =
# we are free to "redraw" everything everytime
# since termBuffer double buffers
# resizing the buffer if needed
let lineCount = textBuffer.getLineCount()
let termWidth = termGetWidth()
let termHeight = termGetHeight()
let (bufWidth, bufHeight) = termBuffer.getSize()
if bufWidth != termWidth or bufHeight != min(lineCount, termHeight):
termBuffer.resize(termWidth, min(lineCount, termHeight))
termBuffer.clear()
let (x, y) = textBuffer.getCursorPos()
let lines = textBuffer.lines()
let promptLen = prompt.len()
let maxTextLen = termWidth - promptLen
if maxTextLen < 1:
termBuffer.redraw()
return # nothing will fit anyways
for i in 0..lines.high():
let line = lines[i]
if i == 0:
termBuffer.write(prompt)
else:
termBuffer.write(" ".repeat(promptLen))
let lineLen = line.len()
if lineLen < maxTextLen - 1:
scroll.x = 0
termBuffer.write(line)
else:
const scrollOffset = 2
# horizontal scroll
# right scroll
if x - scroll.x >= maxTextLen - scrollOffset:
scroll.x = x - maxTextLen + scrollOffset
# left scroll
if x - scroll.x < 0:
scroll.x = x
# left scroll
# keep what's in range
let fromPos = scroll.x
let toPos = min(scroll.x+maxTextLen-2, line.high())
termBuffer.write(line[fromPos..toPos])
termBuffer.newLine()
termBuffer.setCursorPos(x + promptLen - scroll.x, y - scroll.y)
termBuffer.redraw()