Use separate edit buffers for each ID

weechat-hashes
June McEnroe 2022-02-20 14:37:51 -05:00
parent 8065fcabc3
commit 012fd67539
1 changed files with 65 additions and 55 deletions

120
input.c
View File

@ -89,7 +89,7 @@ enum {
#undef X #undef X
}; };
static struct Edit edit; static struct Edit edits[IDCap];
void inputInit(void) { void inputInit(void) {
struct termios term; struct termios term;
@ -160,7 +160,7 @@ static char *inputStop(
void inputUpdate(void) { void inputUpdate(void) {
uint id = windowID(); uint id = windowID();
char *buf = editString(&edit); char *buf = editString(&edits[id]);
if (!buf) err(EX_OSERR, "editString"); if (!buf) err(EX_OSERR, "editString");
const char *prefix = ""; const char *prefix = "";
@ -192,7 +192,7 @@ void inputUpdate(void) {
} else { } else {
prompt = ""; prompt = "";
} }
if (skip > &buf[edit.mbs.pos]) { if (skip > &buf[edits[id].mbs.pos]) {
prefix = prompt = suffix = ""; prefix = prompt = suffix = "";
skip = buf; skip = buf;
} }
@ -211,7 +211,7 @@ void inputUpdate(void) {
int pos; int pos;
struct Style style = styleInput; struct Style style = styleInput;
inputStop(styleInput, &style, skip, &buf[edit.mbs.pos]); inputStop(styleInput, &style, skip, &buf[edits[id].mbs.pos]);
getyx(uiInput, y, pos); getyx(uiInput, y, pos);
wmove(uiInput, y, x); wmove(uiInput, y, x);
@ -276,14 +276,30 @@ static int macroExpand(struct Edit *e) {
} }
static struct { static struct {
uint id;
char *pre; char *pre;
size_t pos; size_t pos;
size_t len; size_t len;
bool suffix; bool suffix;
} tab; } tab;
static void tabAccept(void) {
completeAccept();
tab.len = 0;
}
static void tabReject(void) {
completeReject();
tab.len = 0;
}
static int tabComplete(struct Edit *e, uint id) { static int tabComplete(struct Edit *e, uint id) {
if (tab.len && id != tab.id) {
tabAccept();
}
if (!tab.len) { if (!tab.len) {
tab.id = id;
tab.pos = e->pos; tab.pos = e->pos;
while (tab.pos && !iswspace(e->buf[tab.pos-1])) tab.pos--; while (tab.pos && !iswspace(e->buf[tab.pos-1])) tab.pos--;
tab.len = e->pos - tab.pos; tab.len = e->pos - tab.pos;
@ -359,33 +375,25 @@ fail:
return -1; return -1;
} }
static void tabAccept(void) {
completeAccept();
tab.len = 0;
}
static void tabReject(void) {
completeReject();
tab.len = 0;
}
static void inputEnter(void) { static void inputEnter(void) {
char *cmd = editString(&edit); uint id = windowID();
char *cmd = editString(&edits[id]);
if (!cmd) err(EX_OSERR, "editString"); if (!cmd) err(EX_OSERR, "editString");
tabAccept(); tabAccept();
command(windowID(), cmd); command(id, cmd);
editFn(&edit, EditClear); editFn(&edits[id], EditClear);
} }
static void keyCode(int code) { static void keyCode(int code) {
int error = 0; int error = 0;
struct Edit *edit = &edits[windowID()];
switch (code) { switch (code) {
break; case KEY_RESIZE: uiResize(); break; case KEY_RESIZE: uiResize();
break; case KeyFocusIn: windowUnmark(); break; case KeyFocusIn: windowUnmark();
break; case KeyFocusOut: windowMark(); break; case KeyFocusOut: windowMark();
break; case KeyMetaEnter: error = editInsert(&edit, L'\n'); break; case KeyMetaEnter: error = editInsert(edit, L'\n');
break; case KeyMetaEqual: windowToggleMute(); break; case KeyMetaEqual: windowToggleMute();
break; case KeyMetaMinus: windowToggleThresh(-1); break; case KeyMetaMinus: windowToggleThresh(-1);
break; case KeyMetaPlus: windowToggleThresh(+1); break; case KeyMetaPlus: windowToggleThresh(+1);
@ -396,32 +404,32 @@ static void keyCode(int code) {
break; case KeyMeta0 ... KeyMeta9: windowShow(code - KeyMeta0); break; case KeyMeta0 ... KeyMeta9: windowShow(code - KeyMeta0);
break; case KeyMetaA: windowAuto(); break; case KeyMetaA: windowAuto();
break; case KeyMetaB: error = editFn(&edit, EditPrevWord); break; case KeyMetaB: error = editFn(edit, EditPrevWord);
break; case KeyMetaD: error = editFn(&edit, EditDeleteNextWord); break; case KeyMetaD: error = editFn(edit, EditDeleteNextWord);
break; case KeyMetaF: error = editFn(&edit, EditNextWord); break; case KeyMetaF: error = editFn(edit, EditNextWord);
break; case KeyMetaL: windowBare(); break; case KeyMetaL: windowBare();
break; case KeyMetaM: uiWrite(windowID(), Warm, NULL, ""); break; case KeyMetaM: uiWrite(windowID(), Warm, NULL, "");
break; case KeyMetaN: windowScroll(ScrollHot, +1); break; case KeyMetaN: windowScroll(ScrollHot, +1);
break; case KeyMetaP: windowScroll(ScrollHot, -1); break; case KeyMetaP: windowScroll(ScrollHot, -1);
break; case KeyMetaQ: error = editFn(&edit, EditCollapse); break; case KeyMetaQ: error = editFn(edit, EditCollapse);
break; case KeyMetaS: uiSpoilerReveal ^= true; windowUpdate(); break; case KeyMetaS: uiSpoilerReveal ^= true; windowUpdate();
break; case KeyMetaT: windowToggleTime(); break; case KeyMetaT: windowToggleTime();
break; case KeyMetaU: windowScroll(ScrollUnread, 0); break; case KeyMetaU: windowScroll(ScrollUnread, 0);
break; case KeyMetaV: windowScroll(ScrollPage, +1); break; case KeyMetaV: windowScroll(ScrollPage, +1);
break; case KeyCtrlLeft: error = editFn(&edit, EditPrevWord); break; case KeyCtrlLeft: error = editFn(edit, EditPrevWord);
break; case KeyCtrlRight: error = editFn(&edit, EditNextWord); break; case KeyCtrlRight: error = editFn(edit, EditNextWord);
break; case KEY_BACKSPACE: error = editFn(&edit, EditDeletePrev); break; case KEY_BACKSPACE: error = editFn(edit, EditDeletePrev);
break; case KEY_DC: error = editFn(&edit, EditDeleteNext); break; case KEY_DC: error = editFn(edit, EditDeleteNext);
break; case KEY_DOWN: windowScroll(ScrollOne, -1); break; case KEY_DOWN: windowScroll(ScrollOne, -1);
break; case KEY_END: error = editFn(&edit, EditTail); break; case KEY_END: error = editFn(edit, EditTail);
break; case KEY_ENTER: inputEnter(); break; case KEY_ENTER: inputEnter();
break; case KEY_HOME: error = editFn(&edit, EditHead); break; case KEY_HOME: error = editFn(edit, EditHead);
break; case KEY_LEFT: error = editFn(&edit, EditPrev); break; case KEY_LEFT: error = editFn(edit, EditPrev);
break; case KEY_NPAGE: windowScroll(ScrollPage, -1); break; case KEY_NPAGE: windowScroll(ScrollPage, -1);
break; case KEY_PPAGE: windowScroll(ScrollPage, +1); break; case KEY_PPAGE: windowScroll(ScrollPage, +1);
break; case KEY_RIGHT: error = editFn(&edit, EditNext); break; case KEY_RIGHT: error = editFn(edit, EditNext);
break; case KEY_SEND: windowScroll(ScrollAll, -1); break; case KEY_SEND: windowScroll(ScrollAll, -1);
break; case KEY_SHOME: windowScroll(ScrollAll, +1); break; case KEY_SHOME: windowScroll(ScrollAll, +1);
break; case KEY_UP: windowScroll(ScrollOne, +1); break; case KEY_UP: windowScroll(ScrollOne, +1);
@ -431,29 +439,30 @@ static void keyCode(int code) {
static void keyCtrl(wchar_t ch) { static void keyCtrl(wchar_t ch) {
int error = 0; int error = 0;
struct Edit *edit = &edits[windowID()];
switch (ch ^ L'@') { switch (ch ^ L'@') {
break; case L'?': error = editFn(&edit, EditDeletePrev); break; case L'?': error = editFn(edit, EditDeletePrev);
break; case L'A': error = editFn(&edit, EditHead); break; case L'A': error = editFn(edit, EditHead);
break; case L'B': error = editFn(&edit, EditPrev); break; case L'B': error = editFn(edit, EditPrev);
break; case L'C': raise(SIGINT); break; case L'C': raise(SIGINT);
break; case L'D': error = editFn(&edit, EditDeleteNext); break; case L'D': error = editFn(edit, EditDeleteNext);
break; case L'E': error = editFn(&edit, EditTail); break; case L'E': error = editFn(edit, EditTail);
break; case L'F': error = editFn(&edit, EditNext); break; case L'F': error = editFn(edit, EditNext);
break; case L'H': error = editFn(&edit, EditDeletePrev); break; case L'H': error = editFn(edit, EditDeletePrev);
break; case L'I': error = tabComplete(&edit, windowID()); break; case L'I': error = tabComplete(edit, windowID());
break; case L'J': inputEnter(); break; case L'J': inputEnter();
break; case L'K': error = editFn(&edit, EditDeleteTail); break; case L'K': error = editFn(edit, EditDeleteTail);
break; case L'L': clearok(curscr, true); break; case L'L': clearok(curscr, true);
break; case L'N': windowShow(windowNum() + 1); break; case L'N': windowShow(windowNum() + 1);
break; case L'P': windowShow(windowNum() - 1); break; case L'P': windowShow(windowNum() - 1);
break; case L'R': windowSearch(editString(&edit), -1); break; case L'R': windowSearch(editString(edit), -1);
break; case L'S': windowSearch(editString(&edit), +1); break; case L'S': windowSearch(editString(edit), +1);
break; case L'T': error = editFn(&edit, EditTranspose); break; case L'T': error = editFn(edit, EditTranspose);
break; case L'U': error = editFn(&edit, EditDeleteHead); break; case L'U': error = editFn(edit, EditDeleteHead);
break; case L'V': windowScroll(ScrollPage, -1); break; case L'V': windowScroll(ScrollPage, -1);
break; case L'W': error = editFn(&edit, EditDeletePrevWord); break; case L'W': error = editFn(edit, EditDeletePrevWord);
break; case L'X': error = macroExpand(&edit); tabAccept(); break; case L'X': error = macroExpand(edit); tabAccept();
break; case L'Y': error = editFn(&edit, EditPaste); break; case L'Y': error = editFn(edit, EditPaste);
} }
if (error) err(EX_OSERR, "editFn"); if (error) err(EX_OSERR, "editFn");
} }
@ -488,8 +497,9 @@ static void keyStyle(wchar_t ch) {
if (color != Default) { if (color != Default) {
snprintf(buf, sizeof(buf), "%c%02d", C, color); snprintf(buf, sizeof(buf), "%c%02d", C, color);
} }
struct Edit *edit = &edits[windowID()];
for (char *ch = buf; *ch; ++ch) { for (char *ch = buf; *ch; ++ch) {
int error = editInsert(&edit, *ch); int error = editInsert(edit, *ch);
if (error) err(EX_OSERR, "editInsert"); if (error) err(EX_OSERR, "editInsert");
} }
} }
@ -514,8 +524,8 @@ void inputRead(void) {
wint_t ch; wint_t ch;
static bool paste, style, literal; static bool paste, style, literal;
for (int ret; ERR != (ret = wget_wch(uiInput, &ch));) { for (int ret; ERR != (ret = wget_wch(uiInput, &ch));) {
bool tab = false; bool tabbing = false;
size_t pos = edit.pos; size_t pos = edits[tab.id].pos;
bool spr = uiSpoilerReveal; bool spr = uiSpoilerReveal;
if (ret == KEY_CODE_YES && ch == KeyPasteOn) { if (ret == KEY_CODE_YES && ch == KeyPasteOn) {
@ -525,7 +535,7 @@ void inputRead(void) {
} else if (ret == KEY_CODE_YES && ch == KeyPasteManual) { } else if (ret == KEY_CODE_YES && ch == KeyPasteManual) {
paste ^= true; paste ^= true;
} else if (paste || literal) { } else if (paste || literal) {
int error = editInsert(&edit, ch); int error = editInsert(&edits[windowID()], ch);
if (error) err(EX_OSERR, "editInsert"); if (error) err(EX_OSERR, "editInsert");
} else if (ret == KEY_CODE_YES) { } else if (ret == KEY_CODE_YES) {
keyCode(ch); keyCode(ch);
@ -538,19 +548,19 @@ void inputRead(void) {
} else if (style) { } else if (style) {
keyStyle(ch); keyStyle(ch);
} else if (iswcntrl(ch)) { } else if (iswcntrl(ch)) {
tab = (ch == (L'I' ^ L'@')); tabbing = (ch == (L'I' ^ L'@'));
keyCtrl(ch); keyCtrl(ch);
} else { } else {
int error = editInsert(&edit, ch); int error = editInsert(&edits[windowID()], ch);
if (error) err(EX_OSERR, "editInsert"); if (error) err(EX_OSERR, "editInsert");
} }
style = false; style = false;
literal = false; literal = false;
if (!tab) { if (!tabbing) {
if (edit.pos > pos) { if (edits[tab.id].pos > pos) {
tabAccept(); tabAccept();
} else if (edit.pos < pos) { } else if (edits[tab.id].pos < pos) {
tabReject(); tabReject();
} }
} }