Index: /trunk/ICeCoffEE/ICeCoffEE/APEMain.m
===================================================================
--- /trunk/ICeCoffEE/ICeCoffEE/APEMain.m	(revision 434)
+++ /trunk/ICeCoffEE/ICeCoffEE/APEMain.m	(revision 435)
@@ -129,6 +129,8 @@
         if (ICCF_CFBundleIDMatches(bundleID, CFSTR("com.apple.xcode"))) {
 	    if (ICCF_PatchMethod("XCTextView", "ICeCoffEE", "ICeCoffEESuper", "mouseDown:")) {
+		ICCF_PatchMethod("XCTextView", "ICeCoffEE", "ICeCoffEESuper", "clickedOnLink:atIndex:");
 		ICCF_PatchMethod("XCSourceCodeTextView", "ICeCoffEEMenuOnly", "ICeCoffEEMenuSuper", "menuForEvent:");
 		ICCF_PatchMethod("XCDiffTextView", "ICeCoffEE", "ICeCoffEESuper", "mouseDown:");
+		ICCF_PatchMethod("XCDiffTextView", "ICeCoffEE", "ICeCoffEESuper", "clickedOnLink:atIndex:");
 		ICCF_PatchMethod("XCDiffTextView", "ICeCoffEE", "ICeCoffEESuper", "menuForEvent:"); // subclass of PBXTextView; patching both is bad
 	    } else {
@@ -166,4 +168,5 @@
     if (shouldLoadInNSTextView) {
         ICCF_PatchMethod("NSTextView", "ICeCoffEE", "ICeCoffEESuper", "mouseDown:") &&
+	ICCF_PatchMethod("NSTextView", "ICeCoffEE", "ICeCoffEESuper", "clickedOnLink:atIndex:") &&
         ICCF_PatchMethod("NSTextView", "ICeCoffEE", "ICeCoffEESuper", "menuForEvent:");
         ICapeprintf("ICeCoffEE APE: loaded generic NSTextView support\n");
Index: /trunk/ICeCoffEE/ICeCoffEE/ICeCoffEE.m
===================================================================
--- /trunk/ICeCoffEE/ICeCoffEE/ICeCoffEE.m	(revision 434)
+++ /trunk/ICeCoffEE/ICeCoffEE/ICeCoffEE.m	(revision 435)
@@ -224,13 +224,29 @@
         NSRange range = [self selectedRange];
         NSCAssert(range.location != NSNotFound, ICCF_LocalizedString(@"There is no insertion point or selection in the text field where you clicked"));
-    
-        if (range.length == 0) {
-            if (range.location == length) range.location--;
-            range.length = 1;
-            range = ICCF_URLEnclosingRange(s, range);
-            [self setSelectedRange: range affinity: NSSelectionAffinityDownstream stillSelecting: NO];
-        }
-
-        if (ICCF_LaunchURL([s substringWithRange: range], ICCF_KeyboardAction(triggeringEvent)) && ICCF_prefs.textBlinkEnabled) {
+        NSString *url = nil;
+    
+        if ([[self textStorage] attribute: NSLinkAttributeName atIndex: range.location
+                           effectiveRange: NULL] != nil) {
+            NSRange linkRange;
+            id link = [[self textStorage] attribute: NSLinkAttributeName atIndex: range.location longestEffectiveRange: &linkRange inRange: NSMakeRange(0, length)];
+            if (NSMaxRange(range) <= NSMaxRange(linkRange)) {
+                // selection is entirely within link range
+                url = [link isKindOfClass: [NSURL class]] ? [link absoluteString] : link;
+                range = linkRange;
+                [self setSelectedRange: range affinity: NSSelectionAffinityDownstream stillSelecting: NO];
+            }
+        }
+        if (url == nil) {
+            if (range.length == 0) {
+                if (range.location == length) range.location--;
+                range.length = 1;
+                range = ICCF_URLEnclosingRange(s, range);
+                [self setSelectedRange: range affinity: NSSelectionAffinityDownstream stillSelecting: NO];
+            }
+        
+            url = [s substringWithRange: range];
+        }
+
+        if (ICCF_LaunchURL(url, ICCF_KeyboardAction(triggeringEvent)) && ICCF_prefs.textBlinkEnabled) {
             for (unsigned i = 0 ; i < ICCF_prefs.textBlinkCount ; i++) {
                 NSRange emptyRange = {range.location, 0};
@@ -384,5 +400,4 @@
 }
 
-
 @implementation ICeCoffEE
 
@@ -412,4 +427,12 @@
     NSMenu *myMenu = [super menuForEvent: e];
     return ICCF_MenuForEvent(self, myMenu, e);
+}
+
+static BOOL ICCF_inMouseDown;
+
+- (void)clickedOnLink:(id)link atIndex:(unsigned)charIndex;
+{
+    if (!ICCF_inMouseDown)
+        [super clickedOnLink: link atIndex: charIndex];
 }
 
@@ -428,5 +451,10 @@
 
     if (ICCF_enabled && ICCF_prefs.commandClickEnabled && ICCF_EventIsCommandMouseDown(downEvent)) {
-	[super mouseDown: ICCF_MouseDownEventWithModifierFlags(downEvent, YES)];
+        ICCF_inMouseDown = YES;
+        @try {
+            [super mouseDown: ICCF_MouseDownEventWithModifierFlags(downEvent, YES)];
+        } @finally {
+            ICCF_inMouseDown = NO;
+        }
         // we don't actually get a mouseUp event, just wait for mouseDown to return
         NSEvent *upEvent = [[self window] currentEvent];
Index: /trunk/ICeCoffEE/ICeCoffEE/ICeCoffEESuper.m
===================================================================
--- /trunk/ICeCoffEE/ICeCoffEE/ICeCoffEESuper.m	(revision 434)
+++ /trunk/ICeCoffEE/ICeCoffEE/ICeCoffEESuper.m	(revision 435)
@@ -17,4 +17,9 @@
 }
 
+- (void)clickedOnLink:(id)link atIndex:(unsigned)charIndex;
+{
+    [super clickedOnLink: link atIndex: charIndex];
+}
+
 - (void)mouseDown:(NSEvent *)e;
 {
