mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-09 09:09:03 -04:00
ncreader: implement reamining shortcuts #983
This commit is contained in:
parent
1b1d727169
commit
8a81d06b4b
7
NEWS.md
7
NEWS.md
@ -9,9 +9,10 @@ rearrangements of Notcurses.
|
||||
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).
|
||||
word forward, Ctrl+'A' to move to the beginning of the line, Ctrl+'E' to
|
||||
move to the end of the line, Ctrl+'U' to clear the line before the cursor,
|
||||
and Ctrl+'W' to clear the word before the cursor (when
|
||||
`NCREADER_OPTION_NOCMDKEYS` has not been specified).
|
||||
|
||||
* 2.0.2 (2020-10-25)
|
||||
* Add `ncvisual_decode_loop()`, which returns to the first frame upon
|
||||
|
@ -214,13 +214,48 @@ int ncreader_write_egc(ncreader* n, const char* egc){
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool
|
||||
do_backspace(ncreader* n){
|
||||
int x = n->textarea->x;
|
||||
int y = n->textarea->y;
|
||||
if(n->textarea->x == 0){
|
||||
if(n->textarea->y){
|
||||
y = n->textarea->y - 1;
|
||||
x = n->textarea->lenx - 1;
|
||||
}
|
||||
}else{
|
||||
--x;
|
||||
}
|
||||
ncplane_putegc_yx(n->textarea, y, x, "", NULL);
|
||||
ncplane_cursor_move_yx(n->textarea, y, x);
|
||||
ncplane_cursor_move_yx(n->ncp, n->ncp->y, n->ncp->x - 1);
|
||||
ncreader_redraw(n);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
is_egc_wordbreak(ncplane* textarea){
|
||||
char* egc = ncplane_at_yx(textarea, textarea->y, textarea->x, NULL, NULL);
|
||||
fprintf(stderr, "TAKING A LOKO AT [%s]\n", egc);
|
||||
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_ctrl_input(ncreader* n, const ncinput* ni){
|
||||
switch(ni->id){
|
||||
case 'U':
|
||||
ncplane_erase(n->ncp); // homes the cursor
|
||||
ncplane_erase(n->textarea);
|
||||
break;
|
||||
case 'B':
|
||||
ncreader_move_left(n);
|
||||
break;
|
||||
@ -241,31 +276,31 @@ ncreader_ctrl_input(ncreader* n, const ncinput* ni){
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'U': // clear line before cursor
|
||||
while(n->textarea->x){
|
||||
do_backspace(n);
|
||||
}
|
||||
break;
|
||||
case 'W': // clear word before cursor
|
||||
while(n->textarea->x){
|
||||
if(ncreader_move_left(n)){
|
||||
break;
|
||||
}
|
||||
if(is_egc_wordbreak(n->textarea)){
|
||||
break;
|
||||
}
|
||||
if(ncreader_move_right(n)){
|
||||
break;
|
||||
}
|
||||
do_backspace(n);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return false; // pass on all other ctrls
|
||||
}
|
||||
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){
|
||||
@ -300,8 +335,6 @@ ncreader_alt_input(ncreader* n, const ncinput* ni){
|
||||
// * anything with Ctrl, except 'U' (which clears all input)
|
||||
// * anything synthesized, save arrow keys and backspace
|
||||
bool ncreader_offer_input(ncreader* n, const ncinput* ni){
|
||||
int x = n->textarea->x;
|
||||
int y = n->textarea->y;
|
||||
if(ni->ctrl && !n->no_cmd_keys){
|
||||
return ncreader_ctrl_input(n, ni);
|
||||
}else if(ni->alt && !n->no_cmd_keys){
|
||||
@ -311,19 +344,7 @@ bool ncreader_offer_input(ncreader* n, const ncinput* ni){
|
||||
return false;
|
||||
}
|
||||
if(ni->id == NCKEY_BACKSPACE){
|
||||
if(n->textarea->x == 0){
|
||||
if(n->textarea->y){
|
||||
y = n->textarea->y - 1;
|
||||
x = n->textarea->lenx - 1;
|
||||
}
|
||||
}else{
|
||||
--x;
|
||||
}
|
||||
ncplane_putegc_yx(n->textarea, y, x, "", NULL);
|
||||
ncplane_cursor_move_yx(n->textarea, y, x);
|
||||
ncplane_cursor_move_yx(n->ncp, n->ncp->y, n->ncp->x - 1);
|
||||
ncreader_redraw(n);
|
||||
return true;
|
||||
return do_backspace(n);
|
||||
}
|
||||
// FIXME deal with multicolumn EGCs -- probably extract these and make them
|
||||
// general ncplane_cursor_{left, right, up, down}()
|
||||
|
Loading…
x
Reference in New Issue
Block a user