mirror of
https://github.com/dankamongmen/notcurses.git
synced 2024-11-02 09:40:15 +00:00
ncreader: support ctrl-a and ctrl-e #983
This commit is contained in:
parent
67e7046956
commit
1b1d727169
4
NEWS.md
4
NEWS.md
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user