Skip to content

Commit

Permalink
Accept wide chars in filter input (#1038)
Browse files Browse the repository at this point in the history
Notably this doesn't handle wcwidth!=1 or extended grapheme clusters, but you
can filter for your emoji process now.
  • Loading branch information
adsr committed Oct 16, 2022
1 parent 835c0dd commit b90a89e
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 5 deletions.
22 changes: 21 additions & 1 deletion FunctionBar.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,25 @@ int FunctionBar_draw(const FunctionBar* this) {
return FunctionBar_drawExtra(this, NULL, -1, false);
}

static size_t FunctionBar_displayWidth(const char *s) {
size_t slen = strlen(s);
size_t width = 0, i = 0;

mbtowc(NULL, 0, 0);

while (i < slen) {
wchar_t wch;
int mblen = mbtowc(&wch, s + i, slen - i);
if (mblen <= 0) {
return slen;
}
i += mblen;
width += wcwidth(wch);
}

return width;
}

int FunctionBar_drawExtra(const FunctionBar* this, const char* buffer, int attr, bool setCursor) {
int cursorX = 0;
attrset(CRT_colors[FUNCTION_BAR]);
Expand All @@ -113,7 +132,8 @@ int FunctionBar_drawExtra(const FunctionBar* this, const char* buffer, int attr,
attrset(attr);
}
mvaddstr(LINES - 1, x, buffer);
x += strlen(buffer);
x += FunctionBar_displayWidth(buffer);

cursorX = x;
}

Expand Down
26 changes: 23 additions & 3 deletions IncSet.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ in the source distribution for its full text.
#include "IncSet.h"

#include <ctype.h>
#include <string.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <wctype.h>

#include "CRT.h"
#include "ListItem.h"
Expand Down Expand Up @@ -155,6 +157,23 @@ static bool IncMode_find(const IncMode* mode, Panel* panel, IncMode_GetPanelValu
}
}

static int IncSet_backspaceLen(const char *s, size_t slen) {
size_t i = 0;
int mblen = 0;

mbtowc(NULL, 0, 0);

while (i < slen) {
mblen = mbtowc(NULL, s + i, slen - i);
if (mblen <= 0) {
return slen - i;
}
i += mblen;
}

return mblen;
}

bool IncSet_handleKey(IncSet* this, int ch, Panel* panel, IncMode_GetPanelValue getPanelValue, Vector* lines) {
if (ch == ERR)
return true;
Expand All @@ -169,7 +188,7 @@ bool IncSet_handleKey(IncSet* this, int ch, Panel* panel, IncMode_GetPanelValue

IncMode_find(mode, panel, getPanelValue, ch == KEY_F(3) ? 1 : -1);
doSearch = false;
} else if (0 < ch && ch < 255 && isprint((unsigned char)ch)) {
} else if (iswprint(Panel_getLastWkey())) {
if (mode->index < INCMODE_MAX) {
mode->buffer[mode->index] = (char) ch;
mode->index++;
Expand All @@ -183,8 +202,9 @@ bool IncSet_handleKey(IncSet* this, int ch, Panel* panel, IncMode_GetPanelValue
}
} else if (ch == KEY_BACKSPACE || ch == 127) {
if (mode->index > 0) {
mode->index--;
mode->index -= IncSet_backspaceLen(mode->buffer, mode->index);
mode->buffer[mode->index] = 0;

if (mode->isFilter) {
filterChanged = true;
if (mode->index == 0) {
Expand Down
39 changes: 38 additions & 1 deletion Panel.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ in the source distribution for its full text.

#include <assert.h>
#include <ctype.h>
#include <limits.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
Expand All @@ -22,6 +23,8 @@ in the source distribution for its full text.
#include "XUtils.h"


static wint_t last_wkey = 0;

const PanelClass Panel_class = {
.super = {
.extends = Class(Object),
Expand Down Expand Up @@ -503,5 +506,39 @@ int Panel_getCh(Panel* this) {
#ifdef HAVE_SET_ESCDELAY
set_escdelay(25);
#endif
return getch();

#ifdef HAVE_LIBNCURSESW
static char mbbuf[MB_LEN_MAX];
static size_t mbbuf_len = 0, mbbuf_i = 0;

if (mbbuf_i < mbbuf_len) {
return mbbuf[mbbuf_i++];
}

wint_t wkey;
int wchrv = get_wch(&wkey);
wchar_t wch = (wchar_t)wkey;

if (wchrv == OK) {
mbbuf_i = 0;
mbbuf_len = wcrtomb(mbbuf, wch, NULL);
if (mbbuf_len == (size_t)-1) {
mbbuf_len = 0;
return wkey;
}
last_wkey = wkey;
return mbbuf[mbbuf_i++];
} else if (wchrv == KEY_CODE_YES) {
last_wkey = 0;
return wch;
}

return ERR;
#else
return last_wkey = getch();
#endif
}

wint_t Panel_getLastWkey(void) {
return last_wkey;
}
3 changes: 3 additions & 0 deletions Panel.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ in the source distribution for its full text.

#include <assert.h>
#include <stdbool.h>
#include <wchar.h>

#include "CRT.h"
#include "FunctionBar.h"
Expand Down Expand Up @@ -140,4 +141,6 @@ HandlerResult Panel_selectByTyping(Panel* this, int ch);

int Panel_getCh(Panel* this);

wint_t Panel_getLastWkey(void);

#endif

0 comments on commit b90a89e

Please sign in to comment.