Skip to content

Instantly share code, notes, and snippets.

@Vindaar
Last active February 23, 2018 22:08
Show Gist options
  • Save Vindaar/f5cb17a6c47f6d4cdf3a4995ce2bf3ae to your computer and use it in GitHub Desktop.
Save Vindaar/f5cb17a6c47f6d4cdf3a4995ce2bf3ae to your computer and use it in GitHub Desktop.
import terminal
proc restoreOnInterrupt() {.noconv.} =
## called in `getPassword` if readLine is interrupted by SIGINT to remove the
## typed characters and restore the terminal to default settings.
# erase line, to remove the password
eraseLine()
# restore default terminal settings
showCursor()
resetAttributes()
echo()
if stackTraceAvailable() == true:
writeStackTrace()
quit("SIGINT: Interrupted by Ctrl-C")
proc getPassword(prompt = ""): string =
## Reads a password from stdin without showing any characters. Provides
## handling of backspaces and unicode. Characters are inserted as hidden text,
## which is removed after user input is done or on SIGINT. `prompt` allows
## for a custom password prompt.
# write prompt without newline character
stdout.write(prompt)
# set style to hidden and hide cursor
setStyle({styleHidden})
hideCursor()
# set hook to clear password if Ctrl-C called
setControlCHook(restoreOnInterrupt)
result = stdin.readLine()
unsetControlCHook()
# readline put us 1 line down
cursorUp()
# erase line, to remove the password
eraseLine()
# restore default terminal settings
showCursor()
resetAttributes()
# rewrite the prompt to make it look like it was there all along
echo prompt
when isMainModule:
let password = getPassword("Enter password: ")
echo password.repr
echo "Entered password was ", password
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment