diff --git a/projects/nat-archive-tool/src/nat/ArchiveController.kiss b/projects/nat-archive-tool/src/nat/ArchiveController.kiss index 439dbcb5..2691f8a7 100644 --- a/projects/nat-archive-tool/src/nat/ArchiveController.kiss +++ b/projects/nat-archive-tool/src/nat/ArchiveController.kiss @@ -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))) diff --git a/projects/nat-archive-tool/src/nat/ArchiveUI.hx b/projects/nat-archive-tool/src/nat/ArchiveUI.hx index ed9a3349..98cbd5d3 100644 --- a/projects/nat-archive-tool/src/nat/ArchiveUI.hx +++ b/projects/nat-archive-tool/src/nat/ArchiveUI.hx @@ -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 diff --git a/projects/nat-archive-tool/src/nat/CLI.kiss b/projects/nat-archive-tool/src/nat/CLI.kiss index f9351e77..e128691f 100644 --- a/projects/nat-archive-tool/src/nat/CLI.kiss +++ b/projects/nat-archive-tool/src/nat/CLI.kiss @@ -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 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 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 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) \ No newline at end of file +(defmethod :Void reportError [error] + (print error)) \ No newline at end of file