68 lines
1.8 KiB
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()
|
|
|