This commit is contained in:
Productive2 2021-02-15 20:59:40 +01:00
parent 2358434bae
commit e48cae8774
4 changed files with 49 additions and 57 deletions

View File

@ -31,15 +31,15 @@ proc defControl(editor: LineEditor) =
editor.content.delete() editor.content.delete()
check("enter"): check("enter"):
if editor.content.Y() == editor.content.high() and editor.content.getLine(editor.content.high()) == "": if editor.content.Y() == editor.content.high() and editor.content.getLine(editor.content.high()) == "":
editor.finished = true editor.finish()
else: else:
editor.content.insertline() editor.content.insertline()
check("ctrl+c"): check("ctrl+c"):
editor.finished = true editor.finish()
editor.events.call(jeQuit) editor.events.call(jeQuit)
check("ctrl+d"): check("ctrl+d"):
if editor.content.getContent() == "": if editor.content.getContent() == "":
editor.finished = true editor.finish()
editor.events.call(jeQuit) editor.events.call(jeQuit)
proc defLog(editor: LineEditor) = proc defLog(editor: LineEditor) =

View File

@ -11,7 +11,7 @@ import renderer
type type
JaleEvent* = enum JaleEvent* = enum
jeKeypress, jeQuit jeKeypress, jeQuit, jeFinish
LineEditor* = ref object LineEditor* = ref object
content*: Multiline content*: Multiline
@ -21,9 +21,21 @@ type
events*: Event[JaleEvent] events*: Event[JaleEvent]
prompt*: string prompt*: string
lastKeystroke*: int lastKeystroke*: int
finished*: bool finished: bool
rendered: int # how many lines were printed last full refresh rendered: int # how many lines were printed last full refresh
# getter/setter sorts
proc unfinish*(le: LineEditor) =
le.finished = false
proc finish*(le: LineEditor) =
le.finished = true
# can be overwritten to false, inside the event
le.events.call(jeFinish)
# constructor
proc newLineEditor*: LineEditor = proc newLineEditor*: LineEditor =
new(result) new(result)
result.content = newMultiline() result.content = newMultiline()
@ -35,6 +47,12 @@ proc newLineEditor*: LineEditor =
result.prompt = "" result.prompt = ""
result.rendered = 0 result.rendered = 0
# priv/pub methods
proc reset(editor: LineEditor) =
editor.unfinish()
editor.rendered = 0
proc render(editor: LineEditor, line: int = -1, hscroll: bool = true) = proc render(editor: LineEditor, line: int = -1, hscroll: bool = true) =
var y = line var y = line
if y == -1: if y == -1:
@ -53,63 +71,50 @@ proc render(editor: LineEditor, line: int = -1, hscroll: bool = true) =
proc fullRender(editor: LineEditor) = proc fullRender(editor: LineEditor) =
# from the current (proper) cursor pos, it draws the entire multiline prompt, then # from the top cursor pos, it draws the entire multiline prompt, then
# moves cursor to current x,y # moves cursor to current y
for i in countup(0, editor.content.high()): for i in countup(0, editor.content.high()):
editor.render(i, false) editor.render(i, false)
# if i <= editor.rendered: if i < editor.rendered:
cursorDown(1) cursorDown(1)
# else: else:
# write stdout, "\n" write stdout, "\n"
# inc editor.rendered inc editor.rendered
cursorUp(editor.content.len() - editor.content.Y)
proc restore(editor: LineEditor) =
# from the line that's represented as y=0 it moves the cursor to editor.y
# if it's at the bottom, it also scrolls enough
# it's achieved by the right number of newlines
# does not restore editor.x
write stdout, "\n".repeat(editor.content.len())
cursorUp(editor.content.len())
editor.rendered = editor.content.len()
if editor.content.Y == 0:
return
cursorDown(editor.content.Y)
proc moveCursorToEnd(editor: LineEditor) = proc moveCursorToEnd(editor: LineEditor) =
# only called when read finished # only called when read finished
cursorDown(editor.content.high() - editor.content.Y) if editor.content.high() > editor.content.Y:
cursorDown(editor.content.high() - editor.content.Y)
write stdout, "\n" write stdout, "\n"
proc moveCursorToStart(editor: LineEditor, delta: int = 0) =
if delta > 0:
cursorUp(delta)
proc restoreCursor(editor: LineEditor) =
if editor.content.Y > 0:
cursorDown(editor.content.Y)
proc read*(editor: LineEditor): string = proc read*(editor: LineEditor): string =
# write stdout, "\n" # starts at the top, full render moves it into the right y
editor.restore()
editor.fullRender() editor.fullRender()
editor.restoreCursor()
while not editor.finished: while not editor.finished:
# refresh current line every time
editor.render() editor.render()
setCursorXPos(editor.content.X + editor.prompt.len()) setCursorXPos(editor.content.X + editor.prompt.len())
# get key (with escapes)
let key = getKey() let key = getKey()
# record y pos
let preY = editor.content.Y let preY = editor.content.Y
# call the events
editor.lastKeystroke = key editor.lastKeystroke = key
editor.keystrokes.call(key) editor.keystrokes.call(key)
editor.events.call(jeKeypress) editor.events.call(jeKeypress)
# redraw everything if y changed
if preY != editor.content.Y: if preY != editor.content.Y:
# redraw everything because y changed # move to the top
editor.moveCursorToStart(preY) if preY > 0:
cursorUp(preY)
# move to the right y
editor.fullRender() editor.fullRender()
editor.restoreCursor()
editor.finished = false # move cursor to end
editor.moveCursorToEnd() editor.moveCursorToEnd()
editor.reset()
return editor.content.getContent() return editor.content.getContent()

View File

@ -1,10 +1,7 @@
import defaults import defaults
import tables
import editor import editor
import strutils import strutils
import templates import templates
import multiline
import event
var keep = true var keep = true
@ -13,20 +10,9 @@ let e = newLineEditor()
e.bindEvent(jeQuit): e.bindEvent(jeQuit):
keep = false keep = false
e.bindKey('a'):
echo "a has been pressed"
e.bindKey("ctrl+b"):
echo "ctrl+b has been pressed"
e.prompt = "> " e.prompt = "> "
e.populateDefaults() e.populateDefaults()
while keep: while keep:
let input = e.read() let input = e.read()
if input.contains("quit"): echo "output:<" & input.replace("\n", "\\n") & ">"
break
else:
echo "==="
echo input
echo "==="

View File

@ -1,6 +1,7 @@
import editor import editor
import event import event
import keycodes import keycodes
import tables
template bindKey*(editor: LineEditor, key: int, body: untyped) = template bindKey*(editor: LineEditor, key: int, body: untyped) =
proc action {.gensym.} = proc action {.gensym.} =