#help_index "DolDoc/Editor" public Bool DocGoToLine(CDoc *doc,I64 line_num) //one based {//Nearest to specified line num. Move cur_entry & center. Bool res=FALSE,unlock; if (doc) { unlock=DocLock(doc); doc->x=0; doc->y=line_num-1; DocRecalc(doc,RECALCt_FIND_CURSOR); DocCenter(doc); if (doc->cur_entry->y==line_num-1) res=TRUE; if (unlock) DocUnlock(doc); } return res; } public Bool DocFind(CDoc *haystack_doc,I64 start_line_num=I64_MIN, U8 *needle,I64 match=1) {//Find str by searching tags. Move cur_entry & center. Bool res=FALSE,unlock; CDocEntry *doc_e; U8 *ptr; I64 i; if (haystack_doc) { unlock=DocLock(haystack_doc); if (start_line_num==I64_MIN) { res=TRUE; doc_e=haystack_doc->head.next; } else { res=DocGoToLine(haystack_doc,start_line_num); doc_e=haystack_doc->cur_entry; } if (res) { if (needle) { res=FALSE; while (doc_e!=haystack_doc) { if (doc_e->de_flags&DOCEF_TAG && doc_e->tag && //TODO: handle multi-DocEntry strs (ptr=StrIMatch(needle,doc_e->tag))) { i=ptr-doc_e->tag; if (!--match) { haystack_doc->cur_entry=doc_e; if (i<doc_e->min_col) i=doc_e->min_col; if (i>doc_e->max_col) i=doc_e->max_col; haystack_doc->cur_col=i; res=TRUE; break; } } doc_e=doc_e->next; } } else res=FALSE; } if (!res) DocBottom(haystack_doc); DocCenter(haystack_doc); if (unlock) DocUnlock(haystack_doc); } return res; } public Bool DocAnchorFind(CDoc *haystack_doc,U8 *needle_str) {//Find named anchor. Move cur_entry & center. Bool res=FALSE,unlock; CDocEntry *doc_e; if (haystack_doc) { unlock=DocLock(haystack_doc); doc_e=haystack_doc->head.next; if (needle_str) while (doc_e!=haystack_doc) { if (doc_e->type_u8==DOCT_ANCHOR && doc_e->de_flags & DOCEF_AUX_STR) { if (!StrCmp(needle_str,doc_e->aux_str)) { haystack_doc->cur_entry=doc_e; haystack_doc->cur_col=doc_e->min_col; res=TRUE; break; } } doc_e=doc_e->next; } if (!res) DocBottom(haystack_doc); DocCenter(haystack_doc); if (unlock) DocUnlock(haystack_doc); } return res; } public U0 EdFindNext(CDoc *doc) {//Editor F3 find next, possibly doing replaces. Bool unlock=DocLock(doc); U8 *ptr,*ptr2,*ptr3; CDocEntry *doc_ce=doc->cur_entry,*doc_e=doc_ce; I64 sf_flags; if (doc->find_replace->match_case) sf_flags=0; else sf_flags=SFF_IGNORE_CASE; if (doc->find_replace->whole_labels) sf_flags|=SFG_WHOLE_LABELS; do { if (doc_e!=doc) { if (doc_e->de_flags&DOCEF_TAG && doc_e->tag && !(doc_e->de_flags&(DOCEG_DONT_EDIT|DOCEF_FILTER_SKIP))) { if (doc_e->type & DOCET_SEL || !doc->find_replace->scan_sel_text) { if (doc->find_replace->scan_fwd) { if (doc_e==doc_ce) { ptr=doc_ce->tag+doc->cur_col+1; if (ptr-doc_ce->tag>=doc_ce->max_col) goto fn_skip; if (ptr-doc_ce->tag<doc_ce->min_col) ptr=doc_ce->tag+doc_ce->min_col; } else ptr=doc_e->tag; if (ptr=StrFind(doc->find_replace->find_text,ptr,sf_flags)) { doc->cur_entry=doc_e; doc->cur_col=ptr-doc_e->tag; if (doc->cur_col>=doc_e->max_col) doc->cur_col=doc_e->max_col-1; if (doc->cur_col<doc_e->min_col) doc->cur_col=doc_e->min_col; DocCenter(doc); if (unlock) DocUnlock(doc); return; } } else { ptr2=NULL; ptr=doc_e->tag+doc_e->min_col; if (doc_e==doc_ce) ptr3=doc_ce->tag+doc->cur_col; else ptr3=doc_e->tag+doc_e->max_col; while (ptr=StrFind(doc->find_replace->find_text,ptr,sf_flags)) { if (ptr>=ptr3) break; ptr2=ptr++; } if (ptr2 && ptr2<ptr3) { doc->cur_entry=doc_e; doc->cur_col=ptr2-doc_e->tag; if (doc->cur_col>=doc_e->max_col) doc->cur_col=doc_e->max_col-1; if (doc->cur_col<doc_e->min_col) doc->cur_col=doc_e->min_col; DocCenter(doc); if (unlock) DocUnlock(doc); return; } } } } } fn_skip: if (doc->find_replace->scan_fwd) doc_e=doc_e->next; else doc_e=doc_e->last; } while (doc_e!=doc_ce); if (unlock) DocUnlock(doc); } public U0 EdSelAll(CDoc *doc,Bool sel) {//Set state of DOCET_SEL on all entries. Bool unlock=DocLock(doc); CDocEntry *doc_e=doc->head.next; while (doc_e!=doc) { BEqu(&doc_e->type,DOCEt_SEL,sel); doc_e=doc_e->next; } if (unlock) DocUnlock(doc); } public Bool EdFindPaired(CDoc *doc,U8 plus,U8 minus, Bool fwd,Bool abort_on_dbl_colon=FALSE) {//Find { } or ( ) pair. Move cur_entry & center. Bool unlock=DocLock(doc),res=FALSE; U8 *ptr; I64 ch,levels=0,colons=0,original_col=doc->cur_col; CDocEntry *doc_ce=doc->cur_entry,*doc_e=doc_ce,*original_ce=doc_ce; if (abort_on_dbl_colon && EdCurU8(doc)==':') colons=1; else colons=0; do { if (doc_e!=doc) { if (doc_e->de_flags&DOCEF_TAG && doc_e->tag && !(doc_e->de_flags&DOCEF_FILTER_SKIP)) { if (fwd) { if (doc_e==doc_ce) ptr=doc_e->tag+doc->cur_col+1; else ptr=doc_e->tag; if (ptr-doc_e->tag<doc_e->min_col) ptr=doc_e->tag+doc_e->min_col; if (ptr-doc_e->tag>=doc_e->max_col) goto pa_skip; while (ch=*ptr++) if (abort_on_dbl_colon && ch==':') { if (++colons==2) { doc->cur_entry=doc_e; doc->cur_col=ptr-doc_e->tag-1; EdCursorLeft(doc); res=FALSE; goto pa_done; } } else { colons=0; if (ch==plus) levels++; else if (ch==minus) { if (!levels--) { doc->cur_entry=doc_e; doc->cur_col=ptr-doc_e->tag-1; res=doc->cur_entry!=original_ce || doc->cur_col!=original_col; goto pa_done; } } } } else { if (doc_e==doc_ce) { ptr=doc_e->tag+doc->cur_col-1; if (ptr-doc_e->tag>=doc_e->max_col) ptr=doc_e->tag+doc_e->max_col-1; } else ptr=doc_e->tag+doc_e->max_col-1; if (ptr-doc_e->tag<doc_e->min_col) goto pa_skip; while (ptr>=doc_e->tag+doc_e->min_col) { ch=*ptr--; if (abort_on_dbl_colon && ch==':') { if (++colons==2) { doc->cur_entry=doc_e; doc->cur_col=ptr-doc_e->tag+1; res=FALSE; goto pa_done; } } else { colons=0; if (ch==plus) levels++; else if (ch==minus) { if (!levels--) { doc->cur_entry=doc_e; doc->cur_col=ptr-doc_e->tag+1; res=doc->cur_entry!=original_ce || doc->cur_col!=original_col; goto pa_done; } } } } } } } pa_skip: if (fwd) doc_e=doc_e->next; else doc_e=doc_e->last; } while (doc_e!=doc_ce); pa_done: DocRecalc(doc); DocCenter(doc); if (unlock) DocUnlock(doc); return res; } public Bool EdGoToFun(CDoc *doc,Bool fwd,Bool abort_on_dbl_colon) {//Move cur_entry to start of cur fun and center.(Shoddy) Bool unlock=DocLock(doc),res=FALSE; I64 ch,levels,colons; if (fwd) { levels=0; colons=0; while (doc->cur_entry!=doc) { ch=EdCurU8(doc); if (abort_on_dbl_colon && ch==':') { if (++colons==2) { EdCursorLeft(doc); break; } } else { colons=0; if (ch=='{') levels++; else if (ch=='}' && !levels--) break; } EdCursorRight(doc); } DocRecalc(doc); if (doc->cur_entry!=doc) res=TRUE; } else { while (EdFindPaired(doc,'}','{',FALSE,abort_on_dbl_colon)); if (doc->cur_entry!=doc) { ch=EdCurU8(doc); if (abort_on_dbl_colon && ch==':') res=TRUE; else { if (ch=='{') res=TRUE; } } } if (unlock) DocUnlock(doc); return res; } public U0 EdSelFun(CDoc *doc,Bool abort_on_dbl_colon=FALSE) {//Set DOCET_SEL on all entries in cur fun. Bool unlock=DocLock(doc); U8 *ptr; I64 ch,levels=0,colons=0; CDocEntry *doc_e; EdSelAll(doc,FALSE); EdGoToFun(doc,FALSE,abort_on_dbl_colon); if (EdCurU8(doc)=='{') levels--; else if (abort_on_dbl_colon && EdCurU8(doc)==':') { EdCursorRight(doc); if (EdCurU8(doc)==':') EdCursorRight(doc); } doc_e=doc->cur_entry; while (doc_e!=doc) { doc_e->type|=DOCET_SEL; if (doc_e->de_flags&DOCEF_TAG && doc_e->tag) { ptr=doc_e->tag; if (doc_e==doc->cur_entry) ptr+=doc->cur_col; while (ch=*ptr++) if (abort_on_dbl_colon && ch==':') { if (++colons==2) goto sf_done; } else { colons=0; if (ch=='{') levels++; else if (ch=='}' && !levels--) goto sf_done; } } doc_e=doc_e->next; } sf_done: DocRecalc(doc); if (unlock) DocUnlock(doc); } #define RSAC_REPLACE 0 #define RSAC_SKIP 1 #define RSAC_ALL 2 I64 PopUpReplaceSkipAllCancel(U8 *header=NULL,U8 *footer=NULL) { I64 i; CDoc *doc=DocNew; if (header) DocPrint(doc,"%s",header); DocPrint(doc,"$CM+LX,1,4$$BT,\"REPLACE\",LE=RSAC_REPLACE$" "$CM+LX,17,0$$BT,\"SKIP\",LE=RSAC_SKIP$" "$CM+LX,1,3$$BT,\"ALL\",LE=RSAC_ALL$" "$CM+LX,17,0$$BT,\"CANCEL\",LE=DOCM_CANCEL$\n"); if (footer) DocPrint(doc,"%s",footer); i=PopUpMenu(doc); DocDel(doc); return i; } I64 EdFindReplace(CDoc *doc) { Bool found,unlock; I64 cmd,i,j,plen,rlen,dlen,res=-1,sf_flags; U8 *src,*dst,*dst2; CDocEntry *doc_ce,*doc_e,*doc_marker=NULL; if (doc->find_replace->pmt) cmd=RSAC_REPLACE; else cmd=RSAC_ALL; if (!doc->find_replace->pmt || DocForm(doc->find_replace)) { res=0; unlock=DocLock(doc); if (doc->find_replace->match_case || doc->find_replace->local_var) sf_flags=0; else sf_flags=SFF_IGNORE_CASE; if (doc->find_replace->whole_labels || doc->find_replace->local_var) sf_flags|=SFG_WHOLE_LABELS; if (i=doc->find_replace->filter_lines) { doc_ce=doc->head.next; while (doc_ce!=doc) { if (doc_ce->de_flags&DOCEF_TAG && doc_ce->tag && !(doc_ce->de_flags&DOCEF_FILTER_SKIP) && StrFind(doc->find_replace->find_text,doc_ce->tag,sf_flags)) { doc_ce->type|=DOCET_SEL; res++; } else doc_ce->type&=~DOCET_SEL; doc_ce=doc_ce->next; } doc_ce=doc->head.next; while (doc_ce!=doc) { if (!(doc_ce->de_flags&DOCEF_FILTER_SKIP)) { found=FALSE; doc_e=doc_ce; while (doc_e!=doc && doc_e->y>doc_ce->y-i) { if (doc_e->type&DOCET_SEL) { found=TRUE; break; } else doc_e=doc_e->last; } if (!found) { doc_e=doc_ce; while (doc_e!=doc && doc_e->y<doc_ce->y+i) { if (doc_e->type&DOCET_SEL) { found=TRUE; break; } else doc_e=doc_e->next; } } if (!found) doc_ce->de_flags|=DOCEF_FILTER_SKIP; } doc_ce=doc_ce->next; } EdSelAll(doc,FALSE); goto fr_unlock_done; } if (doc->find_replace->local_var) EdSelFun(doc); if (!doc->find_replace->replace && !doc->find_replace->local_var) { EdFindNext(doc); goto fr_unlock_done; } plen=StrLen(doc->find_replace->find_text); if (!plen) goto fr_unlock_done; rlen=StrLen(doc->find_replace->replace_text); if (doc->head.next!=doc) { doc_e=doc_marker=DocSplitTag(doc,doc->cur_entry,doc->cur_col, doc->cur_entry->x+doc->cur_col,doc->cur_entry->y,DOCT_MARKER); do { if (doc_e==doc) { if (doc->find_replace->scan_fwd) doc_e=doc_e->next; else doc_e=doc_e->last; if (doc_e==doc_marker) break; } if (doc_e->type_u8==DOCT_TEXT && !(doc_e->de_flags&(DOCEG_DONT_EDIT|DOCEF_FILTER_SKIP)) && (doc_e->type & DOCET_SEL || !doc->find_replace->scan_sel_text&& !doc->find_replace->local_var)) { src=doc_e->tag; while (src) { src=StrFind(doc->find_replace->find_text,src,sf_flags); if (src) { doc->cur_col=src-doc_e->tag; doc->cur_entry=doc_e; if (cmd!=RSAC_ALL) DocCenter(doc); if (cmd!=RSAC_ALL) { DocUnlock(doc); cmd=PopUpReplaceSkipAllCancel(""); DocLock(doc); if (cmd<0) goto fr_unlock_done; } doc_e=doc->cur_entry; src=doc->cur_col+doc_e->tag; if (cmd==RSAC_REPLACE || cmd==RSAC_ALL) { dlen=StrLen(doc_e->tag); doc_e->max_col=dlen+rlen-plen; dst=MAlloc(doc_e->max_col+1,doc->mem_task); dst2=dst; j=src-doc_e->tag; for (i=0; i<j; i++) *dst++=doc_e->tag[i]; for (i=0; i<rlen; i++) *dst++=doc->find_replace->replace_text[i]; src=dst; for (i=j+plen; i<=dlen; i++) *dst++=doc_e->tag[i]; Free(doc_e->tag); doc_e->tag=dst2; doc->cur_col=src-doc_e->tag; doc->cur_entry=doc_e; if (cmd!=RSAC_ALL) { DocRemSoftNewLines(doc,doc->cur_entry); DocRecalc(doc); } doc_e=doc->cur_entry; src=doc->cur_col+doc_e->tag; res++; } else src++; } } } if (doc->find_replace->scan_fwd) doc_e=doc_e->next; else doc_e=doc_e->last; } while (doc_e!=doc_marker); } fr_unlock_done: if (doc_marker) DocEntryDel(doc,doc_marker); DocRemSoftNewLines(doc,NULL); DocRecalc(doc); DocCenter(doc); if (unlock) DocUnlock(doc); } return res; } public I64 EdReplace(CDoc *doc,U8 *find,U8 *replace, Bool sel=TRUE,Bool match_case=TRUE,Bool whole_labels=FALSE) {//Find & replace using editor's cmd. CEdFindText old_find_replace; Bool unlock; I64 i,res=-1; if (!doc) return -1; unlock=DocLock(doc); MemCpy(&old_find_replace,doc->find_replace,sizeof(CEdFindText)); MemSet(doc->find_replace,0,sizeof(CEdFindText)); i=StrLen(find); if (i<sizeof(CEdFindText.find_text)) { MemCpy(doc->find_replace->find_text,find,i+1); i=StrLen(replace); if (i<sizeof(CEdFindText.replace_text)) { MemCpy(doc->find_replace->replace_text,replace,i+1); doc->find_replace->replace=TRUE; doc->find_replace->scan_sel_text=sel; doc->find_replace->match_case=match_case; doc->find_replace->whole_labels=whole_labels; doc->find_replace->pmt=FALSE; res=EdFindReplace(doc); } } MemCpy(doc->find_replace,&old_find_replace,sizeof(CEdFindText)); if (unlock) DocUnlock(doc); return res; } class CEdLineGoTo { I64 line format "$DA,A=\"Go to Line:%d\"$"; }; U0 EdGoToLine(CDoc *doc) {//Prompt with form and go to line num. CEdLineGoTo gtl; gtl.line=1; if (DocForm(&gtl)) DocGoToLine(doc,gtl.line); }