24
24
25
25
@interface DVTTextCompletionListWindowController (SCXcodeSwitchExpander)
26
26
27
- - (void )tryExpandingSwitchStatement ;
27
+ - (BOOL )tryExpandingSwitchStatement ;
28
28
29
29
@end
30
30
@@ -42,20 +42,23 @@ + (void)load
42
42
43
43
- (BOOL )scSwizzledAcceptCurrentCompletion
44
44
{
45
- [self .currentSession.listWindowController tryExpandingSwitchStatement ];
46
- return [self scSwizzledAcceptCurrentCompletion ];
45
+ if ([self .currentSession.listWindowController tryExpandingSwitchStatement ]) {
46
+ return YES ;
47
+ }
48
+
49
+ return [self scSwizzledAcceptCurrentCompletion ];
47
50
}
48
51
49
52
@end
50
53
51
54
@implementation DVTTextCompletionListWindowController (SCXcodeSwitchExpander)
52
55
53
- - (void )tryExpandingSwitchStatement
56
+ - (BOOL )tryExpandingSwitchStatement
54
57
{
55
58
IDEIndex *index = [[SCXcodeSwitchExpander sharedSwitchExpander ] index ];
56
59
57
60
if (index == nil ) {
58
- return ;
61
+ return NO ;
59
62
}
60
63
61
64
IDEIndexCompletionItem *item = [self _selectedCompletionItem ];
@@ -72,70 +75,98 @@ - (void)tryExpandingSwitchStatement
72
75
73
76
DVTSourceTextView *textView = (DVTSourceTextView *)self.session .textView ;
74
77
if (self.session .wordStartLocation == NSNotFound ) {
75
- return ;
78
+ return NO ;
76
79
}
77
80
78
81
// Fetch the previous new line
79
82
NSRange newLineRange = [textView.string rangeOfString: @" \n " options: NSBackwardsSearch range: NSMakeRange (0 , self .session.wordStartLocation)];
80
83
if (newLineRange.location == NSNotFound ) {
81
- return ;
84
+ return NO ;
82
85
}
83
86
84
87
// See if the current line has a switch statement
85
88
NSRange switchRange = [textView.string rangeOfString: @" \\ s+switch\\ s*\\ \( " options: NSRegularExpressionSearch range: NSMakeRange (newLineRange.location, self .session.wordStartLocation - newLineRange.location)];
86
89
if (switchRange.location == NSNotFound ) {
87
- return ;
90
+ return NO ;
88
91
}
89
-
90
- // Insert the selected autocomplete item
91
- [self .session insertCurrentCompletion ];
92
-
92
+
93
93
// Fetch the opening bracket for that switch statement
94
- NSRange openingBracketRange = [textView.string rangeOfString: @" {" options: 0 range: NSMakeRange (self .session.wordStartLocation, textView.string.length - self .session.wordStartLocation)];
95
- if (openingBracketRange. location == NSNotFound ) {
96
- return ;
94
+ NSUInteger openingBracketLocation = [textView.string rangeOfString: @" {" options: 0 range: NSMakeRange (self .session.wordStartLocation, textView.string.length - self .session.wordStartLocation)]. location ;
95
+ if (openingBracketLocation == NSNotFound ) {
96
+ return NO ;
97
97
}
98
-
98
+
99
+ // Insert the selected autocomplete item
100
+ [self .session insertCurrentCompletion ];
101
+
102
+ NSRange selectedRange = textView.selectedRange ;
103
+
99
104
// Fetch the closing bracket for that switch statement
100
- NSUInteger closingBracketLocation = [self matchingBracketLocationForOpeningBracketLocation: openingBracketRange.location inString: self .session.textView.string];
105
+ NSUInteger closingBracketLocation = [self matchingBracketLocationForOpeningBracketLocation: openingBracketLocation
106
+ inString: textView.string];
101
107
if (closingBracketLocation == NSNotFound ) {
102
- return ;
108
+ return NO ;
103
109
}
104
-
105
- NSString *switchStatementContents = [self .session.textView.string substringWithRange: NSMakeRange (openingBracketRange.location, closingBracketLocation - openingBracketRange.location)];
106
-
110
+
107
111
// Get rid of the default autocompletion if necessary
108
- NSRange defaultAutocompletionRange = [self .session.textView.string rangeOfString: @" \\ s*case <#constant#>:\\ s*<#statements#>\\ s*break;" options: NSRegularExpressionSearch];
109
-
112
+ NSRange defaultAutocompletionRange = [textView.string rangeOfString: @" \\ s*case <#constant#>:\\ s*<#statements#>\\ s*break;\\ s*default:\\ s*break;\\ s*" options: NSRegularExpressionSearch range: NSMakeRange (openingBracketLocation, closingBracketLocation - openingBracketLocation)];
110
113
if (defaultAutocompletionRange.location != NSNotFound ) {
111
- // remove it from the switch
112
114
[textView insertText: @" " replacementRange: defaultAutocompletionRange];
115
+ closingBracketLocation -= defaultAutocompletionRange.length ;
113
116
}
114
-
115
- // Generate the items to insert
117
+
118
+ NSRange switchContentRange = NSMakeRange (openingBracketLocation + 1 , closingBracketLocation - openingBracketLocation - 1 );
119
+ NSString *switchContent = [textView.string substringWithRange: switchContentRange];
120
+
121
+ // Generate the items to insert and insert them at the end
116
122
NSMutableString *replacementString = [NSMutableString string ];
123
+
124
+ if ([switchContent stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet ]].length == 0 ) {
125
+ [replacementString appendString: @" \n " ];
126
+ }
127
+
117
128
for (IDEIndexSymbol *child in [((IDEIndexContainerSymbol*)symbol).children allObjects ]) {
118
-
119
- if ([switchStatementContents rangeOfString: child.displayName].location == NSNotFound )
120
- {
121
- [replacementString appendString: [NSString stringWithFormat: @" \n case %@ :\n <#statement#>\n break;" , child.displayName]];
129
+ if ([switchContent rangeOfString: child.displayName].location == NSNotFound ) {
130
+ [replacementString appendString: [NSString stringWithFormat: @" case %@ : {\n <#statement#>\n break;\n }\n " , child.displayName]];
122
131
}
123
132
}
124
-
125
- // Insert the generated items
126
- [textView insertText: replacementString replacementRange: NSMakeRange (openingBracketRange.location + 1 , 1 )];
127
-
133
+
134
+ [textView insertText: replacementString replacementRange: NSMakeRange (switchContentRange.location + switchContentRange.length, 0 )];
135
+
136
+ closingBracketLocation += replacementString.length ;
137
+ switchContentRange = NSMakeRange (openingBracketLocation + 1 , closingBracketLocation - openingBracketLocation - 1 );
138
+ switchContent = [textView.string substringWithRange: switchContentRange];
139
+
140
+ // Insert the default case if necessary
141
+ if ([switchContent rangeOfString: @" default" ].location == NSNotFound ) {
142
+ replacementString = [NSMutableString stringWithString: @" default: {\n break;\n }\n " ];
143
+ [textView insertText: replacementString replacementRange: NSMakeRange (switchContentRange.location + switchContentRange.length, 0 )];
144
+ closingBracketLocation += replacementString.length ;
145
+ }
146
+
128
147
// Re-indent everything
129
- [textView _indentInsertedTextIfNecessaryAtRange: NSMakeRange (openingBracketRange.location + 1 , replacementString.length)];
148
+ NSRange reindentRange = NSMakeRange (openingBracketLocation, closingBracketLocation - openingBracketLocation + 2 );
149
+ [textView _indentInsertedTextIfNecessaryAtRange: reindentRange];
150
+
151
+ // Preserve the selected range
152
+ [textView setSelectedRange: selectedRange];
153
+
154
+ return YES ;
130
155
}
131
156
132
157
break ;
133
158
}
159
+
160
+ return NO ;
134
161
}
135
162
136
163
- (NSUInteger )matchingBracketLocationForOpeningBracketLocation : (NSUInteger )location inString : (NSString *)string
137
164
{
138
- const char *cString = [self .session.textView.string cStringUsingEncoding: NSUTF8StringEncoding];
165
+ if (string.length == 0 ) {
166
+ return NSNotFound ;
167
+ }
168
+
169
+ const char *cString = [string cStringUsingEncoding: NSUTF8StringEncoding];
139
170
140
171
NSInteger matchingLocation = location;
141
172
NSInteger counter = 1 ;
0 commit comments