Skip to content

Commit e38f9da

Browse files
committed
feat(karaxpython/ui): history (bug: cursor not to end on restoring)
1 parent 7c15c29 commit e38f9da

File tree

1 file changed

+48
-2
lines changed

1 file changed

+48
-2
lines changed

Python/karaxpython.nim

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ proc interactivePython(input: string): bool {. exportc, discardable .} =
2424
let info = getVersionString(verbose=true)
2525
const gitRepoUrl{.strdefine.} = ""
2626
const repoInfoPre = "This website is frontend-only. Open-Source at "
27+
2728
include karax/prelude
2829
import karax/kdom
2930
import karax/vstyles
@@ -56,10 +57,49 @@ template oneReplLineNode(editNodeClasses;
5657
const historyContainerId = "history-container"
5758
var historyNode: Node
5859

60+
# === history input track ===
61+
type HistoryTrackPos = object
62+
offset: Natural ## neg order
63+
64+
proc reset(self: var HistoryTrackPos) = self.offset = 0
65+
66+
proc stepToPastImpl(self: var HistoryTrackPos) =
67+
let hi = stream.high
68+
self.offset =
69+
if self.offset == hi: hi
70+
else: self.offset + 1
71+
proc stepToNowImpl(self: var HistoryTrackPos) =
72+
self.offset =
73+
if self.offset == 0: 0
74+
else: self.offset - 1
75+
76+
template getHistoryRecord(self: HistoryTrackPos): untyped =
77+
stream[stream.high - self.offset]
78+
79+
template genStep(pastOrNext){.dirty.} =
80+
proc `stepTo pastOrNext`*(self: var HistoryTrackPos, n: var Node) =
81+
self.`stepTo pastOrNext Impl`
82+
var tup: tuple[prompt, info: kstring]
83+
84+
tup = self.getHistoryRecord
85+
if tup.prompt == "": # is output over input
86+
# skip this one
87+
self.`stepTo pastOrNext Impl`
88+
tup = self.getHistoryRecord
89+
90+
n.innerHtml = tup.info
91+
92+
genStep Past
93+
genStep Now
94+
95+
var historyInputPos: HistoryTrackPos
96+
5997
# TODO: arrow-up / arrow-down for history
6098
proc pushHistory(prompt: kstring, exp: string) =
6199
stream.add (prompt, kstring exp)
62100

101+
historyInputPos.reset
102+
63103
# auto scroll down when the inputing line is to go down the view
64104
let last = historyNode.lastChild
65105
if last.isNil: return
@@ -104,12 +144,18 @@ proc createDom(): VNode =
104144
,
105145
block:
106146
proc onKeydown(ev: Event, n: VNode) =
107-
if KeyboardEvent(ev).keyCode == 13:
147+
case KeyboardEvent(ev).key # .keyCode is deprecated
148+
of "Enter":
108149
var input = $n.dom.textContent
109150
pushHistory(prompt, input)
110151
interactivePython(input)
111152
n.dom.innerHTML = kstring""
112-
ev.preventDefault
153+
of "ArrowUp":
154+
historyInputPos.stepToPast n.dom
155+
of "ArrowDown":
156+
historyInputPos.stepToNow n.dom
157+
else: return
158+
ev.preventDefault
113159
)
114160

115161
setRenderer createDom, clientPostRenderCallback=postRenderCallback

0 commit comments

Comments
 (0)