ncreader: support ctrl-a and ctrl-e #983

This commit is contained in:
nick black 2020-11-07 05:39:26 -05:00
parent 67e7046956
commit 1b1d727169
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC
2 changed files with 47 additions and 15 deletions

View File

@ -8,6 +8,10 @@ rearrangements of Notcurses.
returned number of cells written, but since these are not directly
callable by the user, this ought not lead to any user-visible changes.
* Added (k)eller demo to `notcurses-demo`.
* `ncreader` now supports Alt+'b' to move one word back, Alt+'f' to move one
word forward, Ctrl+'A' to move to the beginning of the line, and Ctrl+'E'
to move to the end of the line (when `NCREADER_OPTION_NOCMDKEYS` is not
used).
* 2.0.2 (2020-10-25)
* Add `ncvisual_decode_loop()`, which returns to the first frame upon

View File

@ -122,7 +122,7 @@ int ncreader_move_right(ncreader* n){
//fprintf(stderr, "moving right: tcurs: %dx%d vcurs: %dx%d xproj: %d\n", y, textx, y, viewx, n->xproject);
if(textx >= n->textarea->lenx - 1){
// are we on the last column of the textarea? if so, we must also be on
// the first column of the viewarea. try to move up.
// the first column of the viewarea. try to move down.
if(y >= n->textarea->leny - 1){
return -1; // no move possible
}
@ -227,7 +227,19 @@ ncreader_ctrl_input(ncreader* n, const ncinput* ni){
case 'F':
ncreader_move_right(n);
break;
case 'A':
case 'A': // cursor to beginning of line
while(n->textarea->x){
if(ncreader_move_left(n)){
break;
}
}
break;
case 'E': // cursor to end of line
while(n->textarea->x < ncplane_dim_x(n->textarea) - 1){
if(ncreader_move_right(n)){
break;
}
}
break;
default:
return false; // pass on all other ctrls
@ -235,6 +247,25 @@ ncreader_ctrl_input(ncreader* n, const ncinput* ni){
return true;
}
static bool
is_egc_wordbreak(ncplane* textarea){
char* egc = ncplane_at_yx(textarea, textarea->y, textarea->x, NULL, NULL);
if(egc == NULL){
return true;
}
wchar_t w;
mbstate_t mbstate = {0};
size_t s = mbrtowc(&w, egc, MB_CUR_MAX, &mbstate);
free(egc);
if(s == (size_t)-1 || s == (size_t)-2){
return true;
}
if(iswordbreak(w)){
return true;
}
return false;
}
static bool
ncreader_alt_input(ncreader* n, const ncinput* ni){
switch(ni->id){
@ -243,23 +274,20 @@ ncreader_alt_input(ncreader* n, const ncinput* ni){
if(ncreader_move_left(n)){
break;
}
char* egc = ncplane_at_yx(n->textarea, n->textarea->y, n->textarea->x, NULL, NULL);
if(egc == NULL){
if(is_egc_wordbreak(n->textarea)){
break;
}
wchar_t w;
mbstate_t mbstate = {0};
size_t s = mbrtowc(&w, egc, MB_CUR_MAX, &mbstate);
free(egc);
if(s != (size_t)-1 && s != (size_t)-2){
if(iswordbreak(w)){
break;
}
}
}
break;
case 'f': // forward one word (past end cell) FIXME
ncreader_move_right(n);
case 'f': // forward one word (past end cell)
while(n->textarea->x < ncplane_dim_x(n->textarea) - 1){
if(ncreader_move_right(n)){
break;
}
if(is_egc_wordbreak(n->textarea)){
break;
}
}
break;
default:
return false;