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);