work on resizing
This commit is contained in:
parent
e49d4799f3
commit
7173aada85
47
editor.nim
47
editor.nim
|
@ -17,20 +17,40 @@ type
|
|||
termBuffer: Buffer
|
||||
history: seq[TextBuffer] # past texts
|
||||
historyIndex: int # where are we in history
|
||||
scroll: Scroll
|
||||
active: bool
|
||||
|
||||
# screen properties passed to renderer
|
||||
width, height: int
|
||||
cursorY: int
|
||||
|
||||
EditorResult* = enum
|
||||
erEnter, erCtrlC, erCtrlD, erError
|
||||
erError, erEnter, erCtrlC, erCtrlD
|
||||
|
||||
# for editors
|
||||
var editors: seq[EditorState]
|
||||
|
||||
proc redraw*(ed: EditorState): int =
|
||||
render(ed.textBuffer, ed.termBuffer, ed.prompt, ed.scroll, ed.width, ed.height, ed.cursorY)
|
||||
|
||||
# resize support
|
||||
onSignal(28):
|
||||
discard
|
||||
let nh = termGetHeight()
|
||||
let nw = termGetWidth()
|
||||
for ed in editors:
|
||||
ed.width = nw
|
||||
ed.height = nh
|
||||
if ed.active:
|
||||
discard ed.redraw()
|
||||
|
||||
proc newEditor*(prompt: string = "> "): EditorState =
|
||||
new(result)
|
||||
let (_, cursorY) = termGetCursorPos(stdout)
|
||||
result.cursorY = cursorY
|
||||
result.width = termGetWidth()
|
||||
result.height = termGetHeight()
|
||||
result.prompt = prompt
|
||||
result.active = false
|
||||
editors.add(result)
|
||||
|
||||
proc destroyEditor*(oldEditor: EditorState) =
|
||||
|
@ -43,23 +63,23 @@ proc destroyEditor*(oldEditor: EditorState) =
|
|||
proc read*(ed: EditorState): (EditorResult, string) =
|
||||
|
||||
var editorResult = erError
|
||||
let (_, cursorY) = termGetCursorPos(stdout)
|
||||
ed.termBuffer = newBuffer(0, cursorY, termGetWidth(), 1, stdout)
|
||||
ed.termBuffer = newBuffer(0, ed.cursorY, termGetWidth(), 1, stdout)
|
||||
ed.textBuffer = newTextBuffer()
|
||||
ed.history.add(ed.textBuffer)
|
||||
ed.historyIndex = ed.history.high()
|
||||
|
||||
var scroll: Scroll = new(Scroll)
|
||||
ed.scroll = new(Scroll)
|
||||
ed.active = true
|
||||
var lastRenderLines = 0
|
||||
|
||||
template moveInHistory(delta: int) =
|
||||
let newHistoryIndex = min(max(ed.historyIndex + delta, 0), ed.history.high())
|
||||
if newHistoryIndex != ed.historyIndex:
|
||||
ed.textBuffer = ed.history[newHistoryIndex]
|
||||
scroll.reset()
|
||||
ed.scroll.reset()
|
||||
ed.historyIndex = newHistoryIndex
|
||||
|
||||
while true:
|
||||
render(ed.textBuffer, ed.termBuffer, ed.prompt, scroll)
|
||||
lastRenderLines = ed.redraw()
|
||||
let (getKeyResult, key) = getKey()
|
||||
case getKeyResult:
|
||||
of gkChar:
|
||||
|
@ -114,14 +134,23 @@ proc read*(ed: EditorState): (EditorResult, string) =
|
|||
else:
|
||||
discard # not implemented
|
||||
|
||||
# stop redraws on resize
|
||||
ed.active = false
|
||||
|
||||
# return val, strip final newline (due to how double enter is how you enter)
|
||||
let cont = ed.textBuffer.getContent()
|
||||
if editorResult == erError:
|
||||
raise newException(Defect, "Editor loop quit without setting editor result.")
|
||||
result = (editorResult, cont)
|
||||
|
||||
# cleanup
|
||||
stdout.write("\n")
|
||||
ed.cursorY = min(ed.height-1, ed.cursorY + lastRenderLines)
|
||||
|
||||
# don't add empty lines to history
|
||||
if ed.history[ed.history.high()].getContent() == "":
|
||||
ed.history.del(ed.history.high())
|
||||
|
||||
|
||||
proc updateCursorPos*(ed: EditorState) =
|
||||
let (_, cursorY) = termGetCursorPos(stdout)
|
||||
ed.cursorY = cursorY
|
||||
|
|
|
@ -10,6 +10,10 @@ while true:
|
|||
elif text == "clear":
|
||||
eraseScreen()
|
||||
setCursorPos(0, 0)
|
||||
e.updateCursorPos()
|
||||
continue
|
||||
if text.len() > 0:
|
||||
echo text
|
||||
echo text
|
||||
e.updateCursorPos()
|
||||
|
||||
e.destroyEditor()
|
11
renderer.nim
11
renderer.nim
|
@ -15,16 +15,19 @@ proc reset*(scroll: Scroll) =
|
|||
scroll.x = 0
|
||||
scroll.y = 0
|
||||
|
||||
proc render*(textBuffer: TextBuffer, termBuffer: Buffer, prompt: string, scroll: Scroll) =
|
||||
proc render*(textBuffer: TextBuffer, termBuffer: Buffer, prompt: string, scroll: Scroll, width, height: int, edCursorY: int): int =
|
||||
# we are free to "redraw" everything everytime
|
||||
# since termBuffer double buffers
|
||||
# returns how many lines were drawn
|
||||
|
||||
# GET INFO
|
||||
let (x, y) = textBuffer.getCursorPos()
|
||||
let lines = textBuffer.lines()
|
||||
let lineCount = lines.len()
|
||||
let termWidth = termGetWidth()
|
||||
let termHeight = termGetHeight()
|
||||
#let termWidth = termGetWidth()
|
||||
let termWidth = width
|
||||
#let termHeight = termGetHeight()
|
||||
let termHeight = height
|
||||
let promptLen = prompt.len()
|
||||
let maxTextLen = termWidth - promptLen
|
||||
|
||||
|
@ -101,3 +104,5 @@ proc render*(textBuffer: TextBuffer, termBuffer: Buffer, prompt: string, scroll:
|
|||
termBuffer.setCursorPos(x + promptLen - scroll.x, y - scroll.y)
|
||||
termBuffer.redraw()
|
||||
|
||||
return termBuffer.getHeight()
|
||||
|
||||
|
|
|
@ -158,6 +158,9 @@ proc redraw*(buf: Buffer, force: bool = false) =
|
|||
func getSize*(buf: Buffer): (int, int) =
|
||||
(buf.width, buf.height)
|
||||
|
||||
func getHeight*(buf: Buffer): int =
|
||||
buf.height
|
||||
|
||||
proc resize*(buf: Buffer, newWidth, newHeight: int, terminalWidth, terminalHeight: int) =
|
||||
|
||||
# assert sizes
|
||||
|
|
Loading…
Reference in New Issue