98 lines
4.0 KiB
Plaintext
98 lines
4.0 KiB
Plaintext
// External programs can load Lib.kiss with (loadFrom "nat-archive-tool" "src/nat/Lib.kiss")
|
|
(load "Lib.kiss")
|
|
|
|
(let [[archiveDir] (Sys.args)
|
|
controller
|
|
(new ArchiveController
|
|
(new Archive archiveDir)
|
|
(new CLI))]
|
|
(loop
|
|
(Sys.print ">> ")
|
|
(let [command
|
|
(.trim (.toString (.readLine (Sys.stdin))))]
|
|
(controller.tryRunCommand command))))
|
|
|
|
(prop &mut :ArchiveController controller)
|
|
(prop :kiss_tools.KeyShortcutHandler<Entry> shortcutHandler null)
|
|
|
|
(defNew [])
|
|
|
|
(method :Void enterText [prompt :String->Void resolve maxLength]
|
|
(Sys.print "$prompt ")
|
|
(loop
|
|
(let [entered (.toString (.readLine (Sys.stdin)))]
|
|
(if !(<= entered.length maxLength)
|
|
(Sys.print "Try again? ")
|
|
{(resolve entered)
|
|
(break)}))))
|
|
|
|
(method :Void enterNumber [prompt :Float->Void resolve min max &opt inStepsOf]
|
|
(Sys.print "$prompt ")
|
|
(loop
|
|
(let [entered (Std.parseFloat (.toString (.readLine (Sys.stdin))))]
|
|
(if
|
|
(or
|
|
!(<= min entered max)
|
|
(and inStepsOf !(= 0 (% (- entered min) inStepsOf))))
|
|
(Sys.print "Try again? ")
|
|
{(resolve entered)
|
|
(break)}))))
|
|
|
|
(method :Void chooseEntry [prompt :Archive archive :Entry->Void resolve]
|
|
(_chooseEntry prompt archive resolve ->(chooseEntry "empty name doesn't match any entries. Try again?" archive resolve)))
|
|
|
|
(method :Void _chooseEntry [prompt :Archive archive :Entry->Void resolve :Void->Void onEmptyString]
|
|
// TODO allow narrowing down with a tag string
|
|
(enterText "entry name for $prompt"
|
|
->:Void name {
|
|
(if !name
|
|
(onEmptyString)
|
|
(let [matchingEntries (controller.nameSystem.getEntries name)]
|
|
(case (the Array<Entry> matchingEntries)
|
|
([e] (resolve e))
|
|
([] (chooseEntry "name $name doesn't match any entries. Try again?" archive resolve))
|
|
// TODO disambiguate entries with the same names by listing stringified versions of them and using enterNumber
|
|
(multipleEntries (throw "ambiguous between multiple entries"))
|
|
(otherwise))))}
|
|
Math.POSITIVE_INFINITY))
|
|
|
|
(method :Void chooseEntries [prompt archive :Array<nat.Entry>->Void resolve min max]
|
|
(_chooseEntries prompt archive resolve min max []))
|
|
|
|
(method :Void _chooseEntries [prompt archive :Array<nat.Entry>->Void resolve min max :Array<Entry> collectedEntries]
|
|
(let [onEmptyString
|
|
->:Void (if (<= min collectedEntries.length)
|
|
(resolve collectedEntries)
|
|
(throw "not enough entries chosen"))
|
|
&mut :Void->Void chooseNextEntry
|
|
null
|
|
_chooseNextEntry
|
|
->:Void {(_chooseEntry
|
|
prompt
|
|
archive
|
|
->:Void e {(collectedEntries.push e)
|
|
// If the maximum is reached, return it
|
|
(if (= max collectedEntries.length)
|
|
(resolve collectedEntries)
|
|
// Otherwise, recurse
|
|
(chooseNextEntry))}
|
|
onEmptyString)}]
|
|
(set chooseNextEntry _chooseNextEntry)
|
|
(_chooseNextEntry)))
|
|
|
|
|
|
(method handleChanges [:Archive archive :ChangeSet changeSet]
|
|
(archive.processSystems this)
|
|
(doFor e changeSet
|
|
(print (archive.fullString e))))
|
|
|
|
(method :Void displayMessage [message]
|
|
(print message))
|
|
|
|
(method :Void reportError [error]
|
|
(print error))
|
|
|
|
(method :Void onSelectionChanged [:Array<Entry> selectedEntries :Array<Entry> _]
|
|
(print "Selected:")
|
|
(controller.PrintSelectedEntries selectedEntries))
|