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.