From b36a1347022965fdbe1b61298dc6a05be2d2a34d Mon Sep 17 00:00:00 2001 From: Curtis McEnroe Date: Wed, 12 Sep 2018 22:55:02 -0400 Subject: [PATCH] Use formatParse split to position input cursor --- chat.h | 11 ++++------- edit.c | 11 +++-------- format.c | 8 +++++--- ui.c | 50 +++++++++++++++++++++++++++++--------------------- 4 files changed, 41 insertions(+), 39 deletions(-) diff --git a/chat.h b/chat.h index 50f5c87..6295ce6 100644 --- a/chat.h +++ b/chat.h @@ -86,15 +86,12 @@ enum { struct Format { const wchar_t *str; size_t len; - bool bold; - bool italic; - bool underline; - bool reverse; - int fg; - int bg; + bool split; + bool bold, italic, underline, reverse; + int fg, bg; }; void formatReset(struct Format *format); -bool formatParse(struct Format *format, const wchar_t *stop); +bool formatParse(struct Format *format, const wchar_t *split); void handle(char *line); void input(struct Tag tag, char *line); diff --git a/edit.c b/edit.c index 5aca61f..38ee843 100644 --- a/edit.c +++ b/edit.c @@ -33,17 +33,10 @@ static struct { .end = line.buf, }; -// XXX: editTail must always be called after editHead. -static wchar_t tail; const wchar_t *editHead(void) { - tail = *line.ptr; - *line.ptr = L'\0'; return line.buf; } const wchar_t *editTail(void) { - if (tail) *line.ptr = tail; - *line.end = L'\0'; - tail = L'\0'; return line.ptr; } @@ -180,10 +173,12 @@ void edit(struct Tag tag, enum Edit op, wchar_t ch) { break; case EditKillBackWord: reject(); killBackWord(); break; case EditKillForeWord: reject(); killForeWord(); - break; case EditKillLine: reject(); line.end = line.ptr; + break; case EditKillLine: reject(); line.end = line.ptr; break; case EditComplete: complete(tag); break; case EditEnter: accept(); enter(tag); } + + *line.end = L'\0'; } diff --git a/format.c b/format.c index 800388b..30b287e 100644 --- a/format.c +++ b/format.c @@ -64,10 +64,11 @@ static const wchar_t Stops[] = { L'\0', }; -bool formatParse(struct Format *format, const wchar_t *stop) { +bool formatParse(struct Format *format, const wchar_t *split) { format->str += format->len; if (!format->str[0]) return false; + const wchar_t *init = format->str; switch (format->str[0]) { break; case IRCBold: format->str++; format->bold ^= true; break; case IRCItalic: format->str++; format->italic ^= true; @@ -76,14 +77,15 @@ bool formatParse(struct Format *format, const wchar_t *stop) { break; case IRCColor: format->str++; parseColor(format); break; case IRCReset: format->str++; formatReset(format); } + format->split = (split >= init && split <= format->str); if (format->str[0] == L' ') { format->len = 1 + wcscspn(&format->str[1], Stops); } else { format->len = wcscspn(format->str, Stops); } - if (stop && stop > format->str && stop < &format->str[format->len]) { - format->len = stop - format->str; + if (split > format->str && split < &format->str[format->len]) { + format->len = split - format->str; } return true; } diff --git a/ui.c b/ui.c index 90a75af..72fed6a 100644 --- a/ui.c +++ b/ui.c @@ -239,10 +239,25 @@ static const short IRCColors[] = { [IRCLightGray] = 0 + COLOR_WHITE, }; -static int addIRC(WINDOW *win, const wchar_t *str) { - int lines = 0; +static void addFormat(WINDOW *win, const struct Format *format) { + attr_t attr = A_NORMAL; + if (format->bold) attr |= A_BOLD; + if (format->italic) attr |= A_ITALIC; + if (format->underline) attr |= A_UNDERLINE; + if (format->reverse) attr |= A_REVERSE; + + short pair = -1; + if (format->fg >= 0) pair = IRCColors[format->fg]; + if (format->bg >= 0) pair |= IRCColors[format->bg] << 4; + + wattr_set(win, attr | attr8(pair), 1 + pair8(pair), NULL); + waddnwstr(win, format->str, format->len); +} + +static int addWrap(WINDOW *win, const wchar_t *str) { struct Format format = { .str = str }; formatReset(&format); + int lines = 0; while (formatParse(&format, NULL)) { int _, x, xMax; getyx(win, _, x); @@ -255,19 +270,7 @@ static int addIRC(WINDOW *win, const wchar_t *str) { waddch(win, '\n'); lines++; } - - attr_t attr = A_NORMAL; - if (format.bold) attr |= A_BOLD; - if (format.italic) attr |= A_ITALIC; - if (format.underline) attr |= A_UNDERLINE; - if (format.reverse) attr |= A_REVERSE; - - short pair = -1; - if (format.fg >= 0) pair = IRCColors[format.fg]; - if (format.bg >= 0) pair |= IRCColors[format.bg] << 4; - - wattr_set(win, attr | attr8(pair), 1 + pair8(pair), NULL); - waddnwstr(win, format.str, format.len); + addFormat(win, &format); } return lines; } @@ -293,7 +296,7 @@ static void uiStatus(void) { if (len < 0) err(EX_OSERR, "aswprintf"); if (view->unread == 1) str[unread] = L'\0'; - addIRC(ui.status, count ? str : &str[1]); + addWrap(ui.status, count ? str : &str[1]); free(str); count++; } @@ -360,7 +363,7 @@ void uiTopic(struct Tag tag, const char *topic) { wchar_t *wcs = ambstowcs(topic); if (!wcs) err(EX_DATAERR, "ambstowcs"); wmove(view->topic, 0, 0); - addIRC(view->topic, wcs); + addWrap(view->topic, wcs); wclrtoeol(view->topic); free(wcs); } @@ -380,7 +383,7 @@ void uiLog(struct Tag tag, enum UIHeat heat, const wchar_t *line) { } uiStatus(); } - lines += addIRC(view->log, line); + lines += addWrap(view->log, line); if (view->scroll != LogLines) view->scroll -= lines; } @@ -545,9 +548,14 @@ void uiRead(void) { int y, x; wmove(ui.input, 0, 0); - addIRC(ui.input, editHead()); - getyx(ui.input, y, x); - addIRC(ui.input, editTail()); + + struct Format format = { .str = editHead() }; + formatReset(&format); + while (formatParse(&format, editTail())) { + if (format.split) getyx(ui.input, y, x); + addFormat(ui.input, &format); + } + wclrtoeol(ui.input); wmove(ui.input, y, x); }