Use formatParse split to position input cursor
parent
872608e5c4
commit
b36a134702
11
chat.h
11
chat.h
|
@ -86,15 +86,12 @@ enum {
|
||||||
struct Format {
|
struct Format {
|
||||||
const wchar_t *str;
|
const wchar_t *str;
|
||||||
size_t len;
|
size_t len;
|
||||||
bool bold;
|
bool split;
|
||||||
bool italic;
|
bool bold, italic, underline, reverse;
|
||||||
bool underline;
|
int fg, bg;
|
||||||
bool reverse;
|
|
||||||
int fg;
|
|
||||||
int bg;
|
|
||||||
};
|
};
|
||||||
void formatReset(struct Format *format);
|
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 handle(char *line);
|
||||||
void input(struct Tag tag, char *line);
|
void input(struct Tag tag, char *line);
|
||||||
|
|
9
edit.c
9
edit.c
|
@ -33,17 +33,10 @@ static struct {
|
||||||
.end = line.buf,
|
.end = line.buf,
|
||||||
};
|
};
|
||||||
|
|
||||||
// XXX: editTail must always be called after editHead.
|
|
||||||
static wchar_t tail;
|
|
||||||
const wchar_t *editHead(void) {
|
const wchar_t *editHead(void) {
|
||||||
tail = *line.ptr;
|
|
||||||
*line.ptr = L'\0';
|
|
||||||
return line.buf;
|
return line.buf;
|
||||||
}
|
}
|
||||||
const wchar_t *editTail(void) {
|
const wchar_t *editTail(void) {
|
||||||
if (tail) *line.ptr = tail;
|
|
||||||
*line.end = L'\0';
|
|
||||||
tail = L'\0';
|
|
||||||
return line.ptr;
|
return line.ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,4 +179,6 @@ void edit(struct Tag tag, enum Edit op, wchar_t ch) {
|
||||||
|
|
||||||
break; case EditEnter: accept(); enter(tag);
|
break; case EditEnter: accept(); enter(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*line.end = L'\0';
|
||||||
}
|
}
|
||||||
|
|
8
format.c
8
format.c
|
@ -64,10 +64,11 @@ static const wchar_t Stops[] = {
|
||||||
L'\0',
|
L'\0',
|
||||||
};
|
};
|
||||||
|
|
||||||
bool formatParse(struct Format *format, const wchar_t *stop) {
|
bool formatParse(struct Format *format, const wchar_t *split) {
|
||||||
format->str += format->len;
|
format->str += format->len;
|
||||||
if (!format->str[0]) return false;
|
if (!format->str[0]) return false;
|
||||||
|
|
||||||
|
const wchar_t *init = format->str;
|
||||||
switch (format->str[0]) {
|
switch (format->str[0]) {
|
||||||
break; case IRCBold: format->str++; format->bold ^= true;
|
break; case IRCBold: format->str++; format->bold ^= true;
|
||||||
break; case IRCItalic: format->str++; format->italic ^= 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 IRCColor: format->str++; parseColor(format);
|
||||||
break; case IRCReset: format->str++; formatReset(format);
|
break; case IRCReset: format->str++; formatReset(format);
|
||||||
}
|
}
|
||||||
|
format->split = (split >= init && split <= format->str);
|
||||||
|
|
||||||
if (format->str[0] == L' ') {
|
if (format->str[0] == L' ') {
|
||||||
format->len = 1 + wcscspn(&format->str[1], Stops);
|
format->len = 1 + wcscspn(&format->str[1], Stops);
|
||||||
} else {
|
} else {
|
||||||
format->len = wcscspn(format->str, Stops);
|
format->len = wcscspn(format->str, Stops);
|
||||||
}
|
}
|
||||||
if (stop && stop > format->str && stop < &format->str[format->len]) {
|
if (split > format->str && split < &format->str[format->len]) {
|
||||||
format->len = stop - format->str;
|
format->len = split - format->str;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
50
ui.c
50
ui.c
|
@ -239,10 +239,25 @@ static const short IRCColors[] = {
|
||||||
[IRCLightGray] = 0 + COLOR_WHITE,
|
[IRCLightGray] = 0 + COLOR_WHITE,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int addIRC(WINDOW *win, const wchar_t *str) {
|
static void addFormat(WINDOW *win, const struct Format *format) {
|
||||||
int lines = 0;
|
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 };
|
struct Format format = { .str = str };
|
||||||
formatReset(&format);
|
formatReset(&format);
|
||||||
|
int lines = 0;
|
||||||
while (formatParse(&format, NULL)) {
|
while (formatParse(&format, NULL)) {
|
||||||
int _, x, xMax;
|
int _, x, xMax;
|
||||||
getyx(win, _, x);
|
getyx(win, _, x);
|
||||||
|
@ -255,19 +270,7 @@ static int addIRC(WINDOW *win, const wchar_t *str) {
|
||||||
waddch(win, '\n');
|
waddch(win, '\n');
|
||||||
lines++;
|
lines++;
|
||||||
}
|
}
|
||||||
|
addFormat(win, &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);
|
|
||||||
}
|
}
|
||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
|
@ -293,7 +296,7 @@ static void uiStatus(void) {
|
||||||
if (len < 0) err(EX_OSERR, "aswprintf");
|
if (len < 0) err(EX_OSERR, "aswprintf");
|
||||||
if (view->unread == 1) str[unread] = L'\0';
|
if (view->unread == 1) str[unread] = L'\0';
|
||||||
|
|
||||||
addIRC(ui.status, count ? str : &str[1]);
|
addWrap(ui.status, count ? str : &str[1]);
|
||||||
free(str);
|
free(str);
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
@ -360,7 +363,7 @@ void uiTopic(struct Tag tag, const char *topic) {
|
||||||
wchar_t *wcs = ambstowcs(topic);
|
wchar_t *wcs = ambstowcs(topic);
|
||||||
if (!wcs) err(EX_DATAERR, "ambstowcs");
|
if (!wcs) err(EX_DATAERR, "ambstowcs");
|
||||||
wmove(view->topic, 0, 0);
|
wmove(view->topic, 0, 0);
|
||||||
addIRC(view->topic, wcs);
|
addWrap(view->topic, wcs);
|
||||||
wclrtoeol(view->topic);
|
wclrtoeol(view->topic);
|
||||||
free(wcs);
|
free(wcs);
|
||||||
}
|
}
|
||||||
|
@ -380,7 +383,7 @@ void uiLog(struct Tag tag, enum UIHeat heat, const wchar_t *line) {
|
||||||
}
|
}
|
||||||
uiStatus();
|
uiStatus();
|
||||||
}
|
}
|
||||||
lines += addIRC(view->log, line);
|
lines += addWrap(view->log, line);
|
||||||
if (view->scroll != LogLines) view->scroll -= lines;
|
if (view->scroll != LogLines) view->scroll -= lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -545,9 +548,14 @@ void uiRead(void) {
|
||||||
|
|
||||||
int y, x;
|
int y, x;
|
||||||
wmove(ui.input, 0, 0);
|
wmove(ui.input, 0, 0);
|
||||||
addIRC(ui.input, editHead());
|
|
||||||
getyx(ui.input, y, x);
|
struct Format format = { .str = editHead() };
|
||||||
addIRC(ui.input, editTail());
|
formatReset(&format);
|
||||||
|
while (formatParse(&format, editTail())) {
|
||||||
|
if (format.split) getyx(ui.input, y, x);
|
||||||
|
addFormat(ui.input, &format);
|
||||||
|
}
|
||||||
|
|
||||||
wclrtoeol(ui.input);
|
wclrtoeol(ui.input);
|
||||||
wmove(ui.input, y, x);
|
wmove(ui.input, y, x);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue