AmendHub

Download:

jcs

/

subtext

/

amendments

/

103

session_field_input: Add multiline support

Remove session_multiline_input since session_field_input just gets a
multiline flag. Also support backspacing at the beginning of a line
to jump back up to the end of the previous line.

jcs made amendment 103 over 2 years ago
--- chat.c Thu Feb 17 15:12:42 2022 +++ chat.c Fri May 20 10:38:49 2022 @@ -182,7 +182,7 @@ chat_start(struct session *s, char *with_node) for (;;) { input = session_field_input(s, CHAT_MAX_INPUT - 1, - s->terminal_columns - 1, NULL, 0); + s->terminal_columns - 1, NULL, false, 0); if (!input) break; session_output_string(s, --- mail.c Sun May 15 22:07:37 2022 +++ mail.c Fri May 20 10:40:14 2022 @@ -88,7 +88,7 @@ get_id: if (prompt) session_printf(s, "{{B}}%s:{{/B}} ", prompt); - tmp = session_field_input(s, 5, 5, start_s, 0); + tmp = session_field_input(s, 5, 5, start_s, false, 0); session_output(s, "\r\n", 2); session_flush(s); if (tmp == NULL || s->ending) { @@ -216,7 +216,7 @@ mail_compose_start: session_flush(s); tmp = session_field_input(s, DB_USERNAME_LENGTH + 1, - DB_USERNAME_LENGTH + 1, to_username, 0); + DB_USERNAME_LENGTH + 1, to_username, false, 0); if (to_username != NULL) free(to_username); to_username = tmp; @@ -243,7 +243,7 @@ mail_compose_start: session_output_template(s, "{{B}}Subject:{{/B}} "); session_flush(s); - tmp = session_field_input(s, 50, 50, msg.subject, 0); + tmp = session_field_input(s, 50, 50, msg.subject, false, 0); if (msg.subject != NULL) free(msg.subject); msg.subject = tmp; @@ -268,8 +268,8 @@ mail_compose_start: "{{B}}Message (^D when finished):{{/B}}\r\n"); session_flush(s); - tmp = session_multiline_input(s, s->terminal_columns - 1, - msg.body); + tmp = session_field_input(s, USHRT_MAX, s->terminal_columns - 1, + msg.body, true, 0); if (msg.body != NULL) free(msg.body); msg.body = tmp; --- session.c Sun May 15 22:10:09 2022 +++ session.c Fri May 20 12:29:38 2022 @@ -536,12 +536,14 @@ session_clear_input(struct session *session) /* * Collect up to size-1 bytes of input with trailing null, in a field * width columns wide, optionally masking echoed output with mask char. + * For multiline-capable input, */ char * session_field_input(struct session *session, unsigned short size, - unsigned short width, char *initial_input, char mask) + unsigned short width, char *initial_input, bool multiline, char mask) { - short ilen = 0, ipos = 0; + short ilen = 0, ipos = 0, over; + long n; char *field; unsigned short c; unsigned char chc; @@ -571,31 +573,52 @@ session_field_input(struct session *session, unsigned goto field_input_bail; } break; + case CONTROL_D: /* ^D */ + return field; case CONTROL_C: /* ^C */ + if (multiline) + return field; goto field_input_bail; case BACKSPACE: /* ^H */ case DELETE: /* backspace through telnet */ + case KEY_LEFT: if (ipos == 0) continue; - if (ipos < ilen) { - /* l:3 p:2 f:ab[cursor]c -> l:2 p:2 f:a[cursor]c */ + if (ipos < ilen && c != KEY_LEFT) { redraw = true; memmove(field + ipos - 1, field + ipos, ilen - 1); } - + + if (field[ipos - 1] == '\n') { + /* need to jump up a line and go over */ + session_output_string(session, + ansi(session, ANSI_UP_N, 1, ANSI_END)); + over = 1; + for (n = ipos - 2; n >= 0; n--) { + if (field[n] == '\n') + break; + over++; + } + session_output_string(session, + ansi(session, ANSI_COL_N, over, ANSI_END)); + session_flush(session); + } + ipos--; - ilen--; - field[ilen] = '\0'; - session_output_string(session, - ansi(session, ANSI_BACKSPACE, ANSI_END)); - + if (c != KEY_LEFT) { + ilen--; + field[ilen] = '\0'; + + session_output_string(session, + ansi(session, ANSI_BACKSPACE, ANSI_END)); + } + if (redraw) { session_output_string(session, ansi(session, ANSI_SAVE_CURSOR, ANSI_END)); - session_output(session, field + ipos, - ilen - ipos); + session_output(session, field + ipos, ilen - ipos); session_output(session, " ", 1); session_output_string(session, ansi(session, ANSI_RESTORE_SAVED_CURSOR, ANSI_END)); @@ -605,15 +628,12 @@ session_field_input(struct session *session, unsigned break; case '\r': case '\n': + if (multiline) { + if (c == '\r') + c = '\n'; + goto append_char; + } return field; - case KEY_LEFT: - if (ipos == 0) - continue; - ipos--; - session_output_string(session, - ansi(session, ANSI_BACK_N, 1, ANSI_END)); - session_flush(session); - break; case KEY_RIGHT: if (ipos == ilen) continue; @@ -623,7 +643,8 @@ session_field_input(struct session *session, unsigned session_flush(session); break; default: - if (c < 32 || c > 127) +append_char: + if ((c < 32 || c > 127) && (c != '\n')) break; if (ilen >= size - 1) break; @@ -658,88 +679,6 @@ field_input_bail: return NULL; } -char * -session_multiline_input(struct session *session, short cols, - char *initial_body) -{ - size_t size = 0, length = 0; - size_t pos = 0; - char *field = NULL; - unsigned short c; - bool redraw = false; - - session->abort_input = 0; - - if (initial_body) { - size = length = strlen(initial_body); - field = xmalloc(size + 1); - pos = strlcpy(field, initial_body, size + 1); - /* TODO: handle initial value being longer than width */ - session_output_string(session, field); - session_flush(session); - } - - for (;;) { - c = session_input_char(session); - if (session->ending || session->abort_input) - goto multiline_input_bail; - switch (c) { - case 0: /* session_input_char bailed */ - if (session->obuflen > 0) { - session->node_funcs->output(session); - uthread_yield(); - if (session->ending) - goto multiline_input_bail; - } - break; - case CONTROL_C: /* ^C */ - goto multiline_input_bail; - case CONTROL_D: /* ^D */ - return field; - case BACKSPACE: /* ^H */ - case DELETE: /* (backspace through telnet) */ - if (pos == 0) - continue; - - if (pos < length) { - /* l:3 p:2 f:ab[cursor]c -> l:2 p:2 f:a[cursor]c */ - redraw = true; - BlockMove((Ptr)(field + pos), (Ptr)(field + pos - 1), - length - 1); - } - - pos--; - length--; - field[pos] = '\0'; - - if (redraw) { - /* TODO */ - redraw = false; - } else { - session_output_string(session, - ansi(session, ANSI_BACKSPACE, ANSI_END)); - session_flush(session); - } - - break; - default: - if (c < 32 || c > 127) - break; - EXPAND_TO_FIT(field, size, length, 1, 64); - field[pos] = c; - pos++; - length++; - field[pos] = '\0'; - session_output(session, (char *)&c, 1); - session_flush(session); - } - } - -multiline_input_bail: - free(field); - return NULL; -} - short session_login(struct session *s) { @@ -759,7 +698,7 @@ session_login(struct session *s) } else { session_flush(s); username = session_field_input(s, DB_USERNAME_LENGTH + 1, - DB_USERNAME_LENGTH, NULL, 0); + DB_USERNAME_LENGTH, NULL, false, 0); session_output(s, "\r\n", 2); session_flush(s); @@ -801,7 +740,7 @@ session_login(struct session *s) session_output_string(s, "Password: "); session_flush(s); - password = session_field_input(s, 64, 64, NULL, '*'); + password = session_field_input(s, 64, 64, NULL, false, '*'); session_output(s, "\r\n", 2); session_flush(s); @@ -1148,7 +1087,7 @@ session_page_sysop(struct session *s) session_output_template(s, "{{B}}Message:{{/B}} "); session_flush(s); - message = session_field_input(s, 64, 64, NULL, 0); + message = session_field_input(s, 64, 64, NULL, false, 0); session_output(s, "\r\n", 2); session_flush(s); --- session.h Sun May 15 22:10:32 2022 +++ session.h Fri May 20 10:38:07 2022 @@ -123,9 +123,7 @@ size_t session_output_template(struct session *session size_t session_expand_template(struct session *session, const char *str, char **ret); char * session_field_input(struct session *session, unsigned short size, - unsigned short width, char *initial_input, char mask); -char * session_multiline_input(struct session *session, short cols, - char *initial_body); + unsigned short width, char *initial_input, bool multiline, char mask); char * session_bar(struct session *s, char *left_str, char *right_str); void session_pause_return(struct session *s, short enforce, char *msg); void session_recents(struct session *s); --- settings.c Sun May 15 22:27:29 2022 +++ settings.c Fri May 20 10:41:23 2022 @@ -154,7 +154,7 @@ get_input: switch (sf->type) { case CONFIG_TYPE_STRING: input = session_field_input(s, sf->max, 50, new_data + sf->off, - 0); + false, 0); session_output(s, "\r\n", 2); session_flush(s); if (input == NULL || s->ending) @@ -182,7 +182,7 @@ get_input: sval = (new_data[sf->off] << 8) | new_data[sf->off + 1]; snprintf(initial, sizeof(initial), "%d", sval); } - input = session_field_input(s, 10, 10, initial, 0); + input = session_field_input(s, 10, 10, initial, false, 0); session_output(s, "\r\n", 2); session_flush(s); if (input == NULL || s->ending) --- signup.c Sun May 15 22:12:21 2022 +++ signup.c Fri May 20 10:42:08 2022 @@ -46,7 +46,7 @@ signup(struct session *s) session_flush(s); username = session_field_input(s, DB_USERNAME_LENGTH + 1, - DB_USERNAME_LENGTH, NULL, 0); + DB_USERNAME_LENGTH, NULL, false, 0); session_output(s, "\r\n", 2); session_flush(s); @@ -65,7 +65,7 @@ signup(struct session *s) for (;;) { session_output_template(s, "{{B}}Password:{{/B}} "); session_flush(s); - password = session_field_input(s, 64, 64, NULL, '*'); + password = session_field_input(s, 64, 64, NULL, false, '*'); session_output(s, "\r\n", 2); session_flush(s); @@ -81,7 +81,8 @@ signup(struct session *s) session_output_template(s, "{{B}}Password (again):{{/B}} "); session_flush(s); - password_confirm = session_field_input(s, 64, 64, NULL, '*'); + password_confirm = session_field_input(s, 64, 64, NULL, false, + '*'); session_output(s, "\r\n", 2); session_flush(s);