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

New feature: Support hidden input (for passwords and the like). #8

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
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
44 changes: 37 additions & 7 deletions linenoise.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,9 @@ static int history_max_len = LINENOISE_DEFAULT_HISTORY_MAX_LEN;
static int history_len = 0;
static char **history = NULL;

/* input mode: hidden vs. regular */
static int is_hidden = 0;

/* Structure to contain the status of the current (being edited) line */
struct current {
char *buf; /* Current buffer. Always null terminated */
Expand Down Expand Up @@ -744,13 +747,22 @@ static void refreshLine(const char *prompt, struct current *current)
for (i = 0; i < chars; i++) {
int ch;
int w = utf8_tounicode(buf + b, &ch);
if (ch < ' ') {
if (!is_hidden && ch < ' ') {
n++;
}
if (pchars + i + n >= current->cols) {
break;
}
if (ch < ' ') {
if (is_hidden) {
/* In hidden mode all user-entered characters are shown as
* astericks ('*'). This is like control chars, except for
* a different translation. */
/* assert (b == 0) */
outputChars(current, "*", 1);
buf += w;
/* keep b = 0; */
}
else if (ch < ' ') {
/* A control character, so write the buffer so far */
outputChars(current, buf, b);
buf += b + w;
Expand All @@ -764,6 +776,8 @@ static void refreshLine(const char *prompt, struct current *current)
b += w;
}
}

/* if (is_hidden) assert (b==0) */
outputChars(current, buf, b);

/* Erase to right, move cursor to original position */
Expand Down Expand Up @@ -840,7 +854,7 @@ static int insert_char(struct current *current, int pos, int ch)

#ifdef USE_TERMIOS
/* optimise the case where adding a single char to the end and no scrolling is needed */
if (current->pos == pos && current->chars == pos) {
if (!is_hidden && current->pos == pos && current->chars == pos) {
if (ch >= ' ' && utf8_strlen(current->prompt, -1) + utf8_strlen(current->buf, current->len) < current->cols - 1) {
IGNORE_RC(write(current->fd, buf, n));
ret = 2;
Expand Down Expand Up @@ -971,10 +985,14 @@ static int linenoisePrompt(struct current *current) {
int c = fd_read(current);

#ifndef NO_COMPLETION
/* Only autocomplete when the callback is set. It returns < 0 when
/* Completion is forbidden for hidden input mode.
* Only autocomplete when the callback is set. It returns < 0 when
* there was an error reading from fd. Otherwise it will return the
* character that should be handled next. */
if (c == '\t' && current->pos == current->chars && completionCallback != NULL) {
if (c == '\t' &&
!is_hidden &&
current->pos == current->chars &&
completionCallback != NULL) {
c = completeLine(current);
/* Return on errors */
if (c < 0) return current->len;
Expand Down Expand Up @@ -1041,7 +1059,8 @@ static int linenoisePrompt(struct current *current) {
}
break;
case ctrl('R'): /* ctrl-r */
{
/* Hidden input mode disables use of the history */
if (!is_hidden) {
/* Display the reverse-i-search prompt and process chars */
char rbuf[50];
char rprompt[80];
Expand Down Expand Up @@ -1196,7 +1215,8 @@ static int linenoisePrompt(struct current *current) {
case ctrl('N'):
case SPECIAL_DOWN:
history_navigation:
if (history_len > 1) {
/* Hidden input mode disables use of the history */
if (!is_hidden && history_len > 1) {
/* Update the current history entry before to
* overwrite it with tne next one. */
free(history[history_len - 1 - history_index]);
Expand Down Expand Up @@ -1290,6 +1310,16 @@ char *linenoise(const char *prompt)
return strdup(buf);
}

void linenoiseSetHidden(int enable)
{
is_hidden = enable;
}

int linenoiseGetHidden(void)
{
return is_hidden;
}

/* Using a circular buffer is smarter, but a bit more complex to handle. */
int linenoiseHistoryAdd(const char *line) {
char *linecopy;
Expand Down
2 changes: 2 additions & 0 deletions linenoise.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ void linenoiseAddCompletion(linenoiseCompletions *, const char *);
#endif

char *linenoise(const char *prompt);
void linenoiseSetHidden(int enable);
int linenoiseGetHidden(void);
int linenoiseHistoryAdd(const char *line);
int linenoiseHistorySetMaxLen(int len);
int linenoiseHistoryGetMaxLen(void);
Expand Down