CLI chooseEntries

This commit is contained in:
2021-06-27 19:00:35 -06:00
parent 49bbbe6599
commit 39e0f51856
3 changed files with 45 additions and 15 deletions

View File

@@ -83,7 +83,7 @@
&mut lastCollector
(lambda []
(set lastChangeSet (the ChangeSet (Reflect.callMethod null command.handler collectedArgs)))
(ui.handleChanges lastChangeSet))]
(ui.handleChanges archive lastChangeSet))]
// To facilitate asynchronous arg input via UI, we need to construct an insanely complicated nested callback to give the UI
(doFor arg (reversed command.args)
(set lastCollector (_composeArgCollector collectedArgs arg lastCollector)))

View File

@@ -26,7 +26,7 @@ interface ArchiveUI {
/**
* Update the interface to reflect changes made to Entries through commands
*/
function handleChanges(changeSet:ChangeSet):Void;
function handleChanges(archive:Archive, changeSet:ChangeSet):Void;
/**
* Tell the user something useful

View File

@@ -38,28 +38,58 @@
(break)}))))
(defmethod :Void chooseEntry [prompt :Archive archive resolve]
(_chooseEntry prompt archive resolve ->(chooseEntry "empty name doesn't match any entries. Try again?" archive resolve)))
(defmethod :Void _chooseEntry [prompt :Archive archive resolve onEmptyString]
// TODO allow narrowing down with a tag string
(enterText "entry name for $prompt"
->name {
(let [matchingEntries []]
(.process (archive.addSystem
(stringComponentSystem archive Name name
(lambda [archive e]
(matchingEntries.push e)))) archive)
(if !name
(onEmptyString)
(let [matchingEntries []]
(.process (archive.addSystem
(stringComponentSystem archive Name name
(lambda [archive e]
(matchingEntries.push e)))) archive)
(case (the Array<Entry> matchingEntries)
([e] (resolve e))
([] (throw "name $name doesn't match any entries"))
// TODO disambiguate entries with the same names by listing stringified versions of them and using enterNumber
(multipleEntries (throw "ambiguous between multiple entries"))))}
(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")))))}
0 Math.POSITIVE_INFINITY))
(defmethod :Void chooseEntries [prompt archive resolve min max]
(resolve []))
(_chooseEntries prompt archive resolve min max []))
(defmethod handleChanges [changeSet])
(defmethod :Void _chooseEntries [prompt archive resolve min max :Array<Entry> collectedEntries]
(let [onEmptyString
->(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)))
(defmethod handleChanges [:Archive archive :ChangeSet changeSet]
(doFor e changeSet
(print (archive.fullString e))))
(defmethod :Void displayMessage [message]
(print message))
(defmethod :Void reportError [error] ~error)
(defmethod :Void reportError [error]
(print error))