=== modified file 'lisp/subr.el' --- lisp/subr.el 2014-06-28 17:27:29 +0000 +++ lisp/subr.el 2014-07-10 13:53:13 +0000 @@ -2058,7 +2058,7 @@ (let ((enable-recursive-minibuffers t)) (read-string (if noninteractive - (format "%s[INPUT WILL NOT BE HIDDEN!] " prompt) ; bug#17839 + (propertize prompt 'hide-chars t) ; bug#17839 prompt) nil t default)) ; t = "no history" (when (buffer-live-p minibuf) === modified file 'src/minibuf.c' --- src/minibuf.c 2014-05-26 02:28:09 +0000 +++ src/minibuf.c 2014-07-10 14:19:50 +0000 @@ -35,6 +35,10 @@ #include "keymap.h" #include "termhooks.h" +#include "systty.h" +extern void emacs_get_tty (int, struct emacs_tty *); +extern int emacs_set_tty (int, struct emacs_tty *, bool); + /* List of buffers for use as minibuffers. The first element of the list is used for the outermost minibuffer invocation, the next element is used for a recursive minibuffer @@ -209,6 +213,8 @@ } +static Lisp_Object Qhide_chars; + /* Like read_minibuf but reading from stdin. This function is called from read_minibuf to do the job if noninteractive. */ @@ -224,6 +230,20 @@ char *line; Lisp_Object val; int c; + bool hide_chars; + struct emacs_tty old, new; + + /* Check, whether we need to suppress echoing. */ + hide_chars = ! (NILP (Fget_text_property + (make_number (0), Qhide_chars, prompt))); + if (hide_chars) + { + emacs_get_tty (fileno (stdin), &old); + new = old; + new.main.c_lflag &= ~ICANON; /* Disable buffering */ + new.main.c_lflag &= ~ECHO; /* Disable echoing */ + emacs_set_tty (fileno (stdin), &new, 0); + } fprintf (stdout, "%s", SDATA (prompt)); fflush (stdout); @@ -240,8 +260,17 @@ if (errno != EINTR) break; } + else if (hide_chars && (c == 127)) /* DEL */ + { + /* Unfortunately, we cannot edit stdout. */ + // fprintf (stdout, "%c", c); + /* Hmm, this doesn't work for multi-byte characters. */ + (len > 0) && len--; + } else { + if (hide_chars) + fprintf (stdout, "."); if (len == size) { if (STRING_BYTES_BOUND / 2 < size) @@ -253,6 +282,13 @@ } } + /* Reset tty. */ + if (hide_chars) + { + fprintf (stdout, "\n"); + emacs_set_tty (fileno (stdin), &old, 0); + } + if (len || c == '\n') { val = make_string (line, len); @@ -1935,6 +1971,7 @@ DEFSYM (Qactivate_input_method, "activate-input-method"); DEFSYM (Qcase_fold_search, "case-fold-search"); DEFSYM (Qmetadata, "metadata"); + DEFSYM (Qhide_chars, "hide-chars"); DEFVAR_LISP ("read-expression-history", Vread_expression_history, doc: /* A history list for arguments that are Lisp expressions to evaluate. === modified file 'src/sysdep.c' --- src/sysdep.c 2014-06-09 14:50:57 +0000 +++ src/sysdep.c 2014-07-10 10:07:05 +0000 @@ -105,8 +105,8 @@ #include "syssignal.h" #include "systime.h" -static void emacs_get_tty (int, struct emacs_tty *); -static int emacs_set_tty (int, struct emacs_tty *, bool); +void emacs_get_tty (int, struct emacs_tty *) EXTERNALLY_VISIBLE; +int emacs_set_tty (int, struct emacs_tty *, bool) EXTERNALLY_VISIBLE; /* ULLONG_MAX is missing on Red Hat Linux 7.3; see Bug#11781. */ #ifndef ULLONG_MAX @@ -779,7 +779,7 @@ /* Set *TC to the parameters associated with the terminal FD, or clear it if the parameters are not available. */ -static void +void emacs_get_tty (int fd, struct emacs_tty *settings) { /* Retrieve the primary parameters - baud rate, character size, etcetera. */ @@ -795,7 +795,7 @@ *SETTINGS. If FLUSHP, discard input. Return 0 if all went well, and -1 (setting errno) if anything failed. */ -static int +int emacs_set_tty (int fd, struct emacs_tty *settings, bool flushp) { /* Set the primary parameters - baud rate, character size, etcetera. */