Use formatParse split to position input cursor
This commit is contained in:
		
							parent
							
								
									872608e5c4
								
							
						
					
					
						commit
						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