Skip to content

Instantly share code, notes, and snippets.

@knu
Created June 5, 2009 11:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save knu/124247 to your computer and use it in GitHub Desktop.
Save knu/124247 to your computer and use it in GitHub Desktop.
diff --git a/PTYTextView.m b/PTYTextView.m
index eb83426..088439b 100755
--- a/PTYTextView.m
+++ b/PTYTextView.m
@@ -2626,32 +2626,90 @@ static float strokeWidth, boldStrokeWidth;
y: (int) y
{
static char *urlSet = ".?/:;%=&_-,+~#@!*'()";
- int x1=x, x2=x, y1=y, y2=y;
- int startx=-1, starty=-1, endx, endy;
int w = [dataSource width];
int h = [dataSource numberOfLines];
- unichar c;
-
- for (;x1>=0&&y1>=0;) {
- c = [self _getCharacterAtX:x1 Y:y1];
- if (!c || !(isnumber(c) || isalpha(c) || strchr(urlSet, c))) break;
- startx = x1; starty = y1;
- x1--;
- if (x1<0) y1--, x1=w-1;
+ NSMutableString *url = [NSMutableString string];
+ unichar c = [self _getCharacterAtX:x Y:y];
+
+ if (c == '\0' || !(isalnum(c) || strchr(urlSet, c)))
+ return url;
+
+ // Look for a left edge
+ int leftx = 0;
+ for (int xi = x-1, yi = y; 0 <= xi; xi--) {
+ unichar c = [self _getCharacterAtX:xi Y:yi];
+ if (c == '|' &&
+ ((0 < yi && [self _getCharacterAtX:xi Y:yi-1] == '|') ||
+ (yi < h-1 && [self _getCharacterAtX:xi Y:yi+1] == '|'))) {
+ leftx = xi+1;
+ break;
+ }
}
- if (startx == -1) return nil;
-
- endx = x; endy = y;
- for (;x2<w&&y2<h;) {
- c = [self _getCharacterAtX:x2 Y:y2];
- if (!c || !(isnumber(c) || isalpha(c) || strchr(urlSet, c))) break;
- endx = x2; endy = y2;
- x2++;
- if (x2>=w) y2++, x2=0;
+ //NSLog(@"%s: leftx: %d", __PRETTY_FUNCTION__, leftx);
+
+ // Look for a right edge
+ int rightx = w-1;
+ for (int xi = x+1, yi = y; xi < w; xi++) {
+ unichar c = [self _getCharacterAtX:xi Y:yi];
+ if (c == '|' &&
+ ((0 < yi && [self _getCharacterAtX:xi Y:yi-1] == '|') ||
+ (yi < h-1 && [self _getCharacterAtX:xi Y:yi+1] == '|'))) {
+ rightx = xi-1;
+ break;
+ }
}
+ //NSLog(@"%s: width: %d", __PRETTY_FUNCTION__, w);
+ //NSLog(@"%s: rightx: %d", __PRETTY_FUNCTION__, rightx);
- NSMutableString *url = [[[NSMutableString alloc] initWithString:[self contentFromX:startx Y:starty ToX:endx Y:endy pad: YES]] autorelease];
-
+ // Move to the left
+ {
+ int endx = x-1;
+ for (int xi = endx, yi = y; leftx <= xi && 0 <= yi; xi--) {
+ unichar c = [self _getCharacterAtX:xi Y:yi];
+ if (c == '\0' || !(isalnum(c) || strchr(urlSet, c))) {
+ [url insertString:[self contentFromX:xi+1 Y:yi ToX:endx Y:yi pad: YES]
+ atIndex:0];
+ break;
+ }
+ if (xi == leftx) {
+ [url insertString:[self contentFromX:xi Y:yi ToX:endx Y:yi pad: YES]
+ atIndex:0];
+ if (yi == 0) break;
+ yi--;
+ if (rightx < w-1 && [self _getCharacterAtX:rightx+1 Y:yi] != '|') break;
+ xi = rightx;
+ while (leftx <= xi && [self _getCharacterAtX:xi Y:yi] == '\\') {
+ xi--;
+ }
+ endx = xi;
+ }
+ }
+ }
+ //NSLog(@"%s: url-at-the-left: %@", __PRETTY_FUNCTION__, url);
+
+ // Move to the right
+ {
+ int startx = x;
+ for (int xi = startx+1, yi = y; xi <= rightx && yi < h; xi++) {
+ unichar c = [self _getCharacterAtX:xi Y:yi];
+ if (c == '\0' || !(isalnum(c) || strchr(urlSet, c))) {
+ [url appendString:[self contentFromX:startx Y:yi ToX:xi-1 Y:yi pad: YES]];
+ while (x <= rightx && [self _getCharacterAtX:xi Y:yi] == '\\') {
+ xi++;
+ }
+ if (xi <= rightx) break;
+ } else if (xi == rightx) {
+ [url appendString:[self contentFromX:startx Y:yi ToX:xi Y:yi pad: YES]];
+ } else {
+ continue;
+ }
+ if (yi == h-1) break;
+ yi++;
+ if (0 < leftx && [self _getCharacterAtX:leftx-1 Y:yi] != '|') break;
+ xi = startx = leftx;
+ }
+ }
+ //NSLog(@"%s: url-whole: %@", __PRETTY_FUNCTION__, url);
// Grab the addressbook command
[url replaceOccurrencesOfString:@"\n" withString:@"" options:NSLiteralSearch range:NSMakeRange(0, [url length])];
@@ -2817,8 +2875,33 @@ static float strokeWidth, boldStrokeWidth;
// Check for common types of URLs
NSRange range = [trimmedURLString rangeOfString:@"://"];
- if (range.location == NSNotFound)
+ if (range.location == NSNotFound) {
trimmedURLString = [@"http://" stringByAppendingString:trimmedURLString];
+ } else {
+ for (int i = range.location - 1; 0 <= i; i--) {
+ unichar c = [trimmedURLString characterAtIndex:i];
+ if (!isalnum(c)) {
+ // Remove garbage before the scheme part
+ trimmedURLString = [trimmedURLString substringFromIndex:i + 1];
+ switch (c) {
+ case '(':
+ // If an open parenthesis is right before the
+ // scheme part, remove the closing parenthesis
+ {
+ NSRange closer = [trimmedURLString rangeOfString:@")"];
+ if (closer.location != NSNotFound)
+ trimmedURLString = [trimmedURLString substringToIndex:closer.location];
+ }
+ break;
+ }
+ // Chomp a dot at the end
+ int last = [trimmedURLString length] - 1;
+ if (0 <= last && [trimmedURLString characterAtIndex:last] == '.')
+ trimmedURLString = [trimmedURLString substringToIndex:last];
+ break;
+ }
+ }
+ }
url = [NSURL URLWithString:trimmedURLString];
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment