Use formatParse split to position input cursor
This commit is contained in:
		
							父節點
							
								
									872608e5c4
								
							
						
					
					
						當前提交
						b36a134702
					
				
							
								
								
									
										11
									
								
								chat.h
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								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);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										9
									
								
								edit.c
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -186,4 +179,6 @@ void edit(struct Tag tag, enum Edit op, wchar_t ch) {
 | 
			
		||||
 | 
			
		||||
		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',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										50
									
								
								ui.c
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user