Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSTextField autocompletion delegate method not called

I implemented the following delegate method for NSTextField to add autocompletion support:

- (NSArray *)control:(NSControl *)control
            textView:(NSTextView *)textView
         completions:(NSArray *)words
 forPartialWordRange:(NSRange)charRange
 indexOfSelectedItem:(NSInteger *)index

The issue is that this method never gets called. I can verify that the delegate of the NSTextField is set properly because the other delegate methods function as they should.

like image 217
indragie Avatar asked Apr 02 '11 19:04

indragie


1 Answers

You'll need to get complete: called on the text field's field editor at some point. That's what triggers the completions menu, but it doesn't get called automatically. If you don't have F5 bound to anything, try typing in your field and hit that. Completion should trigger then; Option-Esc may also work.

If you want auto completion, it takes some work. You could start with something like this:

- (void)controlTextDidChange:(NSNotification *)note {
    if( amDoingAutoComplete ){
        return;
    } else {
        amDoingAutoComplete = YES;
        [[[note userInfo] objectForKey:@"NSFieldEditor"] complete:nil];
    }
}

Some kind of flag is necessary because triggering completion will make NSControlTextDidChangeNotification be posted again, which causes this to be called, triggering completion, which changes the control text, which...

Obviously, you'll need to unset the flag at some point. This will depend on how you want to handle the user's interaction with autocompletion -- is there likely to only be one completion for a given start string, or will the user need to keep typing to narrow down possibilities (in which case you'll need to trigger autocompletion again)?

A simple flag might not quite do it, either; it seems that although the notification is re-posted, the field editor's string won't have changed -- it will only change in response to direct keyboard input. In my implementation of autocomplete, I found that I had to keep a copy of the "last typed string" and compare that each time to the field editor's contents.

like image 169
jscs Avatar answered Oct 22 '22 13:10

jscs