mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-09 09:09:03 -04:00
mbswidth -> ncstrwidth() #985
This commit is contained in:
parent
dab7247cdd
commit
4bb1f3fc85
1
NEWS.md
1
NEWS.md
@ -2,6 +2,7 @@ This document attempts to list user-visible changes and any major internal
|
||||
rearrangements of Notcurses.
|
||||
|
||||
* 1.7.3 (not yet released)
|
||||
* `mbswidth()` has been renamed `ncstrwidth()`.
|
||||
* The long-promised/dreaded Great Widget Review, normalizing behavior across
|
||||
all widgets, has been effected. Sorry, there was no getting around this
|
||||
one. Pretty much all widgets have slightly changed, because pretty much all
|
||||
|
@ -114,7 +114,7 @@ typedef struct cell {
|
||||
|
||||
**bool cell_bg_default_p(const cell* cl);**
|
||||
|
||||
**int mbswidth(const char* text)**;
|
||||
**int ncstrwidth(const char* text)**;
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
|
@ -17,7 +17,7 @@ notcurses_metric - fixed-width numeric output with metric suffixes
|
||||
#define PREFIXSTRLEN (PREFIXCOLUMNS + 1)
|
||||
#define IPREFIXSTRLEN (IPREFIXCOLUMNS + 1)
|
||||
#define BPREFIXSTRLEN (BPREFIXCOLUMNS + 1)
|
||||
#define NCMETRICFWIDTH(x, cols) ((int)(strlen(x) - mbswidth(x) + (cols)))
|
||||
#define NCMETRICFWIDTH(x, cols) ((int)(strlen(x) - ncstrwidth(x) + (cols)))
|
||||
#define PREFIXFMT(x) NCMETRICFWIDTH((x), PREFIXCOLUMNS), (x)
|
||||
#define IPREFIXFMT(x) NCMETRIXFWIDTH((x), IPREFIXCOLUMNS), (x)
|
||||
#define BPREFIXFMT(x) NCMETRICFWIDTH((x), BPREFIXCOLUMNS), (x)
|
||||
|
@ -85,7 +85,7 @@ typedef enum {
|
||||
|
||||
// Returns the number of columns occupied by a multibyte (UTF-8) string, or
|
||||
// -1 if a non-printable/illegal character is encountered.
|
||||
API int mbswidth(const char* mbs);
|
||||
API int ncstrwidth(const char* mbs);
|
||||
|
||||
// input functions like notcurses_getc() return ucs32-encoded char32_t. convert
|
||||
// a series of char32_t to utf8. result must be at least 4 bytes per input
|
||||
@ -2530,7 +2530,7 @@ API struct ncplane* nctablet_ncplane(struct nctablet* t);
|
||||
#define BPREFIXSTRLEN (BPREFIXCOLUMNS + 1) // Does not include a '\0' (xxxx.xxUi), i == prefix
|
||||
// Used as arguments to a variable field width (i.e. "%*s" -- these are the *).
|
||||
// We need this convoluted grotesquery to properly handle 'µ'.
|
||||
#define NCMETRICFWIDTH(x, cols) ((int)(strlen(x) - mbswidth(x) + (cols)))
|
||||
#define NCMETRICFWIDTH(x, cols) ((int)(strlen(x) - ncstrwidth(x) + (cols)))
|
||||
#define PREFIXFMT(x) NCMETRICFWIDTH((x), PREFIXCOLUMNS), (x)
|
||||
#define IPREFIXFMT(x) NCMETRIXFWIDTH((x), IPREFIXCOLUMNS), (x)
|
||||
#define BPREFIXFMT(x) NCMETRICFWIDTH((x), BPREFIXCOLUMNS), (x)
|
||||
|
@ -3508,8 +3508,8 @@ unicode7emoji2(struct ncplane* title, int y){
|
||||
|
||||
struct ncplane*
|
||||
makegroup(struct ncplane* title, int y, const char* emoji, const char* name){
|
||||
int cols = mbswidth(emoji);
|
||||
if(cols < 0){ // take a wild guess on mbswidth() error from old libcs, sigh.
|
||||
int cols = ncstrwidth(emoji);
|
||||
if(cols < 0){ // take a wild guess on ncstrwidth() error from old libcs, sigh.
|
||||
cols = strlen(emoji) * 3 / 5; // best by test
|
||||
}
|
||||
struct ncplane* n = mojiplane(title, y, 3 + cols / (planewidth - 12), name);
|
||||
|
@ -62,7 +62,7 @@ dup_menu_item(ncmenu_int_item* dst, const struct ncmenu_item* src){
|
||||
}
|
||||
sdup[n + mbbytes] = '\0';
|
||||
dst->shortdesc = sdup;
|
||||
dst->shortdesccols = mbswidth(dst->shortdesc);
|
||||
dst->shortdesccols = ncstrwidth(dst->shortdesc);
|
||||
return 0;
|
||||
#undef CTLMOD
|
||||
#undef ALTMOD
|
||||
@ -94,7 +94,7 @@ dup_menu_section(ncmenu_int_section* dst, const struct ncmenu_section* src){
|
||||
return -1;
|
||||
}
|
||||
gotitem = true;
|
||||
int cols = mbswidth(dst->items[i].desc);
|
||||
int cols = ncstrwidth(dst->items[i].desc);
|
||||
if(dst->items[i].shortdesc){
|
||||
cols += 2 + dst->items[i].shortdesccols; // two spaces minimum
|
||||
}
|
||||
@ -140,7 +140,7 @@ dup_menu_sections(ncmenu* ncm, const ncmenu_options* opts, int* totalwidth, int*
|
||||
int i;
|
||||
for(i = 0 ; i < opts->sectioncount ; ++i){
|
||||
if(opts->sections[i].name){
|
||||
int cols = mbswidth(opts->sections[i].name);
|
||||
int cols = ncstrwidth(opts->sections[i].name);
|
||||
if(rightaligned){ // FIXME handle more than one right-aligned section
|
||||
ncm->sections[i].xoff = -(cols + 2);
|
||||
}else{
|
||||
@ -212,14 +212,14 @@ section_x(const ncmenu* ncm, int x){
|
||||
if(x < pos){
|
||||
break;
|
||||
}
|
||||
if(x < pos + mbswidth(ncm->sections[i].name)){
|
||||
if(x < pos + ncstrwidth(ncm->sections[i].name)){
|
||||
return i;
|
||||
}
|
||||
}else{
|
||||
if(x < ncm->sections[i].xoff){
|
||||
break;
|
||||
}
|
||||
if(x < ncm->sections[i].xoff + mbswidth(ncm->sections[i].name)){
|
||||
if(x < ncm->sections[i].xoff + ncstrwidth(ncm->sections[i].name)){
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@ -274,7 +274,7 @@ write_header(ncmenu* ncm){ ncm->ncp->channels = ncm->headerchannels;
|
||||
}
|
||||
cell_release(ncm->ncp, &cl);
|
||||
}
|
||||
xoff += mbswidth(ncm->sections[i].name);
|
||||
xoff += ncstrwidth(ncm->sections[i].name);
|
||||
}
|
||||
}
|
||||
while(xoff < dimx){
|
||||
|
@ -2356,7 +2356,7 @@ int notcurses_ucs32_to_utf8(const char32_t* ucs32, unsigned ucs32count,
|
||||
return buflen;
|
||||
}
|
||||
|
||||
int mbswidth(const char* mbs){
|
||||
int ncstrwidth(const char* mbs){
|
||||
int cols = 0; // number of columns consumed thus far
|
||||
do{
|
||||
int thesecols, thesebytes;
|
||||
|
@ -178,7 +178,7 @@ int ncreader_move_down(ncreader* n){
|
||||
|
||||
// only writing can enlarge the textarea. movement can pan, but not enlarge.
|
||||
int ncreader_write_egc(ncreader* n, const char* egc){
|
||||
const int cols = mbswidth(egc);
|
||||
const int cols = ncstrwidth(egc);
|
||||
if(cols < 0){
|
||||
logerror(n->ncp->nc, "Fed illegal UTF-8 [%s]\n", egc);
|
||||
return -1;
|
||||
|
@ -253,11 +253,11 @@ ncselector* ncselector_create(ncplane* n, const ncselector_options* opts){
|
||||
goto freeitems;
|
||||
}
|
||||
ns->title = opts->title ? strdup(opts->title) : NULL;
|
||||
ns->titlecols = opts->title ? mbswidth(opts->title) : 0;
|
||||
ns->titlecols = opts->title ? ncstrwidth(opts->title) : 0;
|
||||
ns->secondary = opts->secondary ? strdup(opts->secondary) : NULL;
|
||||
ns->secondarycols = opts->secondary ? mbswidth(opts->secondary) : 0;
|
||||
ns->secondarycols = opts->secondary ? ncstrwidth(opts->secondary) : 0;
|
||||
ns->footer = opts->footer ? strdup(opts->footer) : NULL;
|
||||
ns->footercols = opts->footer ? mbswidth(opts->footer) : 0;
|
||||
ns->footercols = opts->footer ? ncstrwidth(opts->footer) : 0;
|
||||
ns->selected = opts->defidx;
|
||||
ns->longop = 0;
|
||||
if( (ns->maxdisplay = opts->maxdisplay) ){
|
||||
@ -286,12 +286,12 @@ ncselector* ncselector_create(ncplane* n, const ncselector_options* opts){
|
||||
}
|
||||
for(ns->itemcount = 0 ; ns->itemcount < itemcount ; ++ns->itemcount){
|
||||
const struct ncselector_item* src = &opts->items[ns->itemcount];
|
||||
int cols = mbswidth(src->option);
|
||||
int cols = ncstrwidth(src->option);
|
||||
ns->items[ns->itemcount].opcolumns = cols;
|
||||
if(cols > ns->longop){
|
||||
ns->longop = cols;
|
||||
}
|
||||
cols = mbswidth(src->desc);
|
||||
cols = ncstrwidth(src->desc);
|
||||
ns->items[ns->itemcount].desccolumns = cols;
|
||||
if(cols > ns->longdesc){
|
||||
ns->longdesc = cols;
|
||||
@ -337,12 +337,12 @@ int ncselector_additem(ncselector* n, const struct ncselector_item* item){
|
||||
n->items = items;
|
||||
n->items[n->itemcount].option = strdup(item->option);
|
||||
n->items[n->itemcount].desc = strdup(item->desc);
|
||||
int cols = mbswidth(item->option);
|
||||
int cols = ncstrwidth(item->option);
|
||||
n->items[n->itemcount].opcolumns = cols;
|
||||
if(cols > n->longop){
|
||||
n->longop = cols;
|
||||
}
|
||||
cols = mbswidth(item->desc);
|
||||
cols = ncstrwidth(item->desc);
|
||||
n->items[n->itemcount].desccolumns = cols;
|
||||
if(cols > n->longdesc){
|
||||
n->longdesc = cols;
|
||||
@ -376,11 +376,11 @@ int ncselector_delitem(ncselector* n, const char* item){
|
||||
found = true;
|
||||
--idx;
|
||||
}else{
|
||||
int cols = mbswidth(n->items[idx].option);
|
||||
int cols = ncstrwidth(n->items[idx].option);
|
||||
if(cols > maxop){
|
||||
maxop = cols;
|
||||
}
|
||||
cols = mbswidth(n->items[idx].desc);
|
||||
cols = ncstrwidth(n->items[idx].desc);
|
||||
if(cols > maxdesc){
|
||||
maxdesc = cols;
|
||||
}
|
||||
@ -841,11 +841,11 @@ ncmultiselector* ncmultiselector_create(ncplane* n, const ncmultiselector_option
|
||||
}
|
||||
ncmultiselector* ns = malloc(sizeof(*ns));
|
||||
ns->title = opts->title ? strdup(opts->title) : NULL;
|
||||
ns->titlecols = opts->title ? mbswidth(opts->title) : 0;
|
||||
ns->titlecols = opts->title ? ncstrwidth(opts->title) : 0;
|
||||
ns->secondary = opts->secondary ? strdup(opts->secondary) : NULL;
|
||||
ns->secondarycols = opts->secondary ? mbswidth(opts->secondary) : 0;
|
||||
ns->secondarycols = opts->secondary ? ncstrwidth(opts->secondary) : 0;
|
||||
ns->footer = opts->footer ? strdup(opts->footer) : NULL;
|
||||
ns->footercols = opts->footer ? mbswidth(opts->footer) : 0;
|
||||
ns->footercols = opts->footer ? ncstrwidth(opts->footer) : 0;
|
||||
ns->current = 0;
|
||||
ns->startdisp = 0;
|
||||
ns->longitem = 0;
|
||||
@ -866,11 +866,11 @@ ncmultiselector* ncmultiselector_create(ncplane* n, const ncmultiselector_option
|
||||
}
|
||||
for(ns->itemcount = 0 ; ns->itemcount < itemcount ; ++ns->itemcount){
|
||||
const struct ncmselector_item* src = &opts->items[ns->itemcount];
|
||||
int cols = mbswidth(src->option);
|
||||
int cols = ncstrwidth(src->option);
|
||||
if(cols > ns->longitem){
|
||||
ns->longitem = cols;
|
||||
}
|
||||
int cols2 = mbswidth(src->desc);
|
||||
int cols2 = ncstrwidth(src->desc);
|
||||
if(cols + cols2 > ns->longitem){
|
||||
ns->longitem = cols + cols2;
|
||||
}
|
||||
|
@ -42,21 +42,21 @@ TEST_CASE("Cell") {
|
||||
}
|
||||
|
||||
SUBCASE("MultibyteWidth") {
|
||||
CHECK(0 == mbswidth("")); // zero bytes, zero columns
|
||||
CHECK(0 == mbswidth("\x7")); // single byte, non-printable
|
||||
CHECK(1 == mbswidth(" ")); // single byte, one column
|
||||
CHECK(5 == mbswidth("abcde")); // single byte, one column
|
||||
CHECK(1 == mbswidth("µ")); // two bytes, one column
|
||||
CHECK(1 <= mbswidth("\xf0\x9f\xa6\xb2")); // four bytes, two columns
|
||||
CHECK(3 <= mbswidth("平仮名")); // nine bytes, six columns
|
||||
CHECK(1 == mbswidth("\ufdfd")); // three bytes, ? columns, wcwidth() returns 1
|
||||
CHECK(0 == ncstrwidth("")); // zero bytes, zero columns
|
||||
CHECK(0 == ncstrwidth("\x7")); // single byte, non-printable
|
||||
CHECK(1 == ncstrwidth(" ")); // single byte, one column
|
||||
CHECK(5 == ncstrwidth("abcde")); // single byte, one column
|
||||
CHECK(1 == ncstrwidth("µ")); // two bytes, one column
|
||||
CHECK(1 <= ncstrwidth("\xf0\x9f\xa6\xb2")); // four bytes, two columns
|
||||
CHECK(3 <= ncstrwidth("平仮名")); // nine bytes, six columns
|
||||
CHECK(1 == ncstrwidth("\ufdfd")); // three bytes, ? columns, wcwidth() returns 1
|
||||
}
|
||||
|
||||
// test combining characters and ZWJs
|
||||
SUBCASE("MultiglyphWidth") {
|
||||
CHECK(2 == mbswidth("\U0001F471"));
|
||||
CHECK(2 == mbswidth("\U0001F471\u200D"));
|
||||
CHECK(3 == mbswidth("\U0001F471\u200D\u2640")); // *not* a single EGC!
|
||||
CHECK(2 == ncstrwidth("\U0001F471"));
|
||||
CHECK(2 == ncstrwidth("\U0001F471\u200D"));
|
||||
CHECK(3 == ncstrwidth("\U0001F471\u200D\u2640")); // *not* a single EGC!
|
||||
}
|
||||
|
||||
SUBCASE("SetItalic") {
|
||||
|
@ -360,7 +360,7 @@ TEST_CASE("NCPlane") {
|
||||
REQUIRE(0 < u2);
|
||||
REQUIRE(strlen(w1) == u1);
|
||||
REQUIRE(strlen(w2) == u2);
|
||||
CHECK(mbswidth(w1) == 1 + cell_double_wide_p(&c1));
|
||||
CHECK(ncstrwidth(w1) == 1 + cell_double_wide_p(&c1));
|
||||
CHECK_FALSE(cell_double_wide_p(&c2));
|
||||
cell_release(n_, &c1);
|
||||
cell_release(n_, &c2);
|
||||
|
@ -126,13 +126,13 @@ TEST_CASE("Wide") {
|
||||
ncplane_at_yx_cell(n_, 0, 0, &c);
|
||||
CHECK(0 == strcmp(cell_extended_gcluster(n_, &c), FROG));
|
||||
ncplane_at_yx_cell(n_, 0, 1, &c);
|
||||
CHECK(mbswidth(FROG) == 1 + cell_double_wide_p(&c)); // should be wide
|
||||
CHECK(ncstrwidth(FROG) == 1 + cell_double_wide_p(&c)); // should be wide
|
||||
ncplane_at_yx_cell(n_, 0, 2, &c);
|
||||
CHECK(0 == strlen(cell_extended_gcluster(n_, &c))); // should be nothing
|
||||
ncplane_at_yx_cell(n_, 1, 0, &c);
|
||||
CHECK(0 == strcmp(cell_extended_gcluster(n_, &c), FROG));
|
||||
ncplane_at_yx_cell(n_, 1, 1, &c);
|
||||
CHECK(mbswidth(FROG) == 1 + cell_double_wide_p(&c)); //should be wide
|
||||
CHECK(ncstrwidth(FROG) == 1 + cell_double_wide_p(&c)); //should be wide
|
||||
ncplane_at_yx_cell(n_, 0, 2, &c);
|
||||
CHECK(0 == strlen(cell_extended_gcluster(n_, &c)));
|
||||
CHECK(0 == notcurses_render(nc_)); // should be nothing
|
||||
@ -160,7 +160,7 @@ TEST_CASE("Wide") {
|
||||
ncplane_at_yx_cell(n_, 0, 1, &c);
|
||||
CHECK(0 == strcmp(cell_extended_gcluster(n_, &c), SNAKE));
|
||||
ncplane_at_yx_cell(n_, 0, 2, &c);
|
||||
CHECK(mbswidth(SNAKE) == 1 + cell_double_wide_p(&c)); // should be wide
|
||||
CHECK(ncstrwidth(SNAKE) == 1 + cell_double_wide_p(&c)); // should be wide
|
||||
CHECK(0 == notcurses_render(nc_));
|
||||
}
|
||||
|
||||
@ -181,7 +181,7 @@ TEST_CASE("Wide") {
|
||||
CHECK(3 == x);
|
||||
cell c = CELL_TRIVIAL_INITIALIZER;
|
||||
ncplane_at_yx_cell(n_, 0, 0, &c);
|
||||
if(mbswidth(wbashedl) > 1){
|
||||
if(ncstrwidth(wbashedl) > 1){
|
||||
CHECK(0 == c.gcluster); // should be nothing
|
||||
}
|
||||
ncplane_at_yx_cell(n_, 0, 1, &c);
|
||||
@ -189,7 +189,7 @@ TEST_CASE("Wide") {
|
||||
ncplane_at_yx_cell(n_, 0, 2, &c);
|
||||
CHECK(0 == strcmp(cc, cell_extended_gcluster(n_, &c))); // should be 'X'
|
||||
ncplane_at_yx_cell(n_, 0, 3, &c);
|
||||
if(mbswidth(wbashedr) > 1){
|
||||
if(ncstrwidth(wbashedr) > 1){
|
||||
CHECK(0 == strlen(cell_extended_gcluster(n_, &c))); // should be nothing
|
||||
}
|
||||
CHECK(0 == notcurses_render(nc_));
|
||||
@ -213,13 +213,13 @@ TEST_CASE("Wide") {
|
||||
ncplane_at_yx_cell(n_, 0, 0, &c);
|
||||
CHECK(0 == strcmp(cell_extended_gcluster(n_, &c), SNAKE));
|
||||
ncplane_at_yx_cell(n_, 0, 1, &c);
|
||||
CHECK(mbswidth(SNAKE) == 1 + cell_double_wide_p(&c));
|
||||
CHECK(ncstrwidth(SNAKE) == 1 + cell_double_wide_p(&c));
|
||||
ncplane_at_yx_cell(n_, 0, 2, &c);
|
||||
CHECK(0 == strcmp(cc, cell_extended_gcluster(n_, &c))); // should be 'X'
|
||||
ncplane_at_yx_cell(n_, 0, 3, &c);
|
||||
CHECK(0 == strcmp(cell_extended_gcluster(n_, &c), SCORPION));
|
||||
ncplane_at_yx_cell(n_, 0, 4, &c);
|
||||
CHECK(mbswidth(SCORPION) == 1 + cell_double_wide_p(&c));
|
||||
CHECK(ncstrwidth(SCORPION) == 1 + cell_double_wide_p(&c));
|
||||
CHECK(0 == notcurses_render(nc_));
|
||||
}
|
||||
|
||||
@ -229,7 +229,7 @@ TEST_CASE("Wide") {
|
||||
int dimx, dimy;
|
||||
ncplane_dim_yx(n_, &dimy, &dimx);
|
||||
CHECK(0 == ncplane_rounded_box_sized(ncp, 0, 0, 3, 4, 0));
|
||||
CHECK(mbswidth(SCORPION) == ncplane_putegc_yx(ncp, 1, 1, SCORPION, nullptr));
|
||||
CHECK(ncstrwidth(SCORPION) == ncplane_putegc_yx(ncp, 1, 1, SCORPION, nullptr));
|
||||
CHECK(0 == notcurses_render(nc_));
|
||||
cell c = CELL_TRIVIAL_INITIALIZER;
|
||||
CHECK(0 < ncplane_at_yx_cell(ncp, 1, 0, &c));
|
||||
|
Loading…
x
Reference in New Issue
Block a user