From 2aa2005339750e64a587f6117ae21960e975e211 Mon Sep 17 00:00:00 2001 From: "C. McEnroe" Date: Sun, 9 Feb 2020 07:09:51 -0500 Subject: [PATCH] Add C-y This is weechat's binding for it. --- catgirl.1 | 2 ++ chat.h | 1 + edit.c | 26 ++++++++++++++++++++++---- ui.c | 7 +++++-- 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/catgirl.1 b/catgirl.1 index 752a9d2..2a3828d 100644 --- a/catgirl.1 +++ b/catgirl.1 @@ -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 diff --git a/chat.h b/chat.h index fc18b15..24360f0 100644 --- a/chat.h +++ b/chat.h @@ -157,6 +157,7 @@ enum Edit { EditDeleteNext, EditDeletePrevWord, EditDeleteNextWord, + EditPaste, EditInsert, EditComplete, EditEnter, diff --git a/edit.c b/edit.c index 47478ec..16fa910 100644 --- a/edit.c +++ b/edit.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -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); diff --git a/ui.c b/ui.c index 65b4760..d946854 100644 --- a/ui.c +++ b/ui.c @@ -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); } }