int m_find(motion_arg const *m, unsigned repeat, window *win, point_t *to) { bool raw; return m_findnext2( last_find_ch = io_getch(IO_NOMAP /* vim doesn't mapraw here */, &raw, true), last_find_type = m->find_type, repeat, win, to); }
int keys_filter( enum io io_m, char *struc, unsigned n_ents, unsigned st_off, unsigned st_sz, int mode_off) { #define STRUCT_STR(i, st, off) *(const char **)(struc + i * st_sz + st_off) int ret = -1; bool potential[n_ents]; if(mode_off >= 0){ enum buf_mode curmode = windows_cur()->ui_mode; for(unsigned i = 0; i < n_ents; i++){ enum buf_mode mode = *(enum buf_mode *)( struc + i * st_sz + mode_off); potential[i] = mode & curmode; } }else{ memset(potential, true, sizeof potential); } unsigned ch_idx = 0; char *sofar = NULL; size_t nsofar = 0; for(;; ch_idx++){ bool raw; int ch = io_getch(io_m, &raw, /*map:*/ch_idx == 0); /* dl shouldn't map l */ if(raw){ /* raw char, doesn't match any, get out */ memset(potential, 0, sizeof potential); } sofar = urealloc(sofar, ++nsofar); sofar[nsofar-1] = ch; unsigned npotential = 0; unsigned last_potential = 0; for(unsigned i = 0; i < sizeof potential; i++){ if(potential[i]){ const char *const kstr = STRUCT_STR(i, struc, str_off); size_t keys_len = strlen(kstr); if(ch_idx >= keys_len || kstr[ch_idx] != ch){ potential[i] = false; }else{ npotential++; last_potential = i; } } } switch(npotential){ case 1: { /* only accept once we have the full string */ const char *kstr = STRUCT_STR(last_potential, struc, str_off); if(ch_idx == strlen(kstr) - 1){ ret = last_potential; goto out; } break; } case 0: for(size_t i = nsofar; i > 0; i--) io_ungetch(sofar[i - 1], false); goto out; } } out: free(sofar); return ret; }
char *prompt(char promp, const char *initial) { int len; char *buf; int i; if(initial) { len = strlen(initial) + 1; buf = umalloc(len); i = len - 1; strcpy(buf, initial); } else { len = 10; buf = umalloc(len); i = 0; } int y, x; nc_get_yx(&y, &x); nc_set_yx(nc_LINES() - 1, 0); nc_addch(promp); for(int x = 0; x < i; x++) nc_addch(buf[x]); nc_clrtoeol(); bool reading = true; while(reading) { bool wasraw; int ch = io_getch(IO_NOMAP | IO_MAPRAW, &wasraw, true); switch(ch) { case CTRL_AND('?'): case CTRL_AND('H'): case 263: case 127: /* backspace */ if(i == 0) goto cancel; buf[--i] = '\0'; nc_set_yx(nc_LINES() - 1, i + 1); break; case '\n': case '\r': reading = false; break; case CTRL_AND('u'): buf[i = 0] = '\0'; nc_set_yx(nc_LINES() - 1, i + 1); break; case K_ESC: if(!wasraw) goto cancel; /* fall */ default: buf[i++] = ch; nc_addch(ch); if(i == len) buf = urealloc(buf, len *= 2); buf[i] = '\0'; break; } } nc_set_yx(y, x); return buf; cancel: nc_set_yx(y, x); free(buf); return NULL; }