📄 usearch.c
字号:
static int set_options(BW *bw, unsigned char *s, SRCH *srch, int *notify){ unsigned char buf[80]; unsigned char *t; srch->ignore = icase; t = s; while (*t) { int c = fwrd_c(&t); if (yncheck(all_key, c)) srch->all = 1; else if (yncheck(list_key, c)) srch->all = 2; else if (yncheck(replace_key, c)) srch->replace = 1; else if (yncheck(backwards_key, c)) srch->backwards = 1; else if (yncheck(ignore_key, c)) srch->ignore = 1; else if (yncheck(noignore_key, c)) srch->ignore = 0; else if (yncheck(wrap_key, c)) srch->allow_wrap = 1; else if (yncheck(nowrap_key, c)) srch->allow_wrap = 0; else if (yncheck(block_key, c)) srch->block_restrict = 1; else if (c >= '0' && c <= '9') { if (srch->repeat == -1) srch->repeat = 0; srch->repeat = srch->repeat * 10 + c - '0'; } } vsrm(s); if (srch->replace) { /* if (pico && globalsrch && globalsrch->replacement) { joe_snprintf_1(bf1,30,"%s",globalsrch->replacement); if (zlen(globalsrch->replacement)>29) zcat(bf1,USTR "$"); joe_snprintf_1(buf,sizeof(buf),joe_gettext(_("Replace with (^C to abort) [%s]: ")),bf1); } else */ zcpy(buf, joe_gettext(_("Replace with (^C to abort): "))); if (wmkpw(bw->parent, buf, &replhist, set_replace, srchstr, pfabort, srch_cmplt, srch, notify, bw->b->o.charmap, 0)) return 0; else return -1; } else return dopfnext(bw, setmark(srch), notify);}static int set_pattern(BW *bw, unsigned char *s, SRCH *srch, int *notify){ BW *pbw; unsigned char *p; if (icase) p = joe_gettext(_("case (S)ensitive (R)eplace (B)ackwards Bloc(K) (A)ll files NNN (^C to abort): ")); else p = joe_gettext(_("(I)gnore (R)eplace (B)ackwards Bloc(K) (A)ll files NNN (^C to abort): ")); vsrm(srch->pattern); if (sLEN(s) || !globalsrch || !pico) srch->pattern = s; else { vsrm(s); srch->pattern = vsdup(globalsrch->pattern); } if ((pbw = wmkpw(bw->parent, p, NULL, set_options, srchopt, pfabort, utypebw, srch, notify, bw->b->o.charmap, 0)) != NULL) { unsigned char buf[10]; if (srch->ignore) { unsigned char *t = joe_gettext(ignore_key); binsc(pbw->cursor, fwrd_c(&t)); } if (srch->replace) { unsigned char *t = joe_gettext(replace_key); binsc(pbw->cursor, fwrd_c(&t)); } if (srch->backwards) { unsigned char *t = joe_gettext(backwards_key); binsc(pbw->cursor, fwrd_c(&t)); } if (srch->repeat >= 0) joe_snprintf_1(buf, sizeof(buf), "%d", srch->repeat), binss(pbw->cursor, buf); pset(pbw->cursor, pbw->b->eof); pbw->cursor->xcol = piscol(pbw->cursor); srch->ignore = 0; srch->replace = 0; srch->backwards = 0; srch->repeat = -1; return 0; } else { rmsrch(srch); return -1; }}/* Unescape for text going to genfmt */void unesc_genfmt(unsigned char *d, unsigned char *s, int max){ while (max && *s) { if (*s == '\\') *d++ = '\\'; *d++ = *s++; --max; } if (*s) *d++ = '$'; *d = 0;}int dofirst(BW *bw, int back, int repl, unsigned char *hint){ SRCH *srch; BW *pbw; unsigned char bf1[80]; unsigned char buf[80]; if (smode && globalsrch) { globalsrch->backwards = back; globalsrch->replace = repl; return pfnext(bw); } if (bw->parent->huh == srchstr) { long byte; p_goto_eol(bw->cursor); byte = bw->cursor->byte; p_goto_bol(bw->cursor); if (byte == bw->cursor->byte) prgetc(bw->cursor); return urtn((BASE *)bw, -1); } srch = mksrch(NULL, NULL, 0, back, -1, repl, 0, 0); srch->addr = bw->cursor->byte; srch->wrap_p = pdup(bw->cursor, USTR "dofirst"); srch->wrap_p->owner = &srch->wrap_p; if (pico && globalsrch && globalsrch->pattern) { unesc_genfmt(bf1, globalsrch->pattern, 30); joe_snprintf_1(buf,sizeof(buf),joe_gettext(_("Find (^C to abort) [%s]: ")),bf1); } else zcpy(buf, joe_gettext(_("Find (^C to abort): "))); if ((pbw=wmkpw(bw->parent, buf, &findhist, set_pattern, srchstr, pfabort, srch_cmplt, srch, NULL, bw->b->o.charmap, 0))) { if (hint) { binss(pbw->cursor, hint); pset(pbw->cursor, pbw->b->eof); pbw->cursor->xcol = piscol(pbw->cursor); } return 0; } else { rmsrch(srch); return -1; }}int pffirst(BW *bw){ return dofirst(bw, 0, 0, NULL);}int prfirst(BW *bw){ return dofirst(bw, 1, 0, NULL);}int pqrepl(BW *bw){ return dofirst(bw, 0, 1, NULL);}/* Execute next search */static int doreplace(BW *bw, SRCH *srch){ P *q; if (!modify_logic(bw,bw->b)) return -1; if (markk) markk->end = 1; if (srch->markk) srch->markk->end = 1; q = pdup(bw->cursor, USTR "doreplace"); if (srch->backwards) { q = pfwrd(q, (long) sLEN(srch->entire)); bdel(bw->cursor, q); prm(q); } else { q = pbkwd(q, (long) sLEN(srch->entire)); bdel(q, bw->cursor); prm(q); } insert(srch, bw->cursor, sv(srch->replacement)); srch->addr = bw->cursor->byte; srch->last_repl = bw->cursor->byte; if (markk) markk->end = 0; if (srch->markk) srch->markk->end = 0; return 0;}static void visit(SRCH *srch, BW *bw, int yn){ SRCHREC *r = (SRCHREC *) alitem(&fsr, sizeof(SRCHREC)); r->addr = bw->cursor->byte; r->yn = yn; r->wrap_flag = srch->wrap_flag; r->last_repl = srch->last_repl; r->b = bw->b; enqueb(SRCHREC, link, &srch->recs, r);}static void goback(SRCH *srch, BW *bw){ SRCHREC *r = srch->recs.link.prev; if (r != &srch->recs) { srch->current = r->b; if (r->yn) { uundo(bw); } if (r->b != bw->b) { W *w = bw->parent; get_buffer_in_window(bw, r->b); bw = (BW *)w->object; } if (bw->cursor->byte != r->addr) pgoto(bw->cursor, r->addr); srch->wrap_flag = r->wrap_flag; srch->last_repl = r->last_repl; demote(SRCHREC, link, &fsr, r); }}unsigned char *rest_key = (unsigned char *) _("|rest of file|rR");unsigned char *backup_key = (unsigned char *) _("|backup|bB");static int dopfrepl(BW *bw, int c, SRCH *srch, int *notify){ srch->addr = bw->cursor->byte; if (c == NO_CODE || yncheck(no_key, c)) return dopfnext(bw, srch, notify); else if (c == YES_CODE || yncheck(yes_key, c) || c == ' ') { srch->recs.link.prev->yn = 1; if (doreplace(bw, srch)) { pfsave(bw, srch); return -1; } else return dopfnext(bw, srch, notify); } else if (yncheck(rest_key, c)) { if (doreplace(bw, srch)) return -1; srch->rest = 1; return dopfnext(bw, srch, notify); } else if (c == 8 || c == 127 || yncheck(backup_key, c)) { W *w = bw->parent; goback(srch, bw); goback(srch, (BW *)w->object); return dopfnext((BW *)w->object, srch, notify); } else if (c != -1) { if (notify) *notify = 1; pfsave(bw, srch); nungetc(c); return 0; } if (mkqwnsr(bw->parent, sz(joe_gettext(_("Replace (Y)es (N)o (R)est (B)ackup (^C to abort)?"))), dopfrepl, pfsave, srch, notify)) return 0; else return pfsave(bw, srch);}/* Test if found text is within region * return 0 if it is, * -1 if we should keep searching * 1 if we're done */static int restrict_to_block(BW *bw, SRCH *srch){ if (!srch->valid || !srch->block_restrict) return 0; bw->cursor->xcol = piscol(bw->cursor); if (srch->backwards) if (!square) { if (bw->cursor->byte < srch->markb->byte) return 1; else if (bw->cursor->byte + sLEN(srch->entire) > srch->markk->byte) return -1; } else { if (bw->cursor->line < srch->markb->line) return 1; else if (bw->cursor->line > srch->markk->line) return -1; else if (piscol(bw->cursor) + sLEN(srch->entire) > srch->markk->xcol || piscol(bw->cursor) < srch->markb->xcol) return -1; } else if (!square) { if (bw->cursor->byte > srch->markk->byte) return 1; else if (bw->cursor->byte - sLEN(srch->entire) < srch->markb->byte) return -1; } else { if (bw->cursor->line > srch->markk->line) return 1; if (bw->cursor->line < srch->markb->line) return -1; if (piscol(bw->cursor) > srch->markk->xcol || piscol(bw->cursor) - sLEN(srch->entire) < srch->markb->xcol) return -1; } return 0;}/* Possible results: * 0) Search or search & replace is finished. * 1) Search string was not found. * 2) Search string was found. * 3) Abort due to infinite loop */static int fnext(BW *bw, SRCH *srch){ P *sta; if (!srch->first) { srch->first = bw->b; srch->current = bw->b; } next: if (srch->repeat != -1) { if (!srch->repeat) return 0; else --srch->repeat; } again: if (srch->backwards) sta = searchb(bw, srch, bw->cursor); else sta = searchf(bw, srch, bw->cursor); if (!sta && srch->all) { B *b; if (srch->all == 2) b = beafter(srch->current); else { berror = 0; b = bafter(srch->current); } if (b && b != srch->first && !berror) { W *w = bw->parent; srch->current = b; /* this bumps reference count of b */ get_buffer_in_window(bw, b); bw = (BW *)w->object; p_goto_bof(bw->cursor); goto again; } else if (berror) { msgnw(bw->parent, joe_gettext(msgs[-berror])); } } if (!sta) { srch->repeat = -1; return 1; } if (srch->rest || (srch->repeat != -1 && srch->replace)) { if (srch->valid) switch (restrict_to_block(bw, srch)) { case -1: goto again; case 1: if (srch->addr >= 0) pgoto(bw->cursor, srch->addr); return !srch->rest; } if (doreplace(bw, srch)) return 0; goto next; } else if (srch->repeat != -1) { if (srch->valid) switch (restrict_to_block(bw, srch)) { case -1: goto again; case 1: if (srch->addr >= 0) pgoto(bw->cursor, srch->addr); return 1; } srch->addr = bw->cursor->byte; goto next; } else return 2;}int dopfnext(BW *bw, SRCH *srch, int *notify){ W *w; int fnr; int orgmid = mid; /* Original mid status */ int ret = 0; mid = 1; /* Screen recenters mode during search */ if (csmode) smode = 2; /* We have started a search mode */ if (srch->replace) visit(srch, bw, 0);again: w = bw->parent; fnr = fnext(bw, srch); bw = (BW *)w->object; switch (fnr) { case 0: break; case 1:bye: if (!srch->flg && !srch->rest) { if (srch->valid && srch->block_restrict) msgnw(bw->parent, joe_gettext(_("Not found (search restricted to marked block)"))); else msgnw(bw->parent, joe_gettext(_("Not found"))); ret = -1; } break; case 3: msgnw(bw->parent, joe_gettext(_("Infinite loop aborted: your search repeatedly matched same place"))); ret = -1; break; case 2: if (srch->valid) switch (restrict_to_block(bw, srch)) { case -1: goto again; case 1: if (srch->addr >= 0) pgoto(bw->cursor, srch->addr); goto bye; } srch->addr = bw->cursor->byte; /* Make sure found text is fully on screen */ if(srch->backwards) { bw->offset=0; pfwrd(bw->cursor,sLEN(srch->entire)); bw->cursor->xcol = piscol(bw->cursor); dofollows(); pbkwd(bw->cursor,sLEN(srch->entire)); } else { bw->offset=0; pbkwd(bw->cursor,sLEN(srch->entire)); bw->cursor->xcol = piscol(bw->cursor); dofollows(); pfwrd(bw->cursor,sLEN(srch->entire)); } if (srch->replace) { if (square) bw->cursor->xcol = piscol(bw->cursor); if (srch->backwards) { pdupown(bw->cursor, &markb, USTR "dopfnext"); markb->xcol = piscol(markb); pdupown(markb, &markk, USTR "dopfnext"); pfwrd(markk, (long) sLEN(srch->entire)); markk->xcol = piscol(markk); } else { pdupown(bw->cursor, &markk, USTR "dopfnext"); markk->xcol = piscol(markk); pdupown(bw->cursor, &markb, USTR "dopfnext"); pbkwd(markb, (long) sLEN(srch->entire)); markb->xcol = piscol(markb); } srch->flg = 1; if (dopfrepl(bw, -1, srch, notify)) ret = -1; notify = 0; srch = 0; } break; } bw->cursor->xcol = piscol(bw->cursor); dofollows(); mid = orgmid; if (notify) *notify = 1; if (srch) pfsave(bw, srch); else updall(); return ret;}int pfnext(BW *bw){ if (!globalsrch) { /* Query for search string if there isn't any */ return pffirst(bw); } else { SRCH *srch = globalsrch; globalsrch = 0; srch->addr = bw->cursor->byte; if (!srch->wrap_p || srch->wrap_p->b!=bw->b) { prm(srch->wrap_p); srch->wrap_p = pdup(bw->cursor, USTR "pfnext"); srch->wrap_p->owner = &srch->wrap_p; srch->wrap_flag = 0; } return dopfnext(bw, setmark(srch), NULL); }}void save_srch(FILE *f){ if(globalsrch) { if(globalsrch->pattern) { fprintf(f," pattern "); emit_string(f,globalsrch->pattern,sLEN(globalsrch->pattern)); fprintf(f,"\n"); } if(globalsrch->replacement) { fprintf(f," replacement "); emit_string(f,globalsrch->replacement,sLEN(globalsrch->replacement)); fprintf(f,"\n"); } fprintf(f," backwards %d\n",globalsrch->backwards); fprintf(f," ignore %d\n",globalsrch->ignore); fprintf(f," replace %d\n",globalsrch->replace); fprintf(f," block_restrict %d\n",globalsrch->block_restrict); } fprintf(f,"done\n");}void load_srch(FILE *f){ unsigned char buf[1024]; unsigned char bf[1024]; unsigned char *pattern = 0; unsigned char *replacement = 0; int backwards = 0; int ignore = 0; int replace = 0; int block_restrict = 0; while(fgets((char *)buf,1023,f) && zcmp(buf,USTR "done\n")) { unsigned char *p=buf; parse_ws(&p,'#'); if(!parse_kw(&p,USTR "pattern")) { int len; parse_ws(&p,'#'); bf[0] = 0; len = parse_string(&p,bf,sizeof(bf)); if (len>0) pattern = vsncpy(NULL,0,bf,len); } else if(!parse_kw(&p,USTR "replacement")) { int len; parse_ws(&p,'#'); bf[0] = 0; len = parse_string(&p,bf,sizeof(bf)); if (len>0) replacement = vsncpy(NULL,0,bf,len); } else if(!parse_kw(&p,USTR "backwards")) { parse_ws(&p,'#'); parse_int(&p,&backwards); } else if(!parse_kw(&p,USTR "ignore")) { parse_ws(&p,'#'); parse_int(&p,&ignore); } else if(!parse_kw(&p,USTR "replace")) { parse_ws(&p,'#'); parse_int(&p,&replace); } else if(!parse_kw(&p,USTR "block_restrict")) { parse_ws(&p,'#'); parse_int(&p,&block_restrict); } } globalsrch = mksrch(pattern,replacement,ignore,backwards,-1,replace,0,0); globalsrch->block_restrict = block_restrict;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -