Changeset 3238

Show
Ignore:
Timestamp:
05/31/06 02:34:22 (2 years ago)
Author:
timothy
Message:

Landed the patch for #644. This allows pressing TAB without starting a word to complete the nickname of the last user to send a message to the room with a highlight word, or the last completed nick. This only works if you are at the beginning of the line.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/Panels/JVChatRoomPanel.m

    r3207 r3238  
    602602        NSMutableArray *possibleNicks = [NSMutableArray array]; 
    603603        NSString *name = nil; 
     604 
     605        if( [prefix isEqualToString:@""] ) { 
     606                if( [_preferredTabCompleteNicknames count] ) 
     607                        [possibleNicks addObject:[_preferredTabCompleteNicknames objectAtIndex:0]]; 
     608                return possibleNicks; 
     609        } 
    604610 
    605611        enumerator = [_preferredTabCompleteNicknames objectEnumerator]; 
  • trunk/Views/MVTextView.m

    r3072 r3238  
    1212- (id)initWithFrame:(NSRect)frameRect textContainer:(NSTextContainer *)aTextContainer { 
    1313        if( (self = [super initWithFrame:frameRect textContainer:aTextContainer] ) ) 
    14                 defaultTypingAttributes = [[NSDictionary alloc] init]; 
     14                defaultTypingAttributes = [[NSDictionary allocWithZone:nil] init]; 
    1515        return self; 
    1616} 
     
    3232 
    3333- (void) interpretKeyEvents:(NSArray *) eventArray { 
    34         NSMutableArray *newArray = [NSMutableArray array]; 
     34        NSMutableArray *newArray = [[NSMutableArray allocWithZone:nil] init]; 
    3535        NSEnumerator *e = [eventArray objectEnumerator]; 
    3636        NSEvent *anEvent = nil; 
     
    5656        if( [newArray count] > 0 ) 
    5757                [super interpretKeyEvents:newArray]; 
     58 
     59        [newArray release]; 
    5860} 
    5961 
     
    124126        if( ! font ) { 
    125127                font = [NSFont userFontOfSize:0.]; 
    126                 defaultTypingAttributes = [[NSDictionary alloc] init]; 
    127         } else defaultTypingAttributes = [[NSDictionary dictionaryWithObject: font forKey: NSFontAttributeName] retain]; 
     128                defaultTypingAttributes = [[NSDictionary allocWithZone:nil] init]; 
     129        } else defaultTypingAttributes = [[NSDictionary allocWithZone:nil] initWithObjectsAndKeys:font, NSFontAttributeName, nil]; 
    128130        [self setTypingAttributes:defaultTypingAttributes]; 
    129131        [self setFont:font]; 
     
    160162        unsigned int count = 0, i = 0; 
    161163        NSRectArray rects = NULL; 
    162         NSCursor *linkCursor = [[[NSCursor alloc] initWithImage:[NSImage imageNamed:@"MVLinkCursor"] hotSpot:NSMakePoint( 6., 0. )] autorelease]; 
     164        NSCursor *linkCursor = [[[NSCursor allocWithZone:nil] initWithImage:[NSImage imageNamed:@"MVLinkCursor"] hotSpot:NSMakePoint( 6., 0. )] autorelease]; 
    163165 
    164166        [super resetCursorRects]; 
     
    207209                } 
    208210        } else { 
    209                 NSMutableDictionary *attributes = [NSMutableDictionary dictionaryWithDictionary:[self typingAttributes]]; 
     211                NSMutableDictionary *attributes = [[self typingAttributes] mutableCopyWithZone:nil]; 
    210212                NSFont *font = [attributes objectForKey:NSFontAttributeName]; 
    211213                if( ! font ) font = [NSFont userFontOfSize:0.]; 
     
    215217                [attributes setObject:font forKey:NSFontAttributeName]; 
    216218                [self setTypingAttributes:attributes]; 
     219                [attributes release]; 
    217220        } 
    218221} 
     
    239242                } 
    240243        } else { 
    241                 NSMutableDictionary *attributes = [NSMutableDictionary dictionaryWithDictionary:[self typingAttributes]]; 
     244                NSMutableDictionary *attributes = [[self typingAttributes] mutableCopyWithZone:nil]; 
    242245                NSFont *font = [attributes objectForKey:NSFontAttributeName]; 
    243246                if( ! font ) font = [NSFont userFontOfSize:0.]; 
     
    247250                [attributes setObject:font forKey:NSFontAttributeName]; 
    248251                [self setTypingAttributes:attributes]; 
     252                [attributes release]; 
    249253        } 
    250254} 
     
    258262        if( [color alphaComponent] == 0. ) color = nil; 
    259263        if( ! range.length ) { 
    260                 NSMutableDictionary *attributes = [NSMutableDictionary dictionaryWithDictionary:[self typingAttributes]]; 
     264                NSMutableDictionary *attributes = [[self typingAttributes] mutableCopyWithZone:nil]; 
    261265                [attributes setObject:color forKey:NSBackgroundColorAttributeName]; 
    262266                [self setTypingAttributes:attributes]; 
     267                [attributes release]; 
    263268        } else [[self textStorage] addAttribute:NSBackgroundColorAttributeName value:color range:range]; 
    264269} 
     
    296301                return YES; 
    297302        } 
     303         
     304        [_lastCompletionMatch release]; 
     305        _lastCompletionMatch = nil; 
     306 
     307        [_lastCompletionPrefix release]; 
     308        _lastCompletionPrefix = nil; 
    298309 
    299310        NSMutableCharacterSet *allowedCharacters = (NSMutableCharacterSet *)[NSMutableCharacterSet alphanumericCharacterSet]; 
     
    313324        partialCompletion = [[self string] substringWithRange:theRange]; 
    314325 
    315         // continue if necessary 
    316         if( ! [partialCompletion isEqualToString:@""] ) { 
    317                 // compile list of possible completions 
    318                 NSArray *possibleNicks = [[self delegate] textView:self stringCompletionsForPrefix:partialCompletion]; 
    319                 NSString *name = nil; 
    320  
    321                 // insert word or suggestion 
    322                 if( [possibleNicks count] == 1 && ( curPos.location == [[self string] length] || [illegalCharacters characterIsMember:[[self string] characterAtIndex:curPos.location]] ) ) { 
     326        // only allow an empty tab completion if the current position is zero, this feels best in practice 
     327        if( curPos.location && ! [partialCompletion length] ) { 
     328                NSBeep(); 
     329                return YES; 
     330        } 
     331 
     332        // compile list of possible completions 
     333        NSArray *possibleNicks = [[self delegate] textView:self stringCompletionsForPrefix:partialCompletion]; 
     334        NSString *name = nil; 
     335 
     336        // insert word or suggestion 
     337        if( [possibleNicks count] == 1 && ( curPos.location == [[self string] length] || [illegalCharacters characterIsMember:[[self string] characterAtIndex:curPos.location]] ) ) { 
     338                name = [possibleNicks objectAtIndex:0]; 
     339                NSRange replacementRange = NSMakeRange( curPos.location - [partialCompletion length], [partialCompletion length] ); 
     340 
     341                _ignoreSelectionChanges = YES; 
     342                [self replaceCharactersInRange:replacementRange withString:name]; 
     343 
     344                if( suffix && replacementRange.location == 0 ) [self insertText:@": "]; 
     345                else if( suffix ) [self insertText:@" "]; 
     346                _tabCompletting = NO; 
     347                _ignoreSelectionChanges = NO; 
     348 
     349                if( [[self delegate] respondsToSelector:@selector( textView:selectedCompletion:fromPrefix: )] ) 
     350                        [[self delegate] textView:self selectedCompletion:name fromPrefix:partialCompletion]; 
     351        } else if( [possibleNicks count] > 1 ) { 
     352                // since several are available, we highlight the modified text 
     353                NSRange wordRange; 
     354                BOOL full = YES; 
     355 
     356                [_lastCompletionPrefix release]; 
     357                _lastCompletionPrefix = [partialCompletion copyWithZone:nil]; 
     358 
     359                if( curPos.location == [[self string] length] || [illegalCharacters characterIsMember:[[self string] characterAtIndex:curPos.location]] ) { 
     360                        wordRange = NSMakeRange( curPos.location - [partialCompletion length], [partialCompletion length] ); 
    323361                        name = [possibleNicks objectAtIndex:0]; 
    324                         NSRange replacementRange = NSMakeRange( curPos.location - [partialCompletion length], [partialCompletion length] ); 
    325  
    326                         _ignoreSelectionChanges = YES; 
    327                         [self replaceCharactersInRange:replacementRange withString:name]; 
    328  
    329                         if( suffix && replacementRange.location == 0 ) [self insertText:@": "]; 
    330                         else if( suffix ) [self insertText:@" "]; 
    331                         _tabCompletting = NO; 
    332                         _ignoreSelectionChanges = NO; 
    333  
    334                         if( [[self delegate] respondsToSelector:@selector( textView:selectedCompletion:fromPrefix: )] ) 
    335                                 [[self delegate] textView:self selectedCompletion:name fromPrefix:partialCompletion]; 
    336                 } else if( [possibleNicks count] > 1 ) { 
    337                         // since several are available, we highlight the modified text 
    338                         NSRange wordRange; 
    339                         BOOL full = YES; 
    340  
    341                         [_lastCompletionPrefix release]; 
    342                         _lastCompletionPrefix = [partialCompletion retain]; 
    343  
    344                         if( curPos.location == [[self string] length] || [illegalCharacters characterIsMember:[[self string] characterAtIndex:curPos.location]] ) { 
    345                                 wordRange = NSMakeRange( curPos.location - [partialCompletion length], [partialCompletion length] ); 
    346                                 name = [possibleNicks objectAtIndex:0]; 
    347                         } else { 
    348                                 wordRange = [[self string] rangeOfCharacterFromSet:illegalCharacters options:0 range:NSMakeRange( curPos.location, [[self string] length] - curPos.location )]; 
    349                                 if( wordRange.location == NSNotFound ) 
    350                                         wordRange = NSMakeRange( NSMaxRange( wordStart ), [[self string] length] - NSMaxRange( wordStart )) ; 
    351                                 else wordRange = NSMakeRange( NSMaxRange( wordStart ), wordRange.location - NSMaxRange( wordStart )); 
    352  
    353                                 NSString *tempWord = [[self string] substringWithRange:wordRange]; 
    354                                 BOOL keepSearching = YES; 
    355                                 int count = 0; 
    356  
    357                                 do { 
    358                                         keepSearching = ! [[possibleNicks objectAtIndex:count] isEqualToString:tempWord]; 
    359                                 } while ( ++count < [possibleNicks count] && keepSearching ); 
    360  
    361                                 if( count == [possibleNicks count] ) count = 0; 
    362  
    363                                 name = [possibleNicks objectAtIndex:count]; 
    364                                 full = NO; 
    365                         } 
    366  
    367                         [_lastCompletionMatch release]; 
    368                         _lastCompletionMatch = [name retain]; 
    369  
    370                         if( suffix && wordRange.location == 0 ) name = [name stringByAppendingString:@": "]; 
    371                         else if( suffix ) name = [name stringByAppendingString:@" "]; 
    372  
    373                         _ignoreSelectionChanges = YES; 
    374                         [self replaceCharactersInRange:wordRange withString:( full ? name : _lastCompletionMatch )]; 
    375                         [self setSelectedRange:NSMakeRange( curPos.location, [name length] - [partialCompletion length] )]; 
    376                         _ignoreSelectionChanges = NO; 
    377362                } else { 
    378                         NSBeep(); // no matches 
    379                         _tabCompletting = NO; 
    380                 } 
     363                        wordRange = [[self string] rangeOfCharacterFromSet:illegalCharacters options:0 range:NSMakeRange( curPos.location, [[self string] length] - curPos.location )]; 
     364                        if( wordRange.location == NSNotFound ) 
     365                                wordRange = NSMakeRange( NSMaxRange( wordStart ), [[self string] length] - NSMaxRange( wordStart )) ; 
     366                        else wordRange = NSMakeRange( NSMaxRange( wordStart ), wordRange.location - NSMaxRange( wordStart )); 
     367 
     368                        NSString *tempWord = [[self string] substringWithRange:wordRange]; 
     369                        BOOL keepSearching = YES; 
     370                        int count = 0; 
     371 
     372                        do { 
     373                                keepSearching = ! [[possibleNicks objectAtIndex:count] isEqualToString:tempWord]; 
     374                        } while ( ++count < [possibleNicks count] && keepSearching ); 
     375 
     376                        if( count == [possibleNicks count] ) count = 0; 
     377 
     378                        name = [possibleNicks objectAtIndex:count]; 
     379                        full = NO; 
     380                } 
     381 
     382                [_lastCompletionMatch release]; 
     383                _lastCompletionMatch = [name copyWithZone:nil]; 
     384 
     385                if( suffix && wordRange.location == 0 ) name = [name stringByAppendingString:@": "]; 
     386                else if( suffix ) name = [name stringByAppendingString:@" "]; 
     387 
     388                _ignoreSelectionChanges = YES; 
     389                [self replaceCharactersInRange:wordRange withString:( full ? name : _lastCompletionMatch )]; 
     390                [self setSelectedRange:NSMakeRange( curPos.location, [name length] - [partialCompletion length] )]; 
     391                _ignoreSelectionChanges = NO; 
    381392        } else { 
    382                 [_lastCompletionMatch release]; 
    383                 _lastCompletionMatch = nil; 
    384  
    385                 [_lastCompletionPrefix release]; 
    386                 _lastCompletionPrefix = nil; 
     393                NSBeep(); // no matches 
     394                _tabCompletting = NO; 
    387395        } 
    388396