Skip to content

Commit fb84f42

Browse files
committed
- added breakpoint disabled state highlighting
- reduced number of times breakpoint ranges are calculated - added compatibility plugin for Xcode 6.3 (#38)
1 parent 52ef892 commit fb84f42

8 files changed

+245
-18
lines changed

SCXcodeMinimap.xcodeproj/project.pbxproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
1883080C1A7411930005DF40 /* IDESourceEditor.ideplugin in Resources */ = {isa = PBXBuildFile; fileRef = 1883080B1A7411930005DF40 /* IDESourceEditor.ideplugin */; };
1616
188308101A7411A70005DF40 /* IDESourceEditor in Frameworks */ = {isa = PBXBuildFile; fileRef = 1883080F1A7411A70005DF40 /* IDESourceEditor */; };
1717
188FCC8A1A98B57A0026F529 /* DBGBreakpointAnnotationProvider+SCXcodeMinimap.m in Sources */ = {isa = PBXBuildFile; fileRef = 188FCC891A98B57A0026F529 /* DBGBreakpointAnnotationProvider+SCXcodeMinimap.m */; };
18+
18C2EA5C1A9C7F8A002CEB20 /* DBGBreakpointAnnotation+SCXcodeMinimap.m in Sources */ = {isa = PBXBuildFile; fileRef = 18C2EA5B1A9C7F8A002CEB20 /* DBGBreakpointAnnotation+SCXcodeMinimap.m */; };
1819
18C999FF1A98B04C0008AF54 /* DebuggerUI in Frameworks */ = {isa = PBXBuildFile; fileRef = 18C999FE1A98B04C0008AF54 /* DebuggerUI */; };
1920
18D6AD111A8F727B0082CB3F /* IDEFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 18D6AD101A8F727B0082CB3F /* IDEFoundation.framework */; };
2021
18FE09B61707639E00118FEB /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 18FE09B51707639E00118FEB /* Cocoa.framework */; };
@@ -61,11 +62,14 @@
6162
188FCC881A98B57A0026F529 /* DBGBreakpointAnnotationProvider+SCXcodeMinimap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "DBGBreakpointAnnotationProvider+SCXcodeMinimap.h"; sourceTree = "<group>"; };
6263
188FCC891A98B57A0026F529 /* DBGBreakpointAnnotationProvider+SCXcodeMinimap.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "DBGBreakpointAnnotationProvider+SCXcodeMinimap.m"; sourceTree = "<group>"; };
6364
18B3CEE51A8AA52A00A0873D /* DVTPreferenceSetManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DVTPreferenceSetManager.h; sourceTree = "<group>"; };
65+
18C2EA5A1A9C7F8A002CEB20 /* DBGBreakpointAnnotation+SCXcodeMinimap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "DBGBreakpointAnnotation+SCXcodeMinimap.h"; sourceTree = "<group>"; };
66+
18C2EA5B1A9C7F8A002CEB20 /* DBGBreakpointAnnotation+SCXcodeMinimap.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "DBGBreakpointAnnotation+SCXcodeMinimap.m"; sourceTree = "<group>"; };
6467
18C8F0331A7ECB1300C7A76F /* DVTFoldingLayoutManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DVTFoldingLayoutManager.h; sourceTree = "<group>"; };
6568
18C8F0341A7ECB1300C7A76F /* DVTLayoutManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DVTLayoutManager.h; sourceTree = "<group>"; };
6669
18C999FC1A98AF370008AF54 /* DBGBreakpointAnnotationProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBGBreakpointAnnotationProvider.h; sourceTree = "<group>"; };
6770
18C999FD1A98AF580008AF54 /* DVTAnnotationProvider.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DVTAnnotationProvider.h; sourceTree = "<group>"; };
6871
18C999FE1A98B04C0008AF54 /* DebuggerUI */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = DebuggerUI; path = ../../../../../Applications/Xcode.app/Contents/PlugIns/DebuggerUI.ideplugin/Contents/MacOS/DebuggerUI; sourceTree = "<group>"; };
72+
18CA02B61A9D0DF1001C5CE1 /* IDEBreakpoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IDEBreakpoint.h; sourceTree = "<group>"; };
6973
18D6AD101A8F727B0082CB3F /* IDEFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IDEFoundation.framework; path = ../../../../../Applications/Xcode.app/Contents/Frameworks/IDEFoundation.framework; sourceTree = "<group>"; };
7074
18FE09B21707639E00118FEB /* SCXcodeMinimap.xcplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SCXcodeMinimap.xcplugin; sourceTree = BUILT_PRODUCTS_DIR; };
7175
18FE09B51707639E00118FEB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
@@ -134,6 +138,7 @@
134138
184C117E1A740F8A002A7C65 /* IDESourceCodeEditor.h */,
135139
184C117F1A740F8A002A7C65 /* IDESourceCodeEditorContainerView.h */,
136140
184C11801A740F8A002A7C65 /* IDEViewController.h */,
141+
18CA02B61A9D0DF1001C5CE1 /* IDEBreakpoint.h */,
137142
);
138143
path = "Xcode Headers";
139144
sourceTree = "<group>";
@@ -183,6 +188,8 @@
183188
184C11841A740F97002A7C65 /* SCXcodeMinimapView.m */,
184189
184C11811A740F97002A7C65 /* SCXcodeMinimapSelectionView.h */,
185190
184C11821A740F97002A7C65 /* SCXcodeMinimapSelectionView.m */,
191+
18C2EA5A1A9C7F8A002CEB20 /* DBGBreakpointAnnotation+SCXcodeMinimap.h */,
192+
18C2EA5B1A9C7F8A002CEB20 /* DBGBreakpointAnnotation+SCXcodeMinimap.m */,
186193
188FCC881A98B57A0026F529 /* DBGBreakpointAnnotationProvider+SCXcodeMinimap.h */,
187194
188FCC891A98B57A0026F529 /* DBGBreakpointAnnotationProvider+SCXcodeMinimap.m */,
188195
18FE09BC1707639E00118FEB /* Supporting Files */,
@@ -266,6 +273,7 @@
266273
18FE09C9170764E400118FEB /* SCXcodeMinimap.m in Sources */,
267274
184C11861A740F97002A7C65 /* SCXcodeMinimapSelectionView.m in Sources */,
268275
184C11871A740F97002A7C65 /* SCXcodeMinimapView.m in Sources */,
276+
18C2EA5C1A9C7F8A002CEB20 /* DBGBreakpointAnnotation+SCXcodeMinimap.m in Sources */,
269277
);
270278
runOnlyForDeploymentPostprocessing = 0;
271279
};
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//
2+
// DBGBreakpointAnnotation+SCXcodeMinimap.h
3+
// SCXcodeMinimap
4+
//
5+
// Created by Stefan Ceriu on 24/02/2015.
6+
// Copyright (c) 2015 Stefan Ceriu. All rights reserved.
7+
//
8+
9+
#import "DBGBreakpointAnnotation.h"
10+
11+
@protocol DBGBreakpointAnnotationDelegate;
12+
13+
@interface DBGBreakpointAnnotation (SCXcodeMinimap)
14+
15+
@property (nonatomic, readonly) BOOL enabled;
16+
@property (nonatomic, weak) id<DBGBreakpointAnnotationDelegate> minimapDelegate;
17+
18+
@end
19+
20+
@protocol DBGBreakpointAnnotationDelegate <NSObject>
21+
22+
- (void)breakpointAnnotationDidChangeState:(DBGBreakpointAnnotation *)annotation;
23+
24+
@end
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
//
2+
// DBGBreakpointAnnotation+SCXcodeMinimap.m
3+
// SCXcodeMinimap
4+
//
5+
// Created by Stefan Ceriu on 24/02/2015.
6+
// Copyright (c) 2015 Stefan Ceriu. All rights reserved.
7+
//
8+
9+
#import "DBGBreakpointAnnotation+SCXcodeMinimap.h"
10+
#import <objc/runtime.h>
11+
12+
#import "IDEFileBreakpoint.h"
13+
14+
@implementation DBGBreakpointAnnotation (SCXcodeMinimap)
15+
16+
static void sc_swizzleInstanceMethod(Class class, SEL originalSelector, SEL swizzledSelector) {
17+
Method originalMethod = class_getInstanceMethod(class, originalSelector);
18+
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
19+
if (class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))) {
20+
class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
21+
} else {
22+
method_exchangeImplementations(originalMethod, swizzledMethod);
23+
}
24+
}
25+
26+
+ (void)load
27+
{
28+
sc_swizzleInstanceMethod(self, @selector(_redisplay), @selector(sc_redisplay));
29+
sc_swizzleInstanceMethod(self, @selector(adjustParagraphIndexBy:lengthBy:), @selector(sc_adjustParagraphIndexBy:lengthBy:));
30+
}
31+
32+
- (id<DBGBreakpointAnnotationDelegate>)minimapDelegate
33+
{
34+
return objc_getAssociatedObject(self, @selector(minimapDelegate));
35+
}
36+
37+
- (void)setMinimapDelegate:(id<DBGBreakpointAnnotationDelegate>)minimapDelegate
38+
{
39+
objc_setAssociatedObject(self, @selector(minimapDelegate), minimapDelegate, OBJC_ASSOCIATION_ASSIGN);
40+
}
41+
42+
- (BOOL)enabled
43+
{
44+
if([self.representedObject isKindOfClass:[IDEFileBreakpoint class]]) {
45+
IDEFileBreakpoint *fileBreakpoint = (IDEFileBreakpoint *)self.representedObject;
46+
return fileBreakpoint.shouldBeEnabled;
47+
}
48+
49+
return NO;
50+
}
51+
52+
- (void)sc_redisplay
53+
{
54+
[self sc_redisplay];
55+
56+
if([self.representedObject isKindOfClass:[IDEFileBreakpoint class]]) {
57+
if([self.minimapDelegate respondsToSelector:@selector(breakpointAnnotationDidChangeState:)]) {
58+
[self.minimapDelegate breakpointAnnotationDidChangeState:self];
59+
}
60+
}
61+
}
62+
63+
- (void)sc_adjustParagraphIndexBy:(long long)arg1 lengthBy:(long long)arg2
64+
{
65+
[self sc_adjustParagraphIndexBy:arg1 lengthBy:arg2];
66+
67+
if([self.representedObject isKindOfClass:[IDEFileBreakpoint class]]) {
68+
if([self.minimapDelegate respondsToSelector:@selector(breakpointAnnotationDidChangeState:)]) {
69+
[self.minimapDelegate breakpointAnnotationDidChangeState:self];
70+
}
71+
}
72+
}
73+
74+
@end

SCXcodeMinimap/DBGBreakpointAnnotationProvider+SCXcodeMinimap.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
@interface DBGBreakpointAnnotationProvider (SCXcodeMinimap)
1414

15-
@property (nonatomic, weak) id<DBGBreakpointAnnotationProviderDelegate> delegate;
15+
@property (nonatomic, weak) id<DBGBreakpointAnnotationProviderDelegate> minimapDelegate;
1616

1717
@end
1818

SCXcodeMinimap/DBGBreakpointAnnotationProvider+SCXcodeMinimap.m

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88

99
#import "DBGBreakpointAnnotationProvider+SCXcodeMinimap.h"
1010
#import <objc/runtime.h>
11-
#import "DBGBreakpointAnnotation.h"
11+
12+
#import "DBGBreakpointAnnotation+SCXcodeMinimap.h"
1213

1314
@implementation DBGBreakpointAnnotationProvider (SCXcodeMinimap)
1415

@@ -29,33 +30,61 @@ + (void)load
2930
sc_swizzleInstanceMethod(self, @selector(didMoveAnnotation:), @selector(sc_didMoveAnnotation:));
3031
}
3132

32-
- (void)setDelegate:(id<DBGBreakpointAnnotationProviderDelegate>)delegate
33+
- (void)setMinimapDelegate:(id<DBGBreakpointAnnotationProviderDelegate>)minimapDelegate
3334
{
34-
objc_setAssociatedObject(self, @selector(delegate), delegate, OBJC_ASSOCIATION_ASSIGN);
35+
for(DBGBreakpointAnnotation *annotation in self.annotations) {
36+
[annotation setMinimapDelegate:(id<DBGBreakpointAnnotationDelegate>)self];
37+
}
38+
39+
objc_setAssociatedObject(self, @selector(minimapDelegate), minimapDelegate, OBJC_ASSOCIATION_ASSIGN);
3540
}
3641

37-
- (id<DBGBreakpointAnnotationProviderDelegate>)delegate
42+
- (id<DBGBreakpointAnnotationProviderDelegate>)minimapDelegate
3843
{
39-
return objc_getAssociatedObject(self, @selector(delegate));
44+
return objc_getAssociatedObject(self, @selector(minimapDelegate));
4045
}
4146

4247
- (void)sc_addAnnotationForFileBreakpoint:(id)arg1
4348
{
4449
[self sc_addAnnotationForFileBreakpoint:arg1];
4550

46-
[self.delegate breakpointAnnotationProviderDidChangeBreakpoints:self];
51+
for(DBGBreakpointAnnotation *annotation in self.annotations) {
52+
if([annotation.representedObject isEqual:arg1]) {
53+
[annotation setMinimapDelegate:(id<DBGBreakpointAnnotationDelegate>)self];
54+
}
55+
}
56+
57+
if([self.minimapDelegate respondsToSelector:@selector(breakpointAnnotationProviderDidChangeBreakpoints:)]) {
58+
[self.minimapDelegate breakpointAnnotationProviderDidChangeBreakpoints:self];
59+
}
60+
}
61+
62+
- (void)sc_removeAnnotation:(DBGBreakpointAnnotation *)annotation
63+
{
64+
[annotation setMinimapDelegate:nil];
65+
[self sc_removeAnnotation:annotation];
66+
67+
if([self.minimapDelegate respondsToSelector:@selector(breakpointAnnotationProviderDidChangeBreakpoints:)]) {
68+
[self.minimapDelegate breakpointAnnotationProviderDidChangeBreakpoints:self];
69+
}
4770
}
4871

49-
- (void)sc_removeAnnotation:(id)arg1
72+
- (void)sc_didMoveAnnotation:(DBGBreakpointAnnotation *)annotation
5073
{
51-
[self sc_removeAnnotation:arg1];
74+
[self sc_didMoveAnnotation:annotation];
5275

53-
[self.delegate breakpointAnnotationProviderDidChangeBreakpoints:self];
76+
if([self.minimapDelegate respondsToSelector:@selector(breakpointAnnotationProviderDidChangeBreakpoints:)]) {
77+
[self.minimapDelegate breakpointAnnotationProviderDidChangeBreakpoints:self];
78+
}
5479
}
5580

56-
- (void)sc_didMoveAnnotation:(id)arg1
81+
#pragma mark - DBGBreakpointAnnotationDelegate
82+
83+
- (void)breakpointAnnotationDidChangeState:(DBGBreakpointAnnotation *)annotation
5784
{
58-
[self.delegate breakpointAnnotationProviderDidChangeBreakpoints:self];
85+
if([self.minimapDelegate respondsToSelector:@selector(breakpointAnnotationProviderDidChangeBreakpoints:)]) {
86+
[self.minimapDelegate breakpointAnnotationProviderDidChangeBreakpoints:self];
87+
}
5988
}
6089

6190
@end

SCXcodeMinimap/SCXcodeMinimap-Info.plist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
<string>63FC1C47-140D-42B0-BB4D-A10B2D225574</string>
3232
<string>37B30044-3B14-46BA-ABAA-F01000C27B63</string>
3333
<string>640F884E-CE55-4B40-87C0-8869546CAB7A</string>
34+
<string>992275C1-432A-4CF7-B659-D84ED6D42D3F</string>
3435
</array>
3536
<key>NSHumanReadableCopyright</key>
3637
<string>Copyright © 2013 Stefan Ceriu. All rights reserved.</string>

SCXcodeMinimap/SCXcodeMinimapView.m

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
#import "DVTAnnotationManager.h"
2929
#import "DBGBreakpointAnnotationProvider+SCXcodeMinimap.h"
30+
#import "DBGBreakpointAnnotation+SCXcodeMinimap.h"
3031
#import "DBGBreakpointAnnotation.h"
3132

3233
const CGFloat kBackgroundColorShadowLevel = 0.1f;
@@ -80,6 +81,8 @@ @interface SCXcodeMinimapView () <NSLayoutManagerDelegate, DVTFoldingManagerDele
8081
@property (nonatomic, strong) SCXcodeMinimapTheme *editorTheme;
8182

8283
@property (nonatomic, assign) BOOL shouldAllowFullSyntaxHighlight;
84+
85+
@property (nonatomic, assign) BOOL shouldUpdateBreakpoints;
8386
@property (nonatomic, strong) NSMutableArray *breakpointDictionaries;
8487

8588
@property (nonatomic, weak) DBGBreakpointAnnotationProvider *breakpointAnnotationProvider;
@@ -92,6 +95,7 @@ - (void)dealloc
9295
{
9396
[[NSNotificationCenter defaultCenter] removeObserver:self];
9497
[self.textView.textStorage removeLayoutManager:self.textView.layoutManager];
98+
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(invalidateDisplayForVisibleRange) object:nil];
9599
}
96100

97101
- (instancetype)initWithEditor:(IDESourceCodeEditor *)editor
@@ -135,11 +139,12 @@ - (instancetype)initWithEditor:(IDESourceCodeEditor *)editor
135139
for(NSDictionary *providerDictionary in self.editorTextView.annotationManager.annotationProviders) {
136140
if([providerDictionary[@"annotationProviderObject"] isKindOfClass:[DBGBreakpointAnnotationProvider class]]) {
137141
self.breakpointAnnotationProvider = providerDictionary[@"annotationProviderObject"];
138-
[self.breakpointAnnotationProvider setDelegate:self];
142+
[self.breakpointAnnotationProvider setMinimapDelegate:self];
139143
break;
140144
}
141145
}
142146

147+
self.shouldUpdateBreakpoints = YES;
143148
[self invalidateDisplayForVisibleRange];
144149
}
145150

@@ -258,11 +263,12 @@ - (NSDictionary *)layoutManager:(NSLayoutManager *)layoutManager
258263
if(self.breakpointDictionaries.count) {
259264
for(NSDictionary *breakpointDictionary in self.breakpointDictionaries) {
260265
NSRange range = [breakpointDictionary[kBreakpointRangeKey] rangeValue];
266+
BOOL enabled = [breakpointDictionary[kBreakpointEnabledKey] boolValue];
261267

262268
if(NSIntersectionRange(range, NSMakeRange(charIndex, 1)).length) {
263269
*effectiveCharRange = range;
264270
return @{NSForegroundColorAttributeName : theme.sourceTextBackgroundColor,
265-
NSBackgroundColorAttributeName : theme.enabledBreakpointColor};
271+
NSBackgroundColorAttributeName : (enabled ? theme.enabledBreakpointColor : theme.disabledBreakpointColor)};
266272
}
267273
}
268274
}
@@ -327,7 +333,10 @@ - (void)foldingManager:(DVTFoldingManager *)foldingManager didUnfoldRange:(NSRan
327333

328334
- (void)breakpointAnnotationProviderDidChangeBreakpoints:(DBGBreakpointAnnotationProvider *)annotationProvider
329335
{
330-
[self invalidateDisplayForVisibleRange];
336+
self.shouldUpdateBreakpoints = YES;
337+
338+
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(invalidateDisplayForVisibleRange) object:nil];
339+
[self performSelector:@selector(invalidateDisplayForVisibleRange) withObject:nil afterDelay:kDurationBetweenInvalidations];
331340
}
332341

333342
- (void)updateBreakpoints
@@ -346,12 +355,14 @@ - (void)updateBreakpoints
346355

347356
for(DBGBreakpointAnnotation *breakpointAnnotation in self.breakpointAnnotationProvider.annotations) {
348357
if(breakpointAnnotation.paragraphRange.location == lineNumber) {
349-
[self.breakpointDictionaries addObject:@{kBreakpointRangeKey : [NSValue valueWithRange:lineRange]}];
358+
[self.breakpointDictionaries addObject:@{kBreakpointRangeKey : [NSValue valueWithRange:lineRange], kBreakpointEnabledKey : @(breakpointAnnotation.enabled)}];
350359
}
351360
}
352361

353362
index = NSMaxRange(lineRange);
354363
}
364+
365+
self.shouldUpdateBreakpoints = NO;
355366
}
356367

357368
#pragma mark - Navigation
@@ -511,9 +522,11 @@ - (void)resizeWithOldSuperviewSize:(NSSize)oldSize
511522

512523
- (void)invalidateDisplayForVisibleRange
513524
{
514-
self.shouldAllowFullSyntaxHighlight = YES;
525+
if(self.shouldUpdateBreakpoints) {
526+
[self updateBreakpoints];
527+
}
515528

516-
[self updateBreakpoints];
529+
self.shouldAllowFullSyntaxHighlight = YES;
517530

518531
NSRange visibleMinimapRange = [self.textView visibleCharacterRange];
519532
[self.textView.layoutManager invalidateDisplayForCharacterRange:visibleMinimapRange];

0 commit comments

Comments
 (0)