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 {
 | 
					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);
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										11
									
								
								edit.c
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								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;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -180,10 +173,12 @@ void edit(struct Tag tag, enum Edit op, wchar_t ch) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		break; case EditKillBackWord: reject(); killBackWord();
 | 
							break; case EditKillBackWord: reject(); killBackWord();
 | 
				
			||||||
		break; case EditKillForeWord: reject(); killForeWord();
 | 
							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 EditComplete: complete(tag);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user