diff options
| -rw-r--r-- | catgirl.1 | 2 | ||||
| -rw-r--r-- | chat.h | 1 | ||||
| -rw-r--r-- | edit.c | 26 | ||||
| -rw-r--r-- | ui.c | 7 | 
4 files changed, 30 insertions, 6 deletions
@@ -226,6 +226,8 @@ Delete to end of line.  Delete to beginning of line.  .It Ic C-w  Delete previous word. +.It Ic C-y +Paste previously deleted text.  .It Ic M-b  Move to previous word.  .It Ic M-d @@ -157,6 +157,7 @@ enum Edit {  	EditDeleteNext,  	EditDeletePrevWord,  	EditDeleteNextWord, +	EditPaste,  	EditInsert,  	EditComplete,  	EditEnter, @@ -16,6 +16,7 @@  #include <assert.h>  #include <limits.h> +#include <stdbool.h>  #include <stdio.h>  #include <stdlib.h>  #include <wchar.h> @@ -46,14 +47,24 @@ char *editBuffer(size_t *mbsPos) {  	return mbs;  } -static void reserve(size_t index, size_t count) { -	if (len + count > Cap) return; +static struct { +	wchar_t buf[Cap]; +	size_t len; +} cut; + +static bool reserve(size_t index, size_t count) { +	if (len + count > Cap) return false;  	memmove(&buf[index + count], &buf[index], sizeof(*buf) * (len - index));  	len += count; +	return true;  }  static void delete(size_t index, size_t count) {  	if (index + count > len) return; +	if (count > 1) { +		memcpy(cut.buf, &buf[index], sizeof(*buf) * count); +		cut.len = count; +	}  	memmove(  		&buf[index], &buf[index + count], sizeof(*buf) * (len - index - count)  	); @@ -163,10 +174,17 @@ void edit(size_t id, enum Edit op, wchar_t ch) {  			while (word < len && buf[word] != L' ') word++;  			delete(pos, word - pos);  		} +		break; case EditPaste: { +			if (reserve(pos, cut.len)) { +				memcpy(&buf[pos], cut.buf, sizeof(*buf) * cut.len); +				pos += cut.len; +			} +		}  		break; case EditInsert: { -			reserve(pos, 1); -			if (pos < Cap) buf[pos++] = ch; +			if (reserve(pos, 1)) { +				buf[pos++] = ch; +			}  		}  		break; case EditComplete: {  			tabComplete(id); @@ -166,12 +166,14 @@ void uiHide(void) {  	endwin();  } -static void disableFlowControl(void) { +// Gain use of C-q, C-s, C-z, C-y, C-o. +static void acquireKeys(void) {  	struct termios term;  	int error = tcgetattr(STDOUT_FILENO, &term);  	if (error) err(EX_OSERR, "tcgetattr");  	term.c_iflag &= ~IXON;  	term.c_cc[VSUSP] = _POSIX_VDISABLE; +	term.c_cc[VDSUSP] = _POSIX_VDISABLE;  	term.c_cc[VDISCARD] = _POSIX_VDISABLE;  	error = tcsetattr(STDOUT_FILENO, TCSADRAIN, &term);  	if (error) err(EX_OSERR, "tcsetattr"); @@ -212,7 +214,7 @@ void uiInit(void) {  	initscr();  	cbreak();  	noecho(); -	disableFlowControl(); +	acquireKeys();  	def_prog_mode();  	atexit(errExit);  	colorInit(); @@ -662,6 +664,7 @@ static void keyCtrl(wchar_t ch) {  		break; case L'L': clearok(curscr, true);  		break; case L'U': edit(id, EditDeleteHead, 0);  		break; case L'W': edit(id, EditDeletePrevWord, 0); +		break; case L'Y': edit(id, EditPaste, 0);  	}  }  | 
