-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
For now, only contains a `yes_no_prompt` function.
- Loading branch information
1 parent
763f1ef
commit ea2c9c1
Showing
3 changed files
with
166 additions
and
0 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
---@brief | ||
--- Module for handling when input from the user is needed | ||
|
||
local log <const> = require("cyan.log") | ||
local cs <const> = require("cyan.colorstring") | ||
local ansi <const> = require("cyan.ansi") | ||
|
||
local interaction <const> = {} | ||
|
||
local affirmative <const> = { ansi.color.dark.green } | ||
local negative <const> = { ansi.color.dark.red } | ||
|
||
local yesses <const> = { "yes", "yeah", "yea", "ye", "y" } | ||
local nos <const> = { "no", "nope", "n" } | ||
|
||
local function title_case(s: string): string | ||
return s:sub(1, 1):upper() .. s:sub(2, -1):lower() | ||
end | ||
|
||
local function to_string_set(list: {string}): {string:boolean} | ||
local result <const> = {} | ||
for _, v in ipairs(list) do | ||
result[v:lower()] = true | ||
end | ||
return result | ||
end | ||
|
||
---@desc | ||
--- Ask the user to affirm or deny a given prompt. The user input will be | ||
--- compared against the given `affirm` and `deny` lists (case-insensitive), with | ||
--- defaults used if - they are not provided. | ||
--- | ||
--- The given logger will be used to print the prompt, and `log.info` if none | ||
--- is provided. | ||
function interaction.yes_no_prompt( | ||
prompt: string, | ||
logger: log.Logger, | ||
default: boolean, | ||
affirm: {string}, | ||
deny: {string} | ||
): boolean | ||
logger = logger or log.info | ||
affirm = affirm or yesses | ||
deny = deny or nos | ||
|
||
local y <const> = cs.highlight( | ||
affirmative, | ||
default and title_case(affirm[1]) or affirm[1]:lower() | ||
) | ||
local n <const> = cs.highlight( | ||
negative, | ||
default and deny[1]:lower() or title_case(deny[1]) | ||
) | ||
local prompt_str <const> = prompt .. " [" .. y .. "/" .. n .. "]: " | ||
|
||
local affirm_set <const> = to_string_set(affirm) | ||
local deny_set <const> = to_string_set(deny) | ||
|
||
while true do | ||
logger:nonl(prompt_str) | ||
logger.stream:flush() | ||
local input = io.read("*l"):lower() | ||
|
||
if #input == 0 then | ||
logger:cont( | ||
"Defaulting to ", | ||
default | ||
and cs.highlight(affirmative, title_case(affirm[1])) | ||
or cs.highlight(negative, title_case(deny[1])) | ||
) | ||
return default or false | ||
end | ||
|
||
if affirm_set[input] then | ||
return true | ||
elseif deny_set[input] then | ||
return false | ||
end | ||
end | ||
end | ||
|
||
return interaction |