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