diff --git a/src/app/FakeLib/UserInputHelper.fs b/src/app/FakeLib/UserInputHelper.fs index 078865c7f15..235c4388dc5 100644 --- a/src/app/FakeLib/UserInputHelper.fs +++ b/src/app/FakeLib/UserInputHelper.fs @@ -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 -