Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better user input helper #930

Merged
merged 3 commits into from
Aug 28, 2015
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 38 additions & 13 deletions src/app/FakeLib/UserInputHelper.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,55 @@ module Fake.UserInputHelper

open System

let internal erasePreviousChar () =
try
let left = if Console.CursorLeft <> 0 then Console.CursorLeft-1 else Console.BufferWidth-1
let top = if Console.CursorLeft <> 0 then Console.CursorTop else Console.CursorTop-1

Console.SetCursorPosition(left, top)
Console.Write(' ')
Console.SetCursorPosition(left, top)
with
| :? IO.IOException ->
// Console is dumb, might be redirected. We don't care,
// if it isn't a screen the visual feedback isn't required
()

let internal readString (echo: bool) : string =
let rec loop cs =
let key = Console.ReadKey(not echo)
match key.Key with
| ConsoleKey.Backspace -> match cs with
| [] -> loop []
| _::cs -> loop cs
| ConsoleKey.Enter -> cs
| _ -> loop (key.KeyChar :: cs)

let key = Console.ReadKey(true)
match (key.Key, cs) with
| (ConsoleKey.Backspace, []) -> loop []
| (ConsoleKey.Backspace, _::cs) ->
erasePreviousChar ()
loop cs
| (ConsoleKey.Enter, _) -> cs
| _ ->
if echo then Console.Write(key.KeyChar) else Console.Write('*')
loop (key.KeyChar :: cs)

loop []
|> List.rev
|> Array.ofList
|> fun cs -> new String(cs)

let internal color (color: ConsoleColor) (code : unit -> _) =
let before = Console.ForegroundColor
Console.ForegroundColor <- color
let result = code ()
Console.ForegroundColor <- before
result

/// Return a string entered by the user followed by enter. The input is echoed to the screen.
let getUserInput prompt =
printf "%s" prompt
readString true
color ConsoleColor.White (fun _ -> printf "%s" prompt)
let s = readString true
printfn ""
s

/// Return a string entered by the user followed by enter. The input is not echoed to the screen.
/// Return a string entered by the user followed by enter. The input is replaced by '*' on the screen.
let getUserPassword prompt =
printf "%s" prompt
color ConsoleColor.White (fun _ -> printf "%s" prompt)
let s = readString false
printfn ""
s