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