askpass
askpass copied to clipboard
optionalize use of stty
TL;DR:
Please make the call of stty echo
optional, perhaps based on a getOption(..)
.
I use ssh/tmux to get to a headless system where I run R within emacs/ESS. For some things, I find it convenient to use the keyring
package to store some credentials/secrets, and its default behavior in this scenario is to use its backend_file
. When I need to access a secret, the first time I call keyring::key_get(...)
it internally calls askpass::askpass(..)
. This correctly retrieves my typed-in password for the file-store.
However, the default action of askpass()
is to close out by calling system('stty echo')
which is mildly disruptive in emacs/ESS. (This does the same thing in my local, gui-based emacs, but since it's not headless, I'm able to use gnome's secret service which is not file-based so it does not prompt me for a password.)
This is how it looks. If you are not familiar with emacs/ESS, it normally does not echo every command, instead this is how it "should" look:
> paste("hello", "world")
[1] "hello world"
> pi*2
[1] 6.283185
If I use askpass::askpass
(which, again, is used by keyring::key_get(..)
), from then on it duplicates all text:
> askpass::askpass("hello")
hello
🔑 somesecret
OK
[1] "somesecret"
> paste("hello", "world")
paste("hello", "world")
[1] "hello world"
> pi*2
pi*2
[1] 6.283185
Resolving it is easy enough:
> system("stty -echo")
system("stty -echo")
> pi*2
[1] 6.283185
But it would be incredibly helpful if I didn't have to do that step.. While the use of system('stty echo')
is likely good in most situations, it is not right for emacs/ess, we do not need the stty to echo all commands.
Since it is likely that askpass::askpass(.)
is more often called from within another package, I don't know that "just" a formal argument would suffice; for it to be usable in my situations, it would need to be in an envvar or as an option. For instance, perhaps
readline_silent <- function(prompt, icon = "\U0001f511 ", restore_stty = getOption("askpass_restore_stty", TRUE)) {
if(is_unix() && isatty(stdin())){
if(system('stty -echo') == 0){
if (!isFALSE(restore_stty)) on.exit(system('stty echo'))
}
}
cat(prompt, "\n")
out <- base::readline(icon)
cat(" OK\n")
out
}
My use of !isFALSE
is purely intended to safely default to the current behavior, resilient to most "oopses". I'm not dead-set on that technique, just the notion of using an R option to better inform that step.
Thoughts?