/* search.c, Atto Emacs, Public Domain, Hugh Barney, 2016, Derived from: Anthony's Editor January 93 */ #include "header.h" #define FWD_SEARCH 1 #define REV_SEARCH 2 void search(void) { int cpos = 0; int c; point_t o_point = curbp->b_point; point_t found; searchtext[0] = '\0'; display_prompt_and_response("Search: ", searchtext); cpos = strlen(searchtext); for (;;) { c = getch(); /* ignore control keys other than C-g, backspace, CR, C-s, C-R, ESC */ if (c < 32 && c != 07 && c != 0x08 && c != 0x13 && c != 0x12 && c != 0x1b) continue; switch(c) { case 0x1b: /* esc */ searchtext[cpos] = '\0'; flushinp(); /* discard any escape sequence without writing in buffer */ return; case 0x07: /* ctrl-g */ curbp->b_point = o_point; return; case 0x13: /* ctrl-s, do the search */ found = search_forward(curbp, curbp->b_point, searchtext); display_search_result(found, FWD_SEARCH, "Search: ", searchtext); break; case 0x12: /* ctrl-r, do the search */ found = search_backwards(curbp, curbp->b_point, searchtext); display_search_result(found, REV_SEARCH, "Search: ", searchtext); break; case 0x7f: /* del, erase */ case 0x08: /* backspace */ if (cpos == 0) continue; searchtext[--cpos] = '\0'; display_prompt_and_response("Search: ", searchtext); break; default: if (cpos < STRBUF_M - 1) { searchtext[cpos++] = c; searchtext[cpos] = '\0'; display_prompt_and_response("Search: ", searchtext); } break; } } } void display_search_result(point_t found, int dir, const char *prompt, const char *search) { if (found != -1 ) { curbp->b_point = found; msg("%s%s",prompt, search); display(curwp, TRUE); } else { msg("Failing %s%s",prompt, search); dispmsg(); curbp->b_point = (dir == FWD_SEARCH ? 0 : pos(curbp, curbp->b_ebuf)); } } point_t search_forward(buffer_t *bp, point_t start_p, char *stext) { point_t end_p = pos(bp, bp->b_ebuf); point_t p,pp; char* s; if (0 == strlen(stext)) return start_p; for (p=start_p; p < end_p; p++) { for (s=stext, pp=p; pp < end_p && *s == *(ptr(bp, pp)) && *s !='\0'; s++, pp++) ; if (*s == '\0') return pp; } return -1; } point_t search_backwards(buffer_t *bp, point_t start_p, char *stext) { point_t end_p = pos(bp, bp->b_ebuf); point_t p,pp; char* s; if (0 == strlen(stext)) return start_p; for (p=start_p; p >= 0; p--) { for (s=stext, pp=p; pp > -1 && pp < end_p && *s == *(ptr(bp, pp)) && *s != '\0'; s++, pp++) ; if (*s == '\0') { if (p > 0) p--; return p; } } return -1; }