This is SearchText.m in view mode; [Download] [Up]
/* The code of this example is not covered by the FindPanel license. * You may freely copy, distribute, and reuse the code in this example. * The author disclaims any warranty of any kind, expressed or implied, * as to its fitness for any particular use. * * Created by Christopher J. Kane * Version: 1.0 (15 August 1993) */ #import "SearchText.h" #import "regexpr.h" @implementation Text (SearchText) - (oneway void)makeSelectionVisible { [self scrollSelToVisible]; } - (oneway void)replaceSelection:(const char *)replacement { [self replaceSel:replacement]; } - (oneway void)selectTextFrom:(int)start to:(int)end { [self setSel:start :end]; } - (void)writeSelectionToPasteboard:(in Pasteboard *)pboard asType:(in NXAtom)type { char text[spN.cp-sp0.cp+1]; [self getSubstring:text start:sp0.cp length:spN.cp-sp0.cp]; text[spN.cp-sp0.cp] = '\0'; // writeType:data:length: includes more chars // than the length field if this isn't done if (*text!='\0') // true if there was a non-zero length selection { [pboard declareTypes:&type num:1 owner:NULL]; [pboard writeType:type data:text length:spN.cp-sp0.cp]; } } // makes use of the fact that the FindPanel only uses two modes; one for // each boolean value of the 'rev' parameter - (int)searchFor:(const char *)pattern mode:(SearchMode)mode reverse:(BOOL)rev regexpr:(BOOL)regexpr cases:(BOOL)cases position:(out int *)pos size:(out int *)size { if (!regexpr) { // use Text's built-in (but not necessarily efficient) functionality if ([self findText:pattern ignoreCase:!cases backwards:rev wrap:YES]) { *pos = sp0.cp; *size = spN.cp-sp0.cp; //findText... selects the found text return 1; } return 0; } else { // use regular expression package struct re_pattern_buffer p; char textBuffer[textLength+2], fm[256], tr[256]; char *err=NULL; int res=0, i; memset(&p, 0, sizeof(struct re_pattern_buffer)); [self getSubstring:textBuffer start:0 length:textLength+1]; p.translate = tr; p.fastmap = fm; for(i=0; i<256; i++) tr[i] = i; if (!cases) // translation buffer maps lower case to upper case for(i='a'; i<='z'; i++) tr[i] = i-('a'-'A'); err = re_compile_pattern(pattern, strlen(pattern), &p); if (NULL!=err) { fprintf(stderr, err); return -1; } res = re_search(&p, textBuffer, textLength, rev?sp0.cp-1:spN.cp, rev?-sp0.cp+1:textLength-spN.cp, 0); if (res<-1) return -1; // error in search if (res>-1) { // match found *pos = res; // now use re_match to find size (not very clever) res = re_match(&p, textBuffer, textLength, res, 0); if (res<0) return -1; *size = res; return 1; } // wrap to other bit of text and try again res = re_search(&p, textBuffer, textLength, rev?textLength:0, rev?spN.cp-textLength:sp0.cp, 0); if (res<-1) return -1; // error in search if (res>-1) { // match found *pos = res; // now use re_match to find size (not very clever) res = re_match(&p, textBuffer, textLength, res, 0); if (res<0) return -1; *size = res; return 1; } return 0; // not found in non-selected text } return -1; } - (int)replaceAll:(const char *)pattern with:(const char *)replacement mode:(SearchMode)mode regexpr:(BOOL)regexpr cases:(BOOL)cases { int count=0, end; if (!regexpr) { switch (mode) { case TextEdgeToTextEdge: [self setSel:0 :0]; while ([self findText:pattern ignoreCase:!cases backwards:NO wrap:NO]) { // findText:... method does selecting for us, leverage // off that and use replaceSel: [self replaceSel:replacement]; count++; } return count; case SelStartToSelEnd: end = spN.cp-strlen(pattern); [self setSel:sp0.cp :sp0.cp]; while ([self findText:pattern ignoreCase:!cases backwards:NO wrap:NO]) { // do same as above, but we have to keep track of the // end point (Text does that for us above in textLength) if (sp0.cp>end) break; [self replaceSel:replacement]; end += strlen(replacement)-strlen(pattern); count++; } return count; default: return -1; // FindPanel uses no other modes } } else NXRunAlertPanel("Replace All", "Replace All with regular expressions is not implemented", NULL, NULL, NULL); // it would be implemented very similar to above and searchFor:... return -1; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.