2424
2525@interface DVTTextCompletionListWindowController (SCXcodeSwitchExpander)
2626
27- - (void )tryExpandingSwitchStatement ;
27+ - (BOOL )tryExpandingSwitchStatement ;
2828
2929@end
3030
@@ -42,20 +42,23 @@ + (void)load
4242
4343- (BOOL )scSwizzledAcceptCurrentCompletion
4444{
45- [self .currentSession.listWindowController tryExpandingSwitchStatement ];
46- return [self scSwizzledAcceptCurrentCompletion ];
45+ if ([self .currentSession.listWindowController tryExpandingSwitchStatement ]) {
46+ return YES ;
47+ }
48+
49+ return [self scSwizzledAcceptCurrentCompletion ];
4750}
4851
4952@end
5053
5154@implementation DVTTextCompletionListWindowController (SCXcodeSwitchExpander)
5255
53- - (void )tryExpandingSwitchStatement
56+ - (BOOL )tryExpandingSwitchStatement
5457{
5558 IDEIndex *index = [[SCXcodeSwitchExpander sharedSwitchExpander ] index ];
5659
5760 if (index == nil ) {
58- return ;
61+ return NO ;
5962 }
6063
6164 IDEIndexCompletionItem *item = [self _selectedCompletionItem ];
@@ -72,70 +75,98 @@ - (void)tryExpandingSwitchStatement
7275
7376 DVTSourceTextView *textView = (DVTSourceTextView *)self.session .textView ;
7477 if (self.session .wordStartLocation == NSNotFound ) {
75- return ;
78+ return NO ;
7679 }
7780
7881 // Fetch the previous new line
7982 NSRange newLineRange = [textView.string rangeOfString: @" \n " options: NSBackwardsSearch range: NSMakeRange (0 , self .session.wordStartLocation)];
8083 if (newLineRange.location == NSNotFound ) {
81- return ;
84+ return NO ;
8285 }
8386
8487 // See if the current line has a switch statement
8588 NSRange switchRange = [textView.string rangeOfString: @" \\ s+switch\\ s*\\ \( " options: NSRegularExpressionSearch range: NSMakeRange (newLineRange.location, self .session.wordStartLocation - newLineRange.location)];
8689 if (switchRange.location == NSNotFound ) {
87- return ;
90+ return NO ;
8891 }
89-
90- // Insert the selected autocomplete item
91- [self .session insertCurrentCompletion ];
92-
92+
9393 // 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 ;
9797 }
98-
98+
99+ // Insert the selected autocomplete item
100+ [self .session insertCurrentCompletion ];
101+
102+ NSRange selectedRange = textView.selectedRange ;
103+
99104 // 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];
101107 if (closingBracketLocation == NSNotFound ) {
102- return ;
108+ return NO ;
103109 }
104-
105- NSString *switchStatementContents = [self .session.textView.string substringWithRange: NSMakeRange (openingBracketRange.location, closingBracketLocation - openingBracketRange.location)];
106-
110+
107111 // 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)];
110113 if (defaultAutocompletionRange.location != NSNotFound ) {
111- // remove it from the switch
112114 [textView insertText: @" " replacementRange: defaultAutocompletionRange];
115+ closingBracketLocation -= defaultAutocompletionRange.length ;
113116 }
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
116122 NSMutableString *replacementString = [NSMutableString string ];
123+
124+ if ([switchContent stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet ]].length == 0 ) {
125+ [replacementString appendString: @" \n " ];
126+ }
127+
117128 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]];
122131 }
123132 }
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+
128147 // 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 ;
130155 }
131156
132157 break ;
133158 }
159+
160+ return NO ;
134161}
135162
136163- (NSUInteger )matchingBracketLocationForOpeningBracketLocation : (NSUInteger )location inString : (NSString *)string
137164{
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];
139170
140171 NSInteger matchingLocation = location;
141172 NSInteger counter = 1 ;
0 commit comments