URL and regex filtering

Hi

I’ve just started playing with snippets and I’m confused about how requirements work with regex.

I’ve made a little extension to swap x dot com back to twitter dot com (for some reason)

#popclip
name: X -> Twitter
requirements: [url]
regex: (.*x\.com.*)
icon: iconify:mdi:twitter
javascript:  popclip.pasteText(popclip.input.text.replace(/x\.com/, 'twitter.com'))
description: Change x dot com to twitter dot com.

I’d have expected this would filter so that only URLs that include x.com activate the extension, but for some reason, this activates on every url.

If I remove the “requirements:” line then it does what I expected and only activates if the selected text has x.com in it.

What am I missing?

Thank you

2 Likes

I’ll need to check the code because I’m not sure what happens if we have both a URL requirement and a regex specified.

I suspect that when the URL requirement is there, it’s overriding the regex.

Yes, the way I’ve written it, if it matches a URL in the text, that wipes out the result of the regex.

I don’t think that is the correct behaviour, so I’ll make a note to alter this for the next version. The way you expected it worked is how I would expect it should work, too.

(Actual PopClip code below in case of any vague interest…)

    if (![PopActionFlags checkRequirements:self.requirements forEvent:event options:options]) return NO;
    if (![PopActionFlags checkRequiredApps:self.requiredApps andExcludedApps:self.excludedApps forEvent:event]) return NO;
    
    // clear match from previous invocation
    [self clearMatch];
    
    // match the regex, if provided
    NSString *const text=event.selectedText.length>0?event.selectedText:@"";
    if (self.jsRegex) {
        self.jsRegex[@"lastIndex"]=0;
        JSValue *const jsRegexResult=[self.jsRegex invokeMethod:@"exec" withArguments:@[text]];
        self.jsRegex[@"lastIndex"]=0;
        if (jsRegexResult.isArray) {
            _regexResult=jsRegexResult;
            _matchedText=jsRegexResult[0].toString;
        }
    }
    else if (self.nativeRegex) {
        NSArray *captureComponents=[text nm_captureComponentsMatchedByRegex:self.nativeRegex];
        _matchedText=[captureComponents safeFirstObject];
        _regexResult=captureComponents;
    }
    else {
        _matchedText=text;
    }
    
    // check those requirements which act like regexes
    if ([self.requirements containsObject:@"httpurl"]||[self.requirements containsObject:@"url"]) {
        _matchedText=[[event.intel.urls safeFirstObject] absoluteString];
    }
    else if ([self.requirements containsObject:@"email"]) {
        _matchedText=[event.intel.emails safeFirstObject];
    }
    else if ([self.requirements containsObject:@"path"]) {
        _matchedText=[event.intel.paths safeFirstObject];
    }
    return self.matchedText!=nil;
2 Likes

Thank you, glad to know I wasn’t missing something obvious.

I also liked looking in on the code, interesting.

1 Like

I have almost the same requirement. @nick is this changed now or it will be part of the future version?

1 Like

The behaviour is now changed in PopClip 2024.3.

Now the url requirement is applied first, then the regex is applied to the url.