diff options
| author | C. McEnroe | 2020-03-30 14:56:26 -0400 | 
|---|---|---|
| committer | C. McEnroe | 2020-03-30 14:56:26 -0400 | 
| commit | a0dde10cb61ec2c320103a215172841de636bd03 (patch) | |
| tree | 182d9675f1ab3a0fff276f0d33c7b4246e463f13 | |
| parent | 407eaf9dbf8ed304cded894cbfcc6a563bc9f5bf (diff) | |
Add text macros
| -rw-r--r-- | catgirl.1 | 7 | ||||
| -rw-r--r-- | chat.c | 4 | ||||
| -rw-r--r-- | chat.h | 4 | ||||
| -rw-r--r-- | command.c | 2 | ||||
| -rw-r--r-- | edit.c | 52 | ||||
| -rw-r--r-- | ui.c | 1 | 
6 files changed, 61 insertions, 9 deletions
| @@ -1,4 +1,4 @@ -.Dd March 29, 2020 +.Dd March 30, 2020  .Dt CATGIRL 1  .Os  . @@ -392,6 +392,9 @@ Transpose characters.  Delete to beginning of line.  .It Ic C-w  Delete previous word. +.It Ic C-x +Expand a text macro beginning with +.Ql \e .  .It Ic C-y  Paste previously deleted text.  .It Ic M-Enter @@ -403,7 +406,7 @@ Delete next word.  .It Ic M-f  Move to next word.  .It Ic Tab -Complete nick, channel or command. +Complete nick, channel, command or macro.  .El  .  .Ss Window Keys @@ -201,7 +201,9 @@ int main(int argc, char *argv[]) {  	set(&network.name, host);  	set(&self.nick, "*"); -	commandComplete(); + +	editCompleteAdd(); +	commandCompleteAdd();  	FILE *certFile = NULL;  	FILE *privFile = NULL; @@ -198,7 +198,7 @@ void command(uint id, char *input);  const char *commandIsPrivmsg(uint id, const char *input);  const char *commandIsNotice(uint id, const char *input);  const char *commandIsAction(uint id, const char *input); -void commandComplete(void); +void commandCompleteAdd(void);  enum Heat { Cold, Warm, Hot };  extern struct Util uiNotifyUtil; @@ -236,10 +236,12 @@ enum Edit {  	EditTranspose,  	EditInsert,  	EditComplete, +	EditExpand,  	EditEnter,  };  void edit(uint id, enum Edit op, wchar_t ch);  char *editBuffer(size_t *pos); +void editCompleteAdd(void);  const char *complete(uint id, const char *prefix);  void completeAccept(void); @@ -505,7 +505,7 @@ void command(uint id, char *input) {  	handler->fn(id, input);  } -void commandComplete(void) { +void commandCompleteAdd(void) {  	for (size_t i = 0; i < ARRAY_LEN(Commands); ++i) {  		completeAdd(None, Commands[i].cmd, Default);  	} @@ -72,6 +72,42 @@ static void delete(bool copy, size_t index, size_t count) {  	len -= count;  } +static const struct { +	const wchar_t *name; +	const wchar_t *string; +} Macros[] = { +	{ L"\\flip", L"(╯°□°)╯︵ ┻━┻" }, +	{ L"\\gary", L"ᕕ( ᐛ )ᕗ" }, +	{ L"\\lenny", L"( ͡° ͜ʖ ͡°)" }, +	{ L"\\look", L"ಠ_ಠ" }, +	{ L"\\shrug", L"¯\\_(ツ)_/¯" }, +}; + +void editCompleteAdd(void) { +	char mbs[256]; +	for (size_t i = 0; i < ARRAY_LEN(Macros); ++i) { +		size_t n = wcstombs(mbs, Macros[i].name, sizeof(mbs)); +		assert(n != (size_t)-1); +		completeAdd(None, mbs, Default); +	} +} + +static void macroExpand(void) { +	size_t macro = pos; +	while (macro && !iswspace(buf[macro - 1])) macro--; +	if (macro == pos) return; +	for (size_t i = 0; i < ARRAY_LEN(Macros); ++i) { +		if (wcsncmp(Macros[i].name, &buf[macro], pos - macro)) continue; +		delete(false, macro, pos - macro); +		pos = macro; +		size_t expand = wcslen(Macros[i].string); +		if (reserve(macro, expand)) { +			wcsncpy(&buf[macro], Macros[i].string, expand); +			pos += expand; +		} +	} +} +  static struct {  	size_t pos;  	size_t pre; @@ -110,21 +146,24 @@ static void tabComplete(uint id) {  	}  	delete(false, tab.pos, tab.len); -	if (wcs[0] != L'/' && !tab.pos) { -		tab.len = n + 2; +	tab.len = n; +	if (wcs[0] == L'\\') { +		reserve(tab.pos, tab.len); +	} else if (wcs[0] != L'/' && !tab.pos) { +		tab.len += 2;  		reserve(tab.pos, tab.len);  		buf[tab.pos + n + 0] = L':';  		buf[tab.pos + n + 1] = L' ';  	} else if (  		tab.pos >= 2 && (buf[tab.pos - 2] == L':' || buf[tab.pos - 2] == L',')  	) { -		tab.len = n + 2; +		tab.len += 2;  		reserve(tab.pos, tab.len);  		buf[tab.pos - 2] = L',';  		buf[tab.pos + n + 0] = L':';  		buf[tab.pos + n + 1] = L' ';  	} else { -		tab.len = n + 1; +		tab.len++;  		reserve(tab.pos, tab.len);  		buf[tab.pos + n] = L' ';  	} @@ -199,6 +238,11 @@ void edit(uint id, enum Edit op, wchar_t ch) {  			tabComplete(id);  			return;  		} +		break; case EditExpand: { +			macroExpand(); +			tabAccept(); +			return; +		}  		break; case EditEnter: {  			tabAccept();  			command(id, editBuffer(NULL)); @@ -917,6 +917,7 @@ static void keyCtrl(wchar_t ch) {  		break; case L'U': edit(id, EditDeleteHead, 0);  		break; case L'V': windowScroll(window, -(PAGE_LINES - 2));  		break; case L'W': edit(id, EditDeletePrevWord, 0); +		break; case L'X': edit(id, EditExpand, 0);  		break; case L'Y': edit(id, EditPaste, 0);  	}  } | 
