Use PascalCase for constants
Begone underscores.
This commit is contained in:
		
							parent
							
								
									ccb54d36d9
								
							
						
					
					
						commit
						240f9ebf84
					
				
							
								
								
									
										12
									
								
								chat.c
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								chat.c
									
									
									
									
									
								
							| @ -60,7 +60,7 @@ static union { | |||||||
| 
 | 
 | ||||||
| void spawn(char *const argv[]) { | void spawn(char *const argv[]) { | ||||||
| 	if (fds.pipe.events) { | 	if (fds.pipe.events) { | ||||||
| 		uiLog(TAG_STATUS, UI_WARM, L"spawn: existing pipe"); | 		uiLog(TagStatus, UIWarm, L"spawn: existing pipe"); | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -93,7 +93,7 @@ static void pipeRead(void) { | |||||||
| 	if (len) { | 	if (len) { | ||||||
| 		buf[len] = '\0'; | 		buf[len] = '\0'; | ||||||
| 		len = strcspn(buf, "\n"); | 		len = strcspn(buf, "\n"); | ||||||
| 		uiFmt(TAG_STATUS, UI_WARM, "spawn: %.*s", (int)len, buf); | 		uiFmt(TagStatus, UIWarm, "spawn: %.*s", (int)len, buf); | ||||||
| 	} else { | 	} else { | ||||||
| 		close(fds.pipe.fd); | 		close(fds.pipe.fd); | ||||||
| 		fds.pipe.events = 0; | 		fds.pipe.events = 0; | ||||||
| @ -124,15 +124,15 @@ static void sigchld(int sig) { | |||||||
| 	pid_t pid = wait(&status); | 	pid_t pid = wait(&status); | ||||||
| 	if (pid < 0) err(EX_OSERR, "wait"); | 	if (pid < 0) err(EX_OSERR, "wait"); | ||||||
| 	if (WIFEXITED(status) && WEXITSTATUS(status)) { | 	if (WIFEXITED(status) && WEXITSTATUS(status)) { | ||||||
| 		uiFmt(TAG_STATUS, UI_WARM, "spawn: exit %d", WEXITSTATUS(status)); | 		uiFmt(TagStatus, UIWarm, "spawn: exit %d", WEXITSTATUS(status)); | ||||||
| 	} else if (WIFSIGNALED(status)) { | 	} else if (WIFSIGNALED(status)) { | ||||||
| 		uiFmt(TAG_STATUS, UI_WARM, "spawn: signal %d", WTERMSIG(status)); | 		uiFmt(TagStatus, UIWarm, "spawn: signal %d", WTERMSIG(status)); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void sigint(int sig) { | static void sigint(int sig) { | ||||||
| 	(void)sig; | 	(void)sig; | ||||||
| 	input(TAG_STATUS, "/quit"); | 	input(TagStatus, "/quit"); | ||||||
| 	uiExit(); | 	uiExit(); | ||||||
| 	exit(EX_OK); | 	exit(EX_OK); | ||||||
| } | } | ||||||
| @ -183,7 +183,7 @@ int main(int argc, char *argv[]) { | |||||||
| 	inputTab(); | 	inputTab(); | ||||||
| 
 | 
 | ||||||
| 	uiInit(); | 	uiInit(); | ||||||
| 	uiLog(TAG_STATUS, UI_WARM, L"Traveling..."); | 	uiLog(TagStatus, UIWarm, L"Traveling..."); | ||||||
| 	uiDraw(); | 	uiDraw(); | ||||||
| 
 | 
 | ||||||
| 	fds.irc.fd = ircConnect(host, port, pass, webirc); | 	fds.irc.fd = ircConnect(host, port, pass, webirc); | ||||||
|  | |||||||
							
								
								
									
										100
									
								
								chat.h
									
									
									
									
									
								
							
							
						
						
									
										100
									
								
								chat.h
									
									
									
									
									
								
							| @ -42,38 +42,38 @@ struct Tag { | |||||||
| 	const char *name; | 	const char *name; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| enum { TAGS_LEN = 256 }; | enum { TagsLen = 256 }; | ||||||
| const struct Tag TAG_NONE; | const struct Tag TagNone; | ||||||
| const struct Tag TAG_STATUS; | const struct Tag TagStatus; | ||||||
| const struct Tag TAG_VERBOSE; | const struct Tag TagVerbose; | ||||||
| struct Tag tagFind(const char *name); | struct Tag tagFind(const char *name); | ||||||
| struct Tag tagFor(const char *name); | struct Tag tagFor(const char *name); | ||||||
| 
 | 
 | ||||||
| enum { | enum { | ||||||
| 	IRC_WHITE, | 	IRCWhite, | ||||||
| 	IRC_BLACK, | 	IRCBlack, | ||||||
| 	IRC_BLUE, | 	IRCBlue, | ||||||
| 	IRC_GREEN, | 	IRCGreen, | ||||||
| 	IRC_RED, | 	IRCRed, | ||||||
| 	IRC_BROWN, | 	IRCBrown, | ||||||
| 	IRC_MAGENTA, | 	IRCMagenta, | ||||||
| 	IRC_ORANGE, | 	IRCOrange, | ||||||
| 	IRC_YELLOW, | 	IRCYellow, | ||||||
| 	IRC_LIGHT_GREEN, | 	IRCLightGreen, | ||||||
| 	IRC_CYAN, | 	IRCCyan, | ||||||
| 	IRC_LIGHT_CYAN, | 	IRCLightCyan, | ||||||
| 	IRC_LIGHT_BLUE, | 	IRCLightBlue, | ||||||
| 	IRC_PINK, | 	IRCPink, | ||||||
| 	IRC_GRAY, | 	IRCGray, | ||||||
| 	IRC_LIGHT_GRAY, | 	IRCLightGray, | ||||||
| }; | }; | ||||||
| enum { | enum { | ||||||
| 	IRC_BOLD      = 002, | 	IRCBold      = 002, | ||||||
| 	IRC_COLOR     = 003, | 	IRCColor     = 003, | ||||||
| 	IRC_REVERSE   = 026, | 	IRCReverse   = 026, | ||||||
| 	IRC_RESET     = 017, | 	IRCReset     = 017, | ||||||
| 	IRC_ITALIC    = 035, | 	IRCItalic    = 035, | ||||||
| 	IRC_UNDERLINE = 037, | 	IRCUnderline = 037, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| void handle(char *line); | void handle(char *line); | ||||||
| @ -98,24 +98,24 @@ void uiViewNum(int num); | |||||||
| void uiCloseTag(struct Tag tag); | void uiCloseTag(struct Tag tag); | ||||||
| 
 | 
 | ||||||
| enum UIHeat { | enum UIHeat { | ||||||
| 	UI_COLD, | 	UICold, | ||||||
| 	UI_WARM, | 	UIWarm, | ||||||
| 	UI_HOT, | 	UIHot, | ||||||
| }; | }; | ||||||
| void uiTopic(struct Tag tag, const char *topic); | void uiTopic(struct Tag tag, const char *topic); | ||||||
| void uiLog(struct Tag tag, enum UIHeat heat, const wchar_t *line); | void uiLog(struct Tag tag, enum UIHeat heat, const wchar_t *line); | ||||||
| void uiFmt(struct Tag tag, enum UIHeat heat, const wchar_t *format, ...); | void uiFmt(struct Tag tag, enum UIHeat heat, const wchar_t *format, ...); | ||||||
| 
 | 
 | ||||||
| enum TermMode { | enum TermMode { | ||||||
| 	TERM_FOCUS, | 	TermFocus, | ||||||
| 	TERM_PASTE, | 	TermPaste, | ||||||
| }; | }; | ||||||
| enum TermEvent { | enum TermEvent { | ||||||
| 	TERM_NONE, | 	TermNone, | ||||||
| 	TERM_FOCUS_IN, | 	TermFocusIn, | ||||||
| 	TERM_FOCUS_OUT, | 	TermFocusOut, | ||||||
| 	TERM_PASTE_START, | 	TermPasteStart, | ||||||
| 	TERM_PASTE_END, | 	TermPasteEnd, | ||||||
| }; | }; | ||||||
| void termInit(void); | void termInit(void); | ||||||
| void termTitle(const char *title); | void termTitle(const char *title); | ||||||
| @ -123,20 +123,20 @@ void termMode(enum TermMode mode, bool set); | |||||||
| enum TermEvent termEvent(char ch); | enum TermEvent termEvent(char ch); | ||||||
| 
 | 
 | ||||||
| enum Edit { | enum Edit { | ||||||
| 	EDIT_LEFT, | 	EditLeft, | ||||||
| 	EDIT_RIGHT, | 	EditRight, | ||||||
| 	EDIT_HOME, | 	EditHome, | ||||||
| 	EDIT_END, | 	EditEnd, | ||||||
| 	EDIT_BACK_WORD, | 	EditBackWord, | ||||||
| 	EDIT_FORE_WORD, | 	EditForeWord, | ||||||
| 	EDIT_INSERT, | 	EditInsert, | ||||||
| 	EDIT_BACKSPACE, | 	EditBackspace, | ||||||
| 	EDIT_DELETE, | 	EditDelete, | ||||||
| 	EDIT_KILL_BACK_WORD, | 	EditKillBackWord, | ||||||
| 	EDIT_KILL_FORE_WORD, | 	EditKillForeWord, | ||||||
| 	EDIT_KILL_LINE, | 	EditKillLine, | ||||||
| 	EDIT_COMPLETE, | 	EditComplete, | ||||||
| 	EDIT_ENTER, | 	EditEnter, | ||||||
| }; | }; | ||||||
| void edit(struct Tag tag, enum Edit op, wchar_t ch); | void edit(struct Tag tag, enum Edit op, wchar_t ch); | ||||||
| const wchar_t *editHead(void); | const wchar_t *editHead(void); | ||||||
|  | |||||||
							
								
								
									
										34
									
								
								edit.c
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								edit.c
									
									
									
									
									
								
							| @ -22,9 +22,9 @@ | |||||||
| 
 | 
 | ||||||
| #include "chat.h" | #include "chat.h" | ||||||
| 
 | 
 | ||||||
| enum { BUF_LEN = 512 }; | enum { BufLen = 512 }; | ||||||
| static struct { | static struct { | ||||||
| 	wchar_t buf[BUF_LEN]; | 	wchar_t buf[BufLen]; | ||||||
| 	wchar_t *ptr; | 	wchar_t *ptr; | ||||||
| 	wchar_t *end; | 	wchar_t *end; | ||||||
| 	wchar_t *tab; | 	wchar_t *tab; | ||||||
| @ -66,7 +66,7 @@ static void foreWord(void) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void insert(wchar_t ch) { | static void insert(wchar_t ch) { | ||||||
| 	if (line.end == &line.buf[BUF_LEN - 1]) return; | 	if (line.end == &line.buf[BufLen - 1]) return; | ||||||
| 	if (line.ptr != line.end) { | 	if (line.ptr != line.end) { | ||||||
| 		wmemmove(line.ptr + 1, line.ptr, line.end - line.ptr); | 		wmemmove(line.ptr + 1, line.ptr, line.end - line.ptr); | ||||||
| 	} | 	} | ||||||
| @ -166,24 +166,24 @@ static void enter(struct Tag tag) { | |||||||
| 
 | 
 | ||||||
| void edit(struct Tag tag, enum Edit op, wchar_t ch) { | void edit(struct Tag tag, enum Edit op, wchar_t ch) { | ||||||
| 	switch (op) { | 	switch (op) { | ||||||
| 		break; case EDIT_LEFT:  reject(); left(); | 		break; case EditLeft:  reject(); left(); | ||||||
| 		break; case EDIT_RIGHT: reject(); right(); | 		break; case EditRight: reject(); right(); | ||||||
| 		break; case EDIT_HOME:  reject(); line.ptr = line.buf; | 		break; case EditHome:  reject(); line.ptr = line.buf; | ||||||
| 		break; case EDIT_END:   reject(); line.ptr = line.end; | 		break; case EditEnd:   reject(); line.ptr = line.end; | ||||||
| 
 | 
 | ||||||
| 		break; case EDIT_BACK_WORD: reject(); backWord(); | 		break; case EditBackWord: reject(); backWord(); | ||||||
| 		break; case EDIT_FORE_WORD: reject(); foreWord(); | 		break; case EditForeWord: reject(); foreWord(); | ||||||
| 
 | 
 | ||||||
| 		break; case EDIT_INSERT:    accept(); insert(ch); | 		break; case EditInsert:    accept(); insert(ch); | ||||||
| 		break; case EDIT_BACKSPACE: reject(); backspace(); | 		break; case EditBackspace: reject(); backspace(); | ||||||
| 		break; case EDIT_DELETE:    reject(); delete(); | 		break; case EditDelete:    reject(); delete(); | ||||||
| 
 | 
 | ||||||
| 		break; case EDIT_KILL_BACK_WORD: reject(); killBackWord(); | 		break; case EditKillBackWord: reject(); killBackWord(); | ||||||
| 		break; case EDIT_KILL_FORE_WORD: reject(); killForeWord(); | 		break; case EditKillForeWord: reject(); killForeWord(); | ||||||
| 		break; case EDIT_KILL_LINE:      reject(); line.end = line.ptr; | 		break; case EditKillLine:      reject(); line.end = line.ptr; | ||||||
| 
 | 
 | ||||||
| 		break; case EDIT_COMPLETE: complete(tag); | 		break; case EditComplete: complete(tag); | ||||||
| 
 | 
 | ||||||
| 		break; case EDIT_ENTER: accept(); enter(tag); | 		break; case EditEnter: accept(); enter(tag); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										64
									
								
								handle.c
									
									
									
									
									
								
							
							
						
						
									
										64
									
								
								handle.c
									
									
									
									
									
								
							| @ -33,15 +33,15 @@ static uint32_t hashChar(uint32_t hash, char ch) { | |||||||
| 	return hash; | 	return hash; | ||||||
| } | } | ||||||
| static int color(const char *str) { | static int color(const char *str) { | ||||||
| 	if (!str) return IRC_GRAY; | 	if (!str) return IRCGray; | ||||||
| 	uint32_t hash = 0; | 	uint32_t hash = 0; | ||||||
| 	for (; str[0]; ++str) { | 	for (; str[0]; ++str) { | ||||||
| 		hash = hashChar(hash, str[0]); | 		hash = hashChar(hash, str[0]); | ||||||
| 	} | 	} | ||||||
| 	while (IRC_BLACK == (hash & IRC_LIGHT_GRAY)) { | 	while (IRCBlack == (hash & IRCLightGray)) { | ||||||
| 		hash = hashChar(hash, '\0'); | 		hash = hashChar(hash, '\0'); | ||||||
| 	} | 	} | ||||||
| 	return (hash & IRC_LIGHT_GRAY); | 	return (hash & IRCLightGray); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static char *paramField(char **params) { | static char *paramField(char **params) { | ||||||
| @ -125,8 +125,8 @@ static void handlePing(char *prefix, char *params) { | |||||||
| static void handleReplyErroneousNickname(char *prefix, char *params) { | static void handleReplyErroneousNickname(char *prefix, char *params) { | ||||||
| 	char *mesg; | 	char *mesg; | ||||||
| 	shift(prefix, NULL, NULL, NULL, params, 3, 0, NULL, NULL, &mesg); | 	shift(prefix, NULL, NULL, NULL, params, 3, 0, NULL, NULL, &mesg); | ||||||
| 	uiFmt(TAG_STATUS, UI_HOT, "You can't use that name here: \"%s\"", mesg); | 	uiFmt(TagStatus, UIHot, "You can't use that name here: \"%s\"", mesg); | ||||||
| 	uiLog(TAG_STATUS, UI_COLD, L"Type /nick <name> to choose a new one"); | 	uiLog(TagStatus, UICold, L"Type /nick <name> to choose a new one"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void handleReplyWelcome(char *prefix, char *params) { | static void handleReplyWelcome(char *prefix, char *params) { | ||||||
| @ -135,9 +135,9 @@ static void handleReplyWelcome(char *prefix, char *params) { | |||||||
| 
 | 
 | ||||||
| 	if (strcmp(nick, self.nick)) selfNick(nick); | 	if (strcmp(nick, self.nick)) selfNick(nick); | ||||||
| 	if (self.join) ircFmt("JOIN %s\r\n", self.join); | 	if (self.join) ircFmt("JOIN %s\r\n", self.join); | ||||||
| 	tabTouch(TAG_STATUS, self.nick); | 	tabTouch(TagStatus, self.nick); | ||||||
| 
 | 
 | ||||||
| 	uiLog(TAG_STATUS, UI_WARM, L"You have arrived"); | 	uiLog(TagStatus, UIWarm, L"You have arrived"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void handleReplyMOTD(char *prefix, char *params) { | static void handleReplyMOTD(char *prefix, char *params) { | ||||||
| @ -145,8 +145,8 @@ static void handleReplyMOTD(char *prefix, char *params) { | |||||||
| 	shift(prefix, NULL, NULL, NULL, params, 2, 0, NULL, &mesg); | 	shift(prefix, NULL, NULL, NULL, params, 2, 0, NULL, &mesg); | ||||||
| 	if (mesg[0] == '-' && mesg[1] == ' ') mesg = &mesg[2]; | 	if (mesg[0] == '-' && mesg[1] == ' ') mesg = &mesg[2]; | ||||||
| 
 | 
 | ||||||
| 	urlScan(TAG_STATUS, mesg); | 	urlScan(TagStatus, mesg); | ||||||
| 	uiFmt(TAG_STATUS, UI_COLD, "%s", mesg); | 	uiFmt(TagStatus, UICold, "%s", mesg); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void handleJoin(char *prefix, char *params) { | static void handleJoin(char *prefix, char *params) { | ||||||
| @ -155,13 +155,13 @@ static void handleJoin(char *prefix, char *params) { | |||||||
| 	struct Tag tag = tagFor(chan); | 	struct Tag tag = tagFor(chan); | ||||||
| 
 | 
 | ||||||
| 	if (isSelf(nick, user)) { | 	if (isSelf(nick, user)) { | ||||||
| 		tabTouch(TAG_NONE, chan); | 		tabTouch(TagNone, chan); | ||||||
| 		uiViewTag(tag); | 		uiViewTag(tag); | ||||||
| 	} | 	} | ||||||
| 	tabTouch(tag, nick); | 	tabTouch(tag, nick); | ||||||
| 
 | 
 | ||||||
| 	uiFmt( | 	uiFmt( | ||||||
| 		tag, UI_COLD, | 		tag, UICold, | ||||||
| 		"\3%d%s\3 arrives in \3%d%s\3", | 		"\3%d%s\3 arrives in \3%d%s\3", | ||||||
| 		color(user), nick, color(chan), chan | 		color(user), nick, color(chan), chan | ||||||
| 	); | 	); | ||||||
| @ -182,14 +182,14 @@ static void handlePart(char *prefix, char *params) { | |||||||
| 	if (mesg) { | 	if (mesg) { | ||||||
| 		urlScan(tag, mesg); | 		urlScan(tag, mesg); | ||||||
| 		uiFmt( | 		uiFmt( | ||||||
| 			tag, UI_COLD, | 			tag, UICold, | ||||||
| 			"\3%d%s\3 leaves \3%d%s\3, \"%s\"", | 			"\3%d%s\3 leaves \3%d%s\3, \"%s\"", | ||||||
| 			color(user), nick, color(chan), chan, dequote(mesg) | 			color(user), nick, color(chan), chan, dequote(mesg) | ||||||
| 		); | 		); | ||||||
| 		logFmt(tag, NULL, "%s leaves %s, \"%s\"", nick, chan, dequote(mesg)); | 		logFmt(tag, NULL, "%s leaves %s, \"%s\"", nick, chan, dequote(mesg)); | ||||||
| 	} else { | 	} else { | ||||||
| 		uiFmt( | 		uiFmt( | ||||||
| 			tag, UI_COLD, | 			tag, UICold, | ||||||
| 			"\3%d%s\3 leaves \3%d%s\3", | 			"\3%d%s\3 leaves \3%d%s\3", | ||||||
| 			color(user), nick, color(chan), chan | 			color(user), nick, color(chan), chan | ||||||
| 		); | 		); | ||||||
| @ -212,7 +212,7 @@ static void handleKick(char *prefix, char *params) { | |||||||
| 	if (mesg) { | 	if (mesg) { | ||||||
| 		urlScan(tag, mesg); | 		urlScan(tag, mesg); | ||||||
| 		uiFmt( | 		uiFmt( | ||||||
| 			tag, (kicked ? UI_HOT : UI_COLD), | 			tag, (kicked ? UIHot : UICold), | ||||||
| 			"\3%d%s\3 kicks \3%d%s\3 out of \3%d%s\3, \"%s\"", | 			"\3%d%s\3 kicks \3%d%s\3 out of \3%d%s\3, \"%s\"", | ||||||
| 			color(user), nick, color(kick), kick, color(chan), chan, | 			color(user), nick, color(kick), kick, color(chan), chan, | ||||||
| 			dequote(mesg) | 			dequote(mesg) | ||||||
| @ -223,7 +223,7 @@ static void handleKick(char *prefix, char *params) { | |||||||
| 		); | 		); | ||||||
| 	} else { | 	} else { | ||||||
| 		uiFmt( | 		uiFmt( | ||||||
| 			tag, (kicked ? UI_HOT : UI_COLD), | 			tag, (kicked ? UIHot : UICold), | ||||||
| 			"\3%d%s\3 kicks \3%d%s\3 out of \3%d%s\3", | 			"\3%d%s\3 kicks \3%d%s\3 out of \3%d%s\3", | ||||||
| 			color(user), nick, color(kick), kick, color(chan), chan | 			color(user), nick, color(kick), kick, color(chan), chan | ||||||
| 		); | 		); | ||||||
| @ -236,19 +236,19 @@ static void handleQuit(char *prefix, char *params) { | |||||||
| 	shift(prefix, &nick, &user, NULL, params, 0, 1, &mesg); | 	shift(prefix, &nick, &user, NULL, params, 0, 1, &mesg); | ||||||
| 
 | 
 | ||||||
| 	struct Tag tag; | 	struct Tag tag; | ||||||
| 	while (TAG_NONE.id != (tag = tabTag(nick)).id) { | 	while (TagNone.id != (tag = tabTag(nick)).id) { | ||||||
| 		tabRemove(tag, nick); | 		tabRemove(tag, nick); | ||||||
| 
 | 
 | ||||||
| 		if (mesg) { | 		if (mesg) { | ||||||
| 			urlScan(tag, mesg); | 			urlScan(tag, mesg); | ||||||
| 			uiFmt( | 			uiFmt( | ||||||
| 				tag, UI_COLD, | 				tag, UICold, | ||||||
| 				"\3%d%s\3 leaves, \"%s\"", | 				"\3%d%s\3 leaves, \"%s\"", | ||||||
| 				color(user), nick, dequote(mesg) | 				color(user), nick, dequote(mesg) | ||||||
| 			); | 			); | ||||||
| 			logFmt(tag, NULL, "%s leaves, \"%s\"", nick, dequote(mesg)); | 			logFmt(tag, NULL, "%s leaves, \"%s\"", nick, dequote(mesg)); | ||||||
| 		} else { | 		} else { | ||||||
| 			uiFmt(tag, UI_COLD, "\3%d%s\3 leaves", color(user), nick); | 			uiFmt(tag, UICold, "\3%d%s\3 leaves", color(user), nick); | ||||||
| 			logFmt(tag, NULL, "%s leaves", nick); | 			logFmt(tag, NULL, "%s leaves", nick); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @ -262,7 +262,7 @@ static void handleReplyTopic(char *prefix, char *params) { | |||||||
| 	urlScan(tag, topic); | 	urlScan(tag, topic); | ||||||
| 	uiTopic(tag, topic); | 	uiTopic(tag, topic); | ||||||
| 	uiFmt( | 	uiFmt( | ||||||
| 		tag, UI_COLD, | 		tag, UICold, | ||||||
| 		"The sign in \3%d%s\3 reads, \"%s\"", | 		"The sign in \3%d%s\3 reads, \"%s\"", | ||||||
| 		color(chan), chan, topic | 		color(chan), chan, topic | ||||||
| 	); | 	); | ||||||
| @ -279,7 +279,7 @@ static void handleTopic(char *prefix, char *params) { | |||||||
| 	urlScan(tag, topic); | 	urlScan(tag, topic); | ||||||
| 	uiTopic(tag, topic); | 	uiTopic(tag, topic); | ||||||
| 	uiFmt( | 	uiFmt( | ||||||
| 		tag, UI_COLD, | 		tag, UICold, | ||||||
| 		"\3%d%s\3 places a new sign in \3%d%s\3, \"%s\"", | 		"\3%d%s\3 places a new sign in \3%d%s\3, \"%s\"", | ||||||
| 		color(user), nick, color(chan), chan, topic | 		color(user), nick, color(chan), chan, topic | ||||||
| 	); | 	); | ||||||
| @ -322,7 +322,7 @@ static void handleReplyEndOfWho(char *prefix, char *params) { | |||||||
| 	struct Tag tag = tagFor(chan); | 	struct Tag tag = tagFor(chan); | ||||||
| 
 | 
 | ||||||
| 	uiFmt( | 	uiFmt( | ||||||
| 		tag, UI_COLD, | 		tag, UICold, | ||||||
| 		"In \3%d%s\3 are %s", | 		"In \3%d%s\3 are %s", | ||||||
| 		color(chan), chan, who.buf | 		color(chan), chan, who.buf | ||||||
| 	); | 	); | ||||||
| @ -336,11 +336,11 @@ static void handleNick(char *prefix, char *params) { | |||||||
| 	if (isSelf(prev, user)) selfNick(next); | 	if (isSelf(prev, user)) selfNick(next); | ||||||
| 
 | 
 | ||||||
| 	struct Tag tag; | 	struct Tag tag; | ||||||
| 	while (TAG_NONE.id != (tag = tabTag(prev)).id) { | 	while (TagNone.id != (tag = tabTag(prev)).id) { | ||||||
| 		tabReplace(tag, prev, next); | 		tabReplace(tag, prev, next); | ||||||
| 
 | 
 | ||||||
| 		uiFmt( | 		uiFmt( | ||||||
| 			tag, UI_COLD, | 			tag, UICold, | ||||||
| 			"\3%d%s\3 is now known as \3%d%s\3", | 			"\3%d%s\3 is now known as \3%d%s\3", | ||||||
| 			color(user), prev, color(user), next | 			color(user), prev, color(user), next | ||||||
| 		); | 		); | ||||||
| @ -360,7 +360,7 @@ static void handleCTCP(struct Tag tag, char *nick, char *user, char *mesg) { | |||||||
| 	urlScan(tag, params); | 	urlScan(tag, params); | ||||||
| 	bool ping = !self && isPing(params); | 	bool ping = !self && isPing(params); | ||||||
| 	uiFmt( | 	uiFmt( | ||||||
| 		tag, (ping ? UI_HOT : UI_WARM), | 		tag, (ping ? UIHot : UIWarm), | ||||||
| 		"%c\3%d* %s\17 %s", | 		"%c\3%d* %s\17 %s", | ||||||
| 		ping["\17\26"], color(user), nick, params | 		ping["\17\26"], color(user), nick, params | ||||||
| 	); | 	); | ||||||
| @ -383,7 +383,7 @@ static void handlePrivmsg(char *prefix, char *params) { | |||||||
| 	urlScan(tag, mesg); | 	urlScan(tag, mesg); | ||||||
| 	bool ping = !self && (direct || isPing(mesg)); | 	bool ping = !self && (direct || isPing(mesg)); | ||||||
| 	uiFmt( | 	uiFmt( | ||||||
| 		tag, (ping ? UI_HOT : UI_WARM), | 		tag, (ping ? UIHot : UIWarm), | ||||||
| 		"%c\3%d%c%s%c\17 %s", | 		"%c\3%d%c%s%c\17 %s", | ||||||
| 		ping["\17\26"], color(user), self["<("], nick, self[">)"], mesg | 		ping["\17\26"], color(user), self["<("], nick, self[">)"], mesg | ||||||
| 	); | 	); | ||||||
| @ -393,7 +393,7 @@ static void handlePrivmsg(char *prefix, char *params) { | |||||||
| static void handleNotice(char *prefix, char *params) { | static void handleNotice(char *prefix, char *params) { | ||||||
| 	char *nick, *user, *chan, *mesg; | 	char *nick, *user, *chan, *mesg; | ||||||
| 	shift(prefix, &nick, &user, NULL, params, 2, 0, &chan, &mesg); | 	shift(prefix, &nick, &user, NULL, params, 2, 0, &chan, &mesg); | ||||||
| 	struct Tag tag = TAG_STATUS; | 	struct Tag tag = TagStatus; | ||||||
| 	if (user) tag = (strcmp(chan, self.nick) ? tagFor(chan) : tagFor(nick)); | 	if (user) tag = (strcmp(chan, self.nick) ? tagFor(chan) : tagFor(nick)); | ||||||
| 
 | 
 | ||||||
| 	bool self = isSelf(nick, user); | 	bool self = isSelf(nick, user); | ||||||
| @ -402,7 +402,7 @@ static void handleNotice(char *prefix, char *params) { | |||||||
| 	urlScan(tag, mesg); | 	urlScan(tag, mesg); | ||||||
| 	bool ping = !self && isPing(mesg); | 	bool ping = !self && isPing(mesg); | ||||||
| 	uiFmt( | 	uiFmt( | ||||||
| 		tag, (ping ? UI_HOT : UI_WARM), | 		tag, (ping ? UIHot : UIWarm), | ||||||
| 		"%c\3%d-%s-\17 %s", | 		"%c\3%d-%s-\17 %s", | ||||||
| 		ping["\17\26"], color(user), nick, mesg | 		ping["\17\26"], color(user), nick, mesg | ||||||
| 	); | 	); | ||||||
| @ -412,7 +412,7 @@ static void handleNotice(char *prefix, char *params) { | |||||||
| static const struct { | static const struct { | ||||||
| 	const char *command; | 	const char *command; | ||||||
| 	Handler handler; | 	Handler handler; | ||||||
| } HANDLERS[] = { | } Handlers[] = { | ||||||
| 	{ "001", handleReplyWelcome }, | 	{ "001", handleReplyWelcome }, | ||||||
| 	{ "315", handleReplyEndOfWho }, | 	{ "315", handleReplyEndOfWho }, | ||||||
| 	{ "332", handleReplyTopic }, | 	{ "332", handleReplyTopic }, | ||||||
| @ -432,7 +432,7 @@ static const struct { | |||||||
| 	{ "QUIT", handleQuit }, | 	{ "QUIT", handleQuit }, | ||||||
| 	{ "TOPIC", handleTopic }, | 	{ "TOPIC", handleTopic }, | ||||||
| }; | }; | ||||||
| static const size_t HANDLERS_LEN = sizeof(HANDLERS) / sizeof(HANDLERS[0]); | static const size_t HandlersLen = sizeof(Handlers) / sizeof(Handlers[0]); | ||||||
| 
 | 
 | ||||||
| void handle(char *line) { | void handle(char *line) { | ||||||
| 	char *prefix = NULL; | 	char *prefix = NULL; | ||||||
| @ -441,9 +441,9 @@ void handle(char *line) { | |||||||
| 		if (!line) errx(EX_PROTOCOL, "unexpected eol"); | 		if (!line) errx(EX_PROTOCOL, "unexpected eol"); | ||||||
| 	} | 	} | ||||||
| 	char *command = strsep(&line, " "); | 	char *command = strsep(&line, " "); | ||||||
| 	for (size_t i = 0; i < HANDLERS_LEN; ++i) { | 	for (size_t i = 0; i < HandlersLen; ++i) { | ||||||
| 		if (strcmp(command, HANDLERS[i].command)) continue; | 		if (strcmp(command, Handlers[i].command)) continue; | ||||||
| 		HANDLERS[i].handler(prefix, line); | 		Handlers[i].handler(prefix, line); | ||||||
| 		break; | 		break; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										34
									
								
								input.c
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								input.c
									
									
									
									
									
								
							| @ -40,7 +40,7 @@ static void privmsg(struct Tag tag, bool action, const char *mesg) { | |||||||
| static char *param(const char *command, char **params, const char *name) { | static char *param(const char *command, char **params, const char *name) { | ||||||
| 	char *param = strsep(params, " "); | 	char *param = strsep(params, " "); | ||||||
| 	if (param) return param; | 	if (param) return param; | ||||||
| 	uiFmt(TAG_STATUS, UI_WARM, "%s requires a %s", command, name); | 	uiFmt(TagStatus, UIHot, "%s requires a %s", command, name); | ||||||
| 	return NULL; | 	return NULL; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -76,7 +76,7 @@ static void inputQuery(struct Tag tag, char *params) { | |||||||
| 	(void)tag; | 	(void)tag; | ||||||
| 	char *nick = param("/query", ¶ms, "nick"); | 	char *nick = param("/query", ¶ms, "nick"); | ||||||
| 	if (!nick) return; | 	if (!nick) return; | ||||||
| 	tabTouch(TAG_NONE, nick); | 	tabTouch(TagNone, nick); | ||||||
| 	uiViewTag(tagFor(nick)); | 	uiViewTag(tagFor(nick)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -121,10 +121,10 @@ static void inputView(struct Tag tag, char *params) { | |||||||
| 		uiViewNum(num); | 		uiViewNum(num); | ||||||
| 	} else { | 	} else { | ||||||
| 		struct Tag tag = tagFind(view); | 		struct Tag tag = tagFind(view); | ||||||
| 		if (tag.id != TAG_NONE.id) { | 		if (tag.id != TagNone.id) { | ||||||
| 			uiViewTag(tag); | 			uiViewTag(tag); | ||||||
| 		} else { | 		} else { | ||||||
| 			uiFmt(TAG_STATUS, UI_WARM, "No view for %s", view); | 			uiFmt(TagStatus, UIHot, "No view for %s", view); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @ -132,13 +132,13 @@ static void inputView(struct Tag tag, char *params) { | |||||||
| static void inputClose(struct Tag tag, char *params) { | static void inputClose(struct Tag tag, char *params) { | ||||||
| 	(void)params; | 	(void)params; | ||||||
| 	uiCloseTag(tag); | 	uiCloseTag(tag); | ||||||
| 	tabRemove(TAG_NONE, tag.name); | 	tabRemove(TagNone, tag.name); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static const struct { | static const struct { | ||||||
| 	const char *command; | 	const char *command; | ||||||
| 	Handler handler; | 	Handler handler; | ||||||
| } COMMANDS[] = { | } Commands[] = { | ||||||
| 	{ "/close", inputClose }, | 	{ "/close", inputClose }, | ||||||
| 	{ "/join", inputJoin }, | 	{ "/join", inputJoin }, | ||||||
| 	{ "/me", inputMe }, | 	{ "/me", inputMe }, | ||||||
| @ -153,7 +153,7 @@ static const struct { | |||||||
| 	{ "/view", inputView }, | 	{ "/view", inputView }, | ||||||
| 	{ "/who", inputWho }, | 	{ "/who", inputWho }, | ||||||
| }; | }; | ||||||
| static const size_t COMMANDS_LEN = sizeof(COMMANDS) / sizeof(COMMANDS[0]); | static const size_t CommandsLen = sizeof(Commands) / sizeof(Commands[0]); | ||||||
| 
 | 
 | ||||||
| void input(struct Tag tag, char *input) { | void input(struct Tag tag, char *input) { | ||||||
| 	bool slash = (input[0] == '/'); | 	bool slash = (input[0] == '/'); | ||||||
| @ -164,9 +164,9 @@ void input(struct Tag tag, char *input) { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (!slash) { | 	if (!slash) { | ||||||
| 		if (tag.id == TAG_VERBOSE.id) { | 		if (tag.id == TagVerbose.id) { | ||||||
| 			ircFmt("%s\r\n", input); | 			ircFmt("%s\r\n", input); | ||||||
| 		} else if (tag.id != TAG_STATUS.id) { | 		} else if (tag.id != TagStatus.id) { | ||||||
| 			privmsg(tag, false, input); | 			privmsg(tag, false, input); | ||||||
| 		} | 		} | ||||||
| 		return; | 		return; | ||||||
| @ -183,24 +183,24 @@ void input(struct Tag tag, char *input) { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	const char *command = word; | 	const char *command = word; | ||||||
| 	const char *uniq = tabNext(TAG_NONE, command); | 	const char *uniq = tabNext(TagNone, command); | ||||||
| 	if (uniq && uniq == tabNext(TAG_NONE, command)) { | 	if (uniq && uniq == tabNext(TagNone, command)) { | ||||||
| 		command = uniq; | 		command = uniq; | ||||||
| 		tabAccept(); | 		tabAccept(); | ||||||
| 	} else { | 	} else { | ||||||
| 		tabReject(); | 		tabReject(); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	for (size_t i = 0; i < COMMANDS_LEN; ++i) { | 	for (size_t i = 0; i < CommandsLen; ++i) { | ||||||
| 		if (strcasecmp(command, COMMANDS[i].command)) continue; | 		if (strcasecmp(command, Commands[i].command)) continue; | ||||||
| 		COMMANDS[i].handler(tag, input); | 		Commands[i].handler(tag, input); | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 	uiFmt(TAG_STATUS, UI_WARM, "%s isn't a recognized command", command); | 	uiFmt(TagStatus, UIHot, "%s isn't a recognized command", command); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void inputTab(void) { | void inputTab(void) { | ||||||
| 	for (size_t i = 0; i < COMMANDS_LEN; ++i) { | 	for (size_t i = 0; i < CommandsLen; ++i) { | ||||||
| 		tabTouch(TAG_NONE, COMMANDS[i].command); | 		tabTouch(TagNone, Commands[i].command); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										8
									
								
								irc.c
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								irc.c
									
									
									
									
									
								
							| @ -108,8 +108,8 @@ void ircFmt(const char *format, ...) { | |||||||
| 	if (!buf) err(EX_OSERR, "vasprintf"); | 	if (!buf) err(EX_OSERR, "vasprintf"); | ||||||
| 	if (self.verbose) { | 	if (self.verbose) { | ||||||
| 		uiFmt( | 		uiFmt( | ||||||
| 			TAG_VERBOSE, UI_COLD, | 			TagVerbose, UICold, | ||||||
| 			"\3%d<<<\3 %.*s", IRC_WHITE, len - 2, buf | 			"\3%d<<<\3 %.*s", IRCWhite, len - 2, buf | ||||||
| 		); | 		); | ||||||
| 	} | 	} | ||||||
| 	ircWrite(buf, len); | 	ircWrite(buf, len); | ||||||
| @ -133,8 +133,8 @@ void ircRead(void) { | |||||||
| 		crlf[0] = '\0'; | 		crlf[0] = '\0'; | ||||||
| 		if (self.verbose) { | 		if (self.verbose) { | ||||||
| 			uiFmt( | 			uiFmt( | ||||||
| 				TAG_VERBOSE, UI_COLD, | 				TagVerbose, UICold, | ||||||
| 				"\3%d>>>\3 %s", IRC_GRAY, line | 				"\3%d>>>\3 %s", IRCGray, line | ||||||
| 			); | 			); | ||||||
| 		} | 		} | ||||||
| 		handle(line); | 		handle(line); | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								log.c
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								log.c
									
									
									
									
									
								
							| @ -34,7 +34,7 @@ static struct Log { | |||||||
| 	int month; | 	int month; | ||||||
| 	int day; | 	int day; | ||||||
| 	FILE *file; | 	FILE *file; | ||||||
| } logs[TAGS_LEN]; | } logs[TagsLen]; | ||||||
| 
 | 
 | ||||||
| void logOpen(const char *path) { | void logOpen(const char *path) { | ||||||
| 	logRoot = open(path, O_RDONLY | O_CLOEXEC); | 	logRoot = open(path, O_RDONLY | O_CLOEXEC); | ||||||
|  | |||||||
							
								
								
									
										4
									
								
								tab.c
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								tab.c
									
									
									
									
									
								
							| @ -121,14 +121,14 @@ struct Tag tabTag(const char *word) { | |||||||
| 		return entry->tag; | 		return entry->tag; | ||||||
| 	} | 	} | ||||||
| 	iter = NULL; | 	iter = NULL; | ||||||
| 	return TAG_NONE; | 	return TagNone; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const char *tabNext(struct Tag tag, const char *prefix) { | const char *tabNext(struct Tag tag, const char *prefix) { | ||||||
| 	size_t len = strlen(prefix); | 	size_t len = strlen(prefix); | ||||||
| 	struct Entry *start = (iter ? iter->next : head); | 	struct Entry *start = (iter ? iter->next : head); | ||||||
| 	for (struct Entry *entry = start; entry; entry = entry->next) { | 	for (struct Entry *entry = start; entry; entry = entry->next) { | ||||||
| 		if (entry->tag.id != TAG_NONE.id && entry->tag.id != tag.id) continue; | 		if (entry->tag.id != TagNone.id && entry->tag.id != tag.id) continue; | ||||||
| 		if (strncasecmp(entry->word, prefix, len)) continue; | 		if (strncasecmp(entry->word, prefix, len)) continue; | ||||||
| 		iter = entry; | 		iter = entry; | ||||||
| 		return entry->word; | 		return entry->word; | ||||||
|  | |||||||
							
								
								
									
										14
									
								
								tag.c
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								tag.c
									
									
									
									
									
								
							| @ -21,12 +21,12 @@ | |||||||
| 
 | 
 | ||||||
| #include "chat.h" | #include "chat.h" | ||||||
| 
 | 
 | ||||||
| const struct Tag TAG_NONE    = { 0, "" }; | const struct Tag TagNone    = { 0, "" }; | ||||||
| const struct Tag TAG_STATUS  = { 1, "(status)" }; | const struct Tag TagStatus  = { 1, "(status)" }; | ||||||
| const struct Tag TAG_VERBOSE = { 2, "(irc)" }; | const struct Tag TagVerbose = { 2, "(irc)" }; | ||||||
| 
 | 
 | ||||||
| static struct { | static struct { | ||||||
| 	char *name[TAGS_LEN]; | 	char *name[TagsLen]; | ||||||
| 	size_t len; | 	size_t len; | ||||||
| } tags = { | } tags = { | ||||||
| 	.name = { "", "(status)", "(irc)" }, | 	.name = { "", "(status)", "(irc)" }, | ||||||
| @ -42,13 +42,13 @@ struct Tag tagFind(const char *name) { | |||||||
| 		if (strcmp(tags.name[id], name)) continue; | 		if (strcmp(tags.name[id], name)) continue; | ||||||
| 		return Tag(id); | 		return Tag(id); | ||||||
| 	} | 	} | ||||||
| 	return TAG_NONE; | 	return TagNone; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct Tag tagFor(const char *name) { | struct Tag tagFor(const char *name) { | ||||||
| 	struct Tag tag = tagFind(name); | 	struct Tag tag = tagFind(name); | ||||||
| 	if (tag.id != TAG_NONE.id) return tag; | 	if (tag.id != TagNone.id) return tag; | ||||||
| 	if (tags.len == TAGS_LEN) return TAG_STATUS; | 	if (tags.len == TagsLen) return TagStatus; | ||||||
| 	size_t id = tags.len++; | 	size_t id = tags.len++; | ||||||
| 	tags.name[id] = strdup(name); | 	tags.name[id] = strdup(name); | ||||||
| 	if (!tags.name[id]) err(EX_OSERR, "strdup"); | 	if (!tags.name[id]) err(EX_OSERR, "strdup"); | ||||||
|  | |||||||
							
								
								
									
										17
									
								
								term.c
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								term.c
									
									
									
									
									
								
							| @ -42,27 +42,28 @@ static void privateMode(const char *mode, bool set) { | |||||||
| 
 | 
 | ||||||
| void termMode(enum TermMode mode, bool set) { | void termMode(enum TermMode mode, bool set) { | ||||||
| 	switch (mode) { | 	switch (mode) { | ||||||
| 		break; case TERM_FOCUS: privateMode("1004", set); | 		break; case TermFocus: privateMode("1004", set); | ||||||
| 		break; case TERM_PASTE: privateMode("2004", set); | 		break; case TermPaste: privateMode("2004", set); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #define ESC '\33' |  | ||||||
| #define T(s, i) ((s) << 8 | (i)) | #define T(s, i) ((s) << 8 | (i)) | ||||||
| 
 | 
 | ||||||
|  | enum { Esc = '\33' }; | ||||||
|  | 
 | ||||||
| enum TermEvent termEvent(char ch) { | enum TermEvent termEvent(char ch) { | ||||||
| 	static int state = 0; | 	static int state = 0; | ||||||
| 	switch (T(state, ch)) { | 	switch (T(state, ch)) { | ||||||
| 		case T(0, ESC): state = 1; return 0; | 		case T(0, Esc): state = 1; return 0; | ||||||
| 		case T(1, '['): state = 2; return 0; | 		case T(1, '['): state = 2; return 0; | ||||||
| 		case T(2, 'I'): state = 0; return TERM_FOCUS_IN; | 		case T(2, 'I'): state = 0; return TermFocusIn; | ||||||
| 		case T(2, 'O'): state = 0; return TERM_FOCUS_OUT; | 		case T(2, 'O'): state = 0; return TermFocusOut; | ||||||
| 		case T(2, '2'): state = 3; return 0; | 		case T(2, '2'): state = 3; return 0; | ||||||
| 		case T(3, '0'): state = 4; return 0; | 		case T(3, '0'): state = 4; return 0; | ||||||
| 		case T(4, '0'): state = 5; return 0; | 		case T(4, '0'): state = 5; return 0; | ||||||
| 		case T(5, '~'): state = 0; return TERM_PASTE_START; | 		case T(5, '~'): state = 0; return TermPasteStart; | ||||||
| 		case T(4, '1'): state = 6; return 0; | 		case T(4, '1'): state = 6; return 0; | ||||||
| 		case T(6, '~'): state = 0; return TERM_PASTE_END; | 		case T(6, '~'): state = 0; return TermPasteEnd; | ||||||
| 		default:        state = 0; return 0; | 		default:        state = 0; return 0; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										181
									
								
								ui.c
									
									
									
									
									
								
							
							
						
						
									
										181
									
								
								ui.c
									
									
									
									
									
								
							| @ -85,7 +85,7 @@ struct View { | |||||||
| static struct { | static struct { | ||||||
| 	struct View *head; | 	struct View *head; | ||||||
| 	struct View *tail; | 	struct View *tail; | ||||||
| 	struct View *tags[TAGS_LEN]; | 	struct View *tags[TagsLen]; | ||||||
| } views; | } views; | ||||||
| 
 | 
 | ||||||
| static void viewAppend(struct View *view) { | static void viewAppend(struct View *view) { | ||||||
| @ -105,13 +105,13 @@ static void viewRemove(struct View *view) { | |||||||
| 	views.tags[view->tag.id] = NULL; | 	views.tags[view->tag.id] = NULL; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static const int LOG_LINES = 256; | static const int LogLines = 256; | ||||||
| 
 | 
 | ||||||
| static int logHeight(const struct View *view) { | static int logHeight(const struct View *view) { | ||||||
| 	return LINES - (view->topic ? 2 : 0) - 2; | 	return LINES - (view->topic ? 2 : 0) - 2; | ||||||
| } | } | ||||||
| static int lastLogLine(void) { | static int lastLogLine(void) { | ||||||
| 	return LOG_LINES - 1; | 	return LogLines - 1; | ||||||
| } | } | ||||||
| static int lastLine(void) { | static int lastLine(void) { | ||||||
| 	return LINES - 1; | 	return LINES - 1; | ||||||
| @ -128,11 +128,11 @@ static struct View *viewTag(struct Tag tag) { | |||||||
| 	if (!view) err(EX_OSERR, "calloc"); | 	if (!view) err(EX_OSERR, "calloc"); | ||||||
| 
 | 
 | ||||||
| 	view->tag = tag; | 	view->tag = tag; | ||||||
| 	view->log = newpad(LOG_LINES, COLS); | 	view->log = newpad(LogLines, COLS); | ||||||
| 	wsetscrreg(view->log, 0, lastLogLine()); | 	wsetscrreg(view->log, 0, lastLogLine()); | ||||||
| 	scrollok(view->log, true); | 	scrollok(view->log, true); | ||||||
| 	wmove(view->log, lastLogLine() - logHeight(view) + 2, 0); | 	wmove(view->log, lastLogLine() - logHeight(view) + 2, 0); | ||||||
| 	view->scroll = LOG_LINES; | 	view->scroll = LogLines; | ||||||
| 	view->mark = true; | 	view->mark = true; | ||||||
| 
 | 
 | ||||||
| 	viewAppend(view); | 	viewAppend(view); | ||||||
| @ -141,7 +141,7 @@ static struct View *viewTag(struct Tag tag) { | |||||||
| 
 | 
 | ||||||
| static void viewResize(void) { | static void viewResize(void) { | ||||||
| 	for (struct View *view = views.head; view; view = view->next) { | 	for (struct View *view = views.head; view; view = view->next) { | ||||||
| 		wresize(view->log, LOG_LINES, COLS); | 		wresize(view->log, LogLines, COLS); | ||||||
| 		wmove(view->log, lastLogLine(), lastCol()); | 		wmove(view->log, lastLogLine(), lastCol()); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @ -162,8 +162,6 @@ static void viewUnmark(struct View *view) { | |||||||
| 	view->mark = false; | 	view->mark = false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static const int COLS_MAX = 512; |  | ||||||
| 
 |  | ||||||
| static struct { | static struct { | ||||||
| 	bool hide; | 	bool hide; | ||||||
| 	struct View *view; | 	struct View *view; | ||||||
| @ -173,12 +171,12 @@ static struct { | |||||||
| 
 | 
 | ||||||
| static void uiShow(void) { | static void uiShow(void) { | ||||||
| 	ui.hide = false; | 	ui.hide = false; | ||||||
| 	termMode(TERM_FOCUS, true); | 	termMode(TermFocus, true); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void uiHide(void) { | void uiHide(void) { | ||||||
| 	ui.hide = true; | 	ui.hide = true; | ||||||
| 	termMode(TERM_FOCUS, false); | 	termMode(TermFocus, false); | ||||||
| 	endwin(); | 	endwin(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -225,23 +223,23 @@ static void uiRedraw(void) { | |||||||
| 	clearok(curscr, true); | 	clearok(curscr, true); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static const short IRC_COLORS[] = { | static const short IRCColors[] = { | ||||||
| 	[IRC_WHITE]       = 8 + COLOR_WHITE, | 	[IRCWhite]      = 8 + COLOR_WHITE, | ||||||
| 	[IRC_BLACK]       = 0 + COLOR_BLACK, | 	[IRCBlack]      = 0 + COLOR_BLACK, | ||||||
| 	[IRC_BLUE]        = 0 + COLOR_BLUE, | 	[IRCBlue]       = 0 + COLOR_BLUE, | ||||||
| 	[IRC_GREEN]       = 0 + COLOR_GREEN, | 	[IRCGreen]      = 0 + COLOR_GREEN, | ||||||
| 	[IRC_RED]         = 8 + COLOR_RED, | 	[IRCRed]        = 8 + COLOR_RED, | ||||||
| 	[IRC_BROWN]       = 0 + COLOR_RED, | 	[IRCBrown]      = 0 + COLOR_RED, | ||||||
| 	[IRC_MAGENTA]     = 0 + COLOR_MAGENTA, | 	[IRCMagenta]    = 0 + COLOR_MAGENTA, | ||||||
| 	[IRC_ORANGE]      = 0 + COLOR_YELLOW, | 	[IRCOrange]     = 0 + COLOR_YELLOW, | ||||||
| 	[IRC_YELLOW]      = 8 + COLOR_YELLOW, | 	[IRCYellow]     = 8 + COLOR_YELLOW, | ||||||
| 	[IRC_LIGHT_GREEN] = 8 + COLOR_GREEN, | 	[IRCLightGreen] = 8 + COLOR_GREEN, | ||||||
| 	[IRC_CYAN]        = 0 + COLOR_CYAN, | 	[IRCCyan]       = 0 + COLOR_CYAN, | ||||||
| 	[IRC_LIGHT_CYAN]  = 8 + COLOR_CYAN, | 	[IRCLightCyan]  = 8 + COLOR_CYAN, | ||||||
| 	[IRC_LIGHT_BLUE]  = 8 + COLOR_BLUE, | 	[IRCLightBlue]  = 8 + COLOR_BLUE, | ||||||
| 	[IRC_PINK]        = 8 + COLOR_MAGENTA, | 	[IRCPink]       = 8 + COLOR_MAGENTA, | ||||||
| 	[IRC_GRAY]        = 8 + COLOR_BLACK, | 	[IRCGray]       = 8 + COLOR_BLACK, | ||||||
| 	[IRC_LIGHT_GRAY]  = 0 + COLOR_WHITE, | 	[IRCLightGray]  = 0 + COLOR_WHITE, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static const wchar_t *parseColor(short *pair, const wchar_t *str) { | static const wchar_t *parseColor(short *pair, const wchar_t *str) { | ||||||
| @ -262,8 +260,8 @@ static const wchar_t *parseColor(short *pair, const wchar_t *str) { | |||||||
| 	if (bgLen) str = &str[1 + bgLen]; | 	if (bgLen) str = &str[1 + bgLen]; | ||||||
| 
 | 
 | ||||||
| 	if (*pair == -1) *pair = 0; | 	if (*pair == -1) *pair = 0; | ||||||
| 	*pair = (*pair & 0xF0) | IRC_COLORS[fg & 0x0F]; | 	*pair = (*pair & 0xF0) | IRCColors[fg & 0x0F]; | ||||||
| 	if (bgLen) *pair = (*pair & 0x0F) | (IRC_COLORS[bg & 0x0F] << 4); | 	if (bgLen) *pair = (*pair & 0x0F) | (IRCColors[bg & 0x0F] << 4); | ||||||
| 
 | 
 | ||||||
| 	return str; | 	return str; | ||||||
| } | } | ||||||
| @ -286,14 +284,14 @@ static void wordWrap(WINDOW *win, const wchar_t *str) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static const wchar_t IRC_CODES[] = { | static const wchar_t IRCCodes[] = { | ||||||
| 	L' ', | 	L' ', | ||||||
| 	IRC_BOLD, | 	IRCBold, | ||||||
| 	IRC_COLOR, | 	IRCColor, | ||||||
| 	IRC_REVERSE, | 	IRCReverse, | ||||||
| 	IRC_RESET, | 	IRCReset, | ||||||
| 	IRC_ITALIC, | 	IRCItalic, | ||||||
| 	IRC_UNDERLINE, | 	IRCUnderline, | ||||||
| 	L'\0', | 	L'\0', | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| @ -301,7 +299,7 @@ static void addIRC(WINDOW *win, const wchar_t *str) { | |||||||
| 	attr_t attr = A_NORMAL; | 	attr_t attr = A_NORMAL; | ||||||
| 	short pair = -1; | 	short pair = -1; | ||||||
| 	for (;;) { | 	for (;;) { | ||||||
| 		size_t cc = wcscspn(str, IRC_CODES); | 		size_t cc = wcscspn(str, IRCCodes); | ||||||
| 		wattr_set(win, attr | attr8(pair), 1 + pair8(pair), NULL); | 		wattr_set(win, attr | attr8(pair), 1 + pair8(pair), NULL); | ||||||
| 		waddnwstr(win, str, cc); | 		waddnwstr(win, str, cc); | ||||||
| 		if (!str[cc]) break; | 		if (!str[cc]) break; | ||||||
| @ -309,12 +307,12 @@ static void addIRC(WINDOW *win, const wchar_t *str) { | |||||||
| 		str = &str[cc]; | 		str = &str[cc]; | ||||||
| 		switch (*str++) { | 		switch (*str++) { | ||||||
| 			break; case L' ':          wordWrap(win, str); | 			break; case L' ':          wordWrap(win, str); | ||||||
| 			break; case IRC_BOLD:      attr ^= A_BOLD; | 			break; case IRCBold:      attr ^= A_BOLD; | ||||||
| 			break; case IRC_ITALIC:    attr ^= A_ITALIC; | 			break; case IRCItalic:    attr ^= A_ITALIC; | ||||||
| 			break; case IRC_UNDERLINE: attr ^= A_UNDERLINE; | 			break; case IRCUnderline: attr ^= A_UNDERLINE; | ||||||
| 			break; case IRC_REVERSE:   attr ^= A_REVERSE; | 			break; case IRCReverse:   attr ^= A_REVERSE; | ||||||
| 			break; case IRC_COLOR:     str = parseColor(&pair, str); | 			break; case IRCColor:     str = parseColor(&pair, str); | ||||||
| 			break; case IRC_RESET:     attr = A_NORMAL; pair = -1; | 			break; case IRCReset:     attr = A_NORMAL; pair = -1; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @ -327,13 +325,13 @@ static void uiStatus(void) { | |||||||
| 	int count = 0; | 	int count = 0; | ||||||
| 	for (const struct View *view = views.head; view; view = view->next, ++num) { | 	for (const struct View *view = views.head; view; view = view->next, ++num) { | ||||||
| 		if (!view->unread) continue; | 		if (!view->unread) continue; | ||||||
| 		bool status = (view->tag.id == TAG_STATUS.id); | 		bool status = (view->tag.id == TagStatus.id); | ||||||
| 
 | 
 | ||||||
| 		int unread; | 		int unread; | ||||||
| 		wchar_t *str; | 		wchar_t *str; | ||||||
| 		int len = aswprintf( | 		int len = aswprintf( | ||||||
| 			&str, L",\3%02d%d\3%s%s%n(%d)", | 			&str, L",\3%02d%d\3%s%s%n(%d)", | ||||||
| 			(view->hot ? IRC_YELLOW : IRC_WHITE), num, | 			(view->hot ? IRCYellow : IRCWhite), num, | ||||||
| 			&status[":"], (status ? "" : view->tag.name), | 			&status[":"], (status ? "" : view->tag.name), | ||||||
| 			&unread, view->unread | 			&unread, view->unread | ||||||
| 		); | 		); | ||||||
| @ -396,11 +394,13 @@ void uiViewNum(int num) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static const int ColsMax = 512; | ||||||
|  | 
 | ||||||
| void uiTopic(struct Tag tag, const char *topic) { | void uiTopic(struct Tag tag, const char *topic) { | ||||||
| 	struct View *view = viewTag(tag); | 	struct View *view = viewTag(tag); | ||||||
| 	if (!view->topic) { | 	if (!view->topic) { | ||||||
| 		view->topic = newpad(2, COLS_MAX); | 		view->topic = newpad(2, ColsMax); | ||||||
| 		mvwhline(view->topic, 1, 0, ACS_HLINE, COLS_MAX); | 		mvwhline(view->topic, 1, 0, ACS_HLINE, ColsMax); | ||||||
| 	} | 	} | ||||||
| 	wchar_t *wcs = ambstowcs(topic); | 	wchar_t *wcs = ambstowcs(topic); | ||||||
| 	if (!wcs) err(EX_DATAERR, "ambstowcs"); | 	if (!wcs) err(EX_DATAERR, "ambstowcs"); | ||||||
| @ -413,9 +413,9 @@ void uiTopic(struct Tag tag, const char *topic) { | |||||||
| void uiLog(struct Tag tag, enum UIHeat heat, const wchar_t *line) { | void uiLog(struct Tag tag, enum UIHeat heat, const wchar_t *line) { | ||||||
| 	struct View *view = viewTag(tag); | 	struct View *view = viewTag(tag); | ||||||
| 	waddch(view->log, '\n'); | 	waddch(view->log, '\n'); | ||||||
| 	if (view->mark && heat > UI_COLD) { | 	if (view->mark && heat > UICold) { | ||||||
| 		if (!view->unread++) waddch(view->log, '\n'); | 		if (!view->unread++) waddch(view->log, '\n'); | ||||||
| 		if (heat > UI_WARM) { | 		if (heat > UIWarm) { | ||||||
| 			view->hot = true; | 			view->hot = true; | ||||||
| 			beep(); // TODO: Notification.
 | 			beep(); // TODO: Notification.
 | ||||||
| 		} | 		} | ||||||
| @ -444,13 +444,13 @@ void uiInit(void) { | |||||||
| 	colorInit(); | 	colorInit(); | ||||||
| 	termInit(); | 	termInit(); | ||||||
| 
 | 
 | ||||||
| 	ui.status = newpad(1, COLS_MAX); | 	ui.status = newpad(1, ColsMax); | ||||||
| 	ui.input = newpad(1, COLS_MAX); | 	ui.input = newpad(1, ColsMax); | ||||||
| 	keypad(ui.input, true); | 	keypad(ui.input, true); | ||||||
| 	nodelay(ui.input, true); | 	nodelay(ui.input, true); | ||||||
| 
 | 
 | ||||||
| 	ui.view = viewTag(TAG_STATUS); | 	ui.view = viewTag(TagStatus); | ||||||
| 	uiViewTag(TAG_STATUS); | 	uiViewTag(TagStatus); | ||||||
| 	uiStatus(); | 	uiStatus(); | ||||||
| 	uiShow(); | 	uiShow(); | ||||||
| } | } | ||||||
| @ -466,13 +466,13 @@ void uiExit(void) { | |||||||
| static void logScrollUp(int lines) { | static void logScrollUp(int lines) { | ||||||
| 	int height = logHeight(ui.view); | 	int height = logHeight(ui.view); | ||||||
| 	if (ui.view->scroll == height) return; | 	if (ui.view->scroll == height) return; | ||||||
| 	if (ui.view->scroll == LOG_LINES) viewMark(ui.view); | 	if (ui.view->scroll == LogLines) viewMark(ui.view); | ||||||
| 	ui.view->scroll = MAX(ui.view->scroll - lines, height); | 	ui.view->scroll = MAX(ui.view->scroll - lines, height); | ||||||
| } | } | ||||||
| static void logScrollDown(int lines) { | static void logScrollDown(int lines) { | ||||||
| 	if (ui.view->scroll == LOG_LINES) return; | 	if (ui.view->scroll == LogLines) return; | ||||||
| 	ui.view->scroll = MIN(ui.view->scroll + lines, LOG_LINES); | 	ui.view->scroll = MIN(ui.view->scroll + lines, LogLines); | ||||||
| 	if (ui.view->scroll == LOG_LINES) viewUnmark(ui.view); | 	if (ui.view->scroll == LogLines) viewUnmark(ui.view); | ||||||
| } | } | ||||||
| static void logPageUp(void) { | static void logPageUp(void) { | ||||||
| 	logScrollUp(logHeight(ui.view) / 2); | 	logScrollUp(logHeight(ui.view) / 2); | ||||||
| @ -485,11 +485,14 @@ static bool keyChar(wchar_t ch) { | |||||||
| 	if (ch < 0200) { | 	if (ch < 0200) { | ||||||
| 		enum TermEvent event = termEvent((char)ch); | 		enum TermEvent event = termEvent((char)ch); | ||||||
| 		switch (event) { | 		switch (event) { | ||||||
| 			break; case TERM_FOCUS_IN:  viewUnmark(ui.view); | 			break; case TermFocusIn:  viewUnmark(ui.view); | ||||||
| 			break; case TERM_FOCUS_OUT: viewMark(ui.view); | 			break; case TermFocusOut: viewMark(ui.view); | ||||||
| 			break; default: {} | 			break; default: {} | ||||||
| 		} | 		} | ||||||
| 		if (event) return false; | 		if (event) { | ||||||
|  | 			uiStatus(); | ||||||
|  | 			return false; | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	static bool meta; | 	static bool meta; | ||||||
| @ -501,10 +504,10 @@ static bool keyChar(wchar_t ch) { | |||||||
| 	if (meta) { | 	if (meta) { | ||||||
| 		bool update = true; | 		bool update = true; | ||||||
| 		switch (ch) { | 		switch (ch) { | ||||||
| 			break; case L'b':  edit(ui.view->tag, EDIT_BACK_WORD, 0); | 			break; case L'b':  edit(ui.view->tag, EditBackWord, 0); | ||||||
| 			break; case L'f':  edit(ui.view->tag, EDIT_FORE_WORD, 0); | 			break; case L'f':  edit(ui.view->tag, EditForeWord, 0); | ||||||
| 			break; case L'\b': edit(ui.view->tag, EDIT_KILL_BACK_WORD, 0); | 			break; case L'\b': edit(ui.view->tag, EditKillBackWord, 0); | ||||||
| 			break; case L'd':  edit(ui.view->tag, EDIT_KILL_FORE_WORD, 0); | 			break; case L'd':  edit(ui.view->tag, EditKillForeWord, 0); | ||||||
| 			break; default: { | 			break; default: { | ||||||
| 				update = false; | 				update = false; | ||||||
| 				if (ch < L'0' || ch > L'9') break; | 				if (ch < L'0' || ch > L'9') break; | ||||||
| @ -519,29 +522,29 @@ static bool keyChar(wchar_t ch) { | |||||||
| 	switch (ch) { | 	switch (ch) { | ||||||
| 		break; case CTRL(L'L'): uiRedraw(); return false; | 		break; case CTRL(L'L'): uiRedraw(); return false; | ||||||
| 
 | 
 | ||||||
| 		break; case CTRL(L'A'): edit(ui.view->tag, EDIT_HOME, 0); | 		break; case CTRL(L'A'): edit(ui.view->tag, EditHome, 0); | ||||||
| 		break; case CTRL(L'B'): edit(ui.view->tag, EDIT_LEFT, 0); | 		break; case CTRL(L'B'): edit(ui.view->tag, EditLeft, 0); | ||||||
| 		break; case CTRL(L'D'): edit(ui.view->tag, EDIT_DELETE, 0); | 		break; case CTRL(L'D'): edit(ui.view->tag, EditDelete, 0); | ||||||
| 		break; case CTRL(L'E'): edit(ui.view->tag, EDIT_END, 0); | 		break; case CTRL(L'E'): edit(ui.view->tag, EditEnd, 0); | ||||||
| 		break; case CTRL(L'F'): edit(ui.view->tag, EDIT_RIGHT, 0); | 		break; case CTRL(L'F'): edit(ui.view->tag, EditRight, 0); | ||||||
| 		break; case CTRL(L'K'): edit(ui.view->tag, EDIT_KILL_LINE, 0); | 		break; case CTRL(L'K'): edit(ui.view->tag, EditKillLine, 0); | ||||||
| 		break; case CTRL(L'W'): edit(ui.view->tag, EDIT_KILL_BACK_WORD, 0); | 		break; case CTRL(L'W'): edit(ui.view->tag, EditKillBackWord, 0); | ||||||
| 
 | 
 | ||||||
| 		break; case CTRL(L'C'): edit(ui.view->tag, EDIT_INSERT, IRC_COLOR); | 		break; case CTRL(L'C'): edit(ui.view->tag, EditInsert, IRCColor); | ||||||
| 		break; case CTRL(L'N'): edit(ui.view->tag, EDIT_INSERT, IRC_RESET); | 		break; case CTRL(L'N'): edit(ui.view->tag, EditInsert, IRCReset); | ||||||
| 		break; case CTRL(L'O'): edit(ui.view->tag, EDIT_INSERT, IRC_BOLD); | 		break; case CTRL(L'O'): edit(ui.view->tag, EditInsert, IRCBold); | ||||||
| 		break; case CTRL(L'R'): edit(ui.view->tag, EDIT_INSERT, IRC_COLOR); | 		break; case CTRL(L'R'): edit(ui.view->tag, EditInsert, IRCColor); | ||||||
| 		break; case CTRL(L'T'): edit(ui.view->tag, EDIT_INSERT, IRC_ITALIC); | 		break; case CTRL(L'T'): edit(ui.view->tag, EditInsert, IRCItalic); | ||||||
| 		break; case CTRL(L'U'): edit(ui.view->tag, EDIT_INSERT, IRC_UNDERLINE); | 		break; case CTRL(L'U'): edit(ui.view->tag, EditInsert, IRCUnderline); | ||||||
| 		break; case CTRL(L'V'): edit(ui.view->tag, EDIT_INSERT, IRC_REVERSE); | 		break; case CTRL(L'V'): edit(ui.view->tag, EditInsert, IRCReverse); | ||||||
| 
 | 
 | ||||||
| 		break; case L'\b': edit(ui.view->tag, EDIT_BACKSPACE, 0); | 		break; case L'\b': edit(ui.view->tag, EditBackspace, 0); | ||||||
| 		break; case L'\t': edit(ui.view->tag, EDIT_COMPLETE, 0); | 		break; case L'\t': edit(ui.view->tag, EditComplete, 0); | ||||||
| 		break; case L'\n': edit(ui.view->tag, EDIT_ENTER, 0); | 		break; case L'\n': edit(ui.view->tag, EditEnter, 0); | ||||||
| 
 | 
 | ||||||
| 		break; default: { | 		break; default: { | ||||||
| 			if (!iswprint(ch)) return false; | 			if (!iswprint(ch)) return false; | ||||||
| 			edit(ui.view->tag, EDIT_INSERT, ch); | 			edit(ui.view->tag, EditInsert, ch); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	return true; | 	return true; | ||||||
| @ -554,13 +557,13 @@ static bool keyCode(wchar_t ch) { | |||||||
| 		break; case KEY_SRIGHT:    logScrollDown(1); return false; | 		break; case KEY_SRIGHT:    logScrollDown(1); return false; | ||||||
| 		break; case KEY_PPAGE:     logPageUp(); return false; | 		break; case KEY_PPAGE:     logPageUp(); return false; | ||||||
| 		break; case KEY_NPAGE:     logPageDown(); return false; | 		break; case KEY_NPAGE:     logPageDown(); return false; | ||||||
| 		break; case KEY_LEFT:      edit(ui.view->tag, EDIT_LEFT, 0); | 		break; case KEY_LEFT:      edit(ui.view->tag, EditLeft, 0); | ||||||
| 		break; case KEY_RIGHT:     edit(ui.view->tag, EDIT_RIGHT, 0); | 		break; case KEY_RIGHT:     edit(ui.view->tag, EditRight, 0); | ||||||
| 		break; case KEY_HOME:      edit(ui.view->tag, EDIT_HOME, 0); | 		break; case KEY_HOME:      edit(ui.view->tag, EditHome, 0); | ||||||
| 		break; case KEY_END:       edit(ui.view->tag, EDIT_END, 0); | 		break; case KEY_END:       edit(ui.view->tag, EditEnd, 0); | ||||||
| 		break; case KEY_DC:        edit(ui.view->tag, EDIT_DELETE, 0); | 		break; case KEY_DC:        edit(ui.view->tag, EditDelete, 0); | ||||||
| 		break; case KEY_BACKSPACE: edit(ui.view->tag, EDIT_BACKSPACE, 0); | 		break; case KEY_BACKSPACE: edit(ui.view->tag, EditBackspace, 0); | ||||||
| 		break; case KEY_ENTER:     edit(ui.view->tag, EDIT_ENTER, 0); | 		break; case KEY_ENTER:     edit(ui.view->tag, EditEnter, 0); | ||||||
| 	} | 	} | ||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										26
									
								
								url.c
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								url.c
									
									
									
									
									
								
							| @ -23,23 +23,23 @@ | |||||||
| 
 | 
 | ||||||
| #include "chat.h" | #include "chat.h" | ||||||
| 
 | 
 | ||||||
| static const char *SCHEMES[] = { | static const char *Schemes[] = { | ||||||
| 	"https:", | 	"https:", | ||||||
| 	"http:", | 	"http:", | ||||||
| 	"ftp:", | 	"ftp:", | ||||||
| }; | }; | ||||||
| static const size_t SCHEMES_LEN = sizeof(SCHEMES) / sizeof(SCHEMES[0]); | static const size_t SchemesLen = sizeof(Schemes) / sizeof(Schemes[0]); | ||||||
| 
 | 
 | ||||||
| struct Entry { | struct Entry { | ||||||
| 	size_t tag; | 	size_t tag; | ||||||
| 	char *url; | 	char *url; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| enum { RING_LEN = 32 }; | enum { RingLen = 32 }; | ||||||
| static_assert(!(RING_LEN & (RING_LEN - 1)), "power of two RING_LEN"); | static_assert(!(RingLen & (RingLen - 1)), "power of two RingLen"); | ||||||
| 
 | 
 | ||||||
| static struct { | static struct { | ||||||
| 	struct Entry buf[RING_LEN]; | 	struct Entry buf[RingLen]; | ||||||
| 	size_t end; | 	size_t end; | ||||||
| } ring; | } ring; | ||||||
| 
 | 
 | ||||||
| @ -48,14 +48,14 @@ static void push(struct Tag tag, const char *url, size_t len) { | |||||||
| 	ring.buf[ring.end].tag = tag.id; | 	ring.buf[ring.end].tag = tag.id; | ||||||
| 	ring.buf[ring.end].url = strndup(url, len); | 	ring.buf[ring.end].url = strndup(url, len); | ||||||
| 	if (!ring.buf[ring.end].url) err(EX_OSERR, "strndup"); | 	if (!ring.buf[ring.end].url) err(EX_OSERR, "strndup"); | ||||||
| 	ring.end = (ring.end + 1) & (RING_LEN - 1); | 	ring.end = (ring.end + 1) & (RingLen - 1); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void urlScan(struct Tag tag, const char *str) { | void urlScan(struct Tag tag, const char *str) { | ||||||
| 	while (str[0]) { | 	while (str[0]) { | ||||||
| 		size_t len = 1; | 		size_t len = 1; | ||||||
| 		for (size_t i = 0; i < SCHEMES_LEN; ++i) { | 		for (size_t i = 0; i < SchemesLen; ++i) { | ||||||
| 			if (strncmp(str, SCHEMES[i], strlen(SCHEMES[i]))) continue; | 			if (strncmp(str, Schemes[i], strlen(Schemes[i]))) continue; | ||||||
| 			len = strcspn(str, " >\""); | 			len = strcspn(str, " >\""); | ||||||
| 			push(tag, str, len); | 			push(tag, str, len); | ||||||
| 		} | 		} | ||||||
| @ -65,8 +65,8 @@ void urlScan(struct Tag tag, const char *str) { | |||||||
| 
 | 
 | ||||||
| void urlList(struct Tag tag) { | void urlList(struct Tag tag) { | ||||||
| 	uiHide(); | 	uiHide(); | ||||||
| 	for (size_t i = 0; i < RING_LEN; ++i) { | 	for (size_t i = 0; i < RingLen; ++i) { | ||||||
| 		struct Entry entry = ring.buf[(ring.end + i) & (RING_LEN - 1)]; | 		struct Entry entry = ring.buf[(ring.end + i) & (RingLen - 1)]; | ||||||
| 		if (!entry.url || entry.tag != tag.id) continue; | 		if (!entry.url || entry.tag != tag.id) continue; | ||||||
| 		printf("%s\n", entry.url); | 		printf("%s\n", entry.url); | ||||||
| 	} | 	} | ||||||
| @ -74,10 +74,10 @@ void urlList(struct Tag tag) { | |||||||
| 
 | 
 | ||||||
| void urlOpen(struct Tag tag, size_t at, size_t to) { | void urlOpen(struct Tag tag, size_t at, size_t to) { | ||||||
| 	size_t argc = 1; | 	size_t argc = 1; | ||||||
| 	char *argv[2 + RING_LEN] = { "open" }; | 	char *argv[2 + RingLen] = { "open" }; | ||||||
| 	size_t tagIndex = 0; | 	size_t tagIndex = 0; | ||||||
| 	for (size_t i = 0; i < RING_LEN; ++i) { | 	for (size_t i = 0; i < RingLen; ++i) { | ||||||
| 		struct Entry entry = ring.buf[(ring.end - i) & (RING_LEN - 1)]; | 		struct Entry entry = ring.buf[(ring.end - i) & (RingLen - 1)]; | ||||||
| 		if (!entry.url || entry.tag != tag.id) continue; | 		if (!entry.url || entry.tag != tag.id) continue; | ||||||
| 		if (tagIndex >= at && tagIndex < to) argv[argc++] = entry.url; | 		if (tagIndex >= at && tagIndex < to) argv[argc++] = entry.url; | ||||||
| 		tagIndex++; | 		tagIndex++; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user