Completion (word, not syntax) [plus pseudo-patch]

John R. Zedlewski zedlwski at Princeton.EDU
Thu Mar 8 07:14:44 UTC 2001


No, wait!  I'm not going to start up an ancient code completion thread again.  But, for a while, I've been
missing one of my favorite Emacs features in KDevelop: the "completion" command.  At least in my XEmacs, it's
bound to "ALT-/".  Basically, if this command is invoked when the cursor is on an incomplete word, it'll
attempt to find an earlier word which has the current word as its prefix.  It then inserts that word at the
current position.  So, if I had:
"KAddClassLongNameDialog d = ...;
KAdd[Cursor Here]"  when I invoked "ALT-/", XEmacs would automatically expand "KAdd" to
"KAddClassLongNameDialog".  Very handy for long class names.

Anyways, it was actually pretty easy to add a simple version of this to KDev 1.4.  But I don't have a clean
copy of the source lying around, and this is just a 1/2 hour hack, so I don't really have a good diff.  If
anybody else is interested in using this, let me know what you think of the code and I can clean some stuff up
and make a real diff.

But, just so you can try it, here's what I did:

 I created a "doCompletion(VConfig& c)" method in the KWrite class and bound it to "CTRL-/" (but you can pick
the key of your choice, obviously), by adding the following code to KWrite::keyPressEvent's control+key
handling (to be precise, I inserted it at line 1200 in kwview.cpp):

        case Key_Slash:
          kWrite->doCompletion(c);
          break;

Then, I added the following code to the end of "kwview.cpp" to implement the function:

#include <iostream.h>

/** Attempts EMACS-style word completion at
the current cursor point */

void KWrite::doCompletion(VConfig& c){
 QString curWord = currentWord();
 cout << "Trying to complete: " << curWord << endl;
 addToStrList( searchForList, curWord );

 // Setup basic search options
 SConfig search;
 search.cursor = c.cursor;
 search.cursor.x -= 1;
 search.startCursor = c.cursor;
 search.startCursor.x += 1;

 // Give precedence to words occuring above current cursor
 search.flags = sfBackward;

 // based on code from searchAgain
  int query;
  int slen;
  QString str;

  const char *searchFor = searchForList.getFirst();

  slen = strlen(searchFor);

  while ( true ) {
    cout << "Searching for " << searchFor << endl;
    if (kWriteDoc->doSearch(search,searchFor)) {
     cout << "Found word" << endl;
     // Figure out what word we found that contains the current substring
      QString foundWord = kWriteDoc->getWord(search.cursor);
      cout << "Should complete with " << foundWord << endl;

      // Look only for strings that BEGIN with the current substring
      if (!foundWord.startsWith( searchFor ) ) {
    // Don't want to keep finding this same word!
    s.cursor.x -= 1;
    // Go back and search again for a real match
    continue;
      }

      // Grab the remainder of the word and insert it at the current cursor
      int foundWordLen = foundWord.length();
      QString textToAdd = foundWord.right(foundWordLen - slen);
      cout << "Should add " << textToAdd << endl;
      kWriteDoc->insert(kWriteView, c, textToAdd);
      break;

    } else {
     // Automatically wrap around and search from end
   if (!(search.flags & sfFinished)) {
    search.flags |= sfFinished;
    search.cursor.x = -1;
    search.cursor.y = kWriteDoc->lastLine();
    query = 0;
    continue;
   } else {
    // If we've already looped around, just quit, because we won't find anything
    break;
   }
    }
  }  // End of while ( true )

  // Now, we're done searching for this word, so pop it off the list
  searchForList.remove( 0 );
}


Well, that's it!  Someday soon, I hope to add real emacs-style kill-line/yank-line handling (the one other
emacs-ism that I can't live without).  Plus, there's a lot that you could do to make this completion function
smarter.  Since it looks upwards from the current cursor, though, it tends to do a pretty good job of finding
the right completion (provided that you give it at least 3-4 letters to start with).
  Oh, and I just realized that there's a bug if the cursor is currently in the middle of a word, rather than
at the end.
--JRZ


-
to unsubscribe from this list send an email to kdevelop-devel-request at kdevelop.org with the following body:
unsubscribe »your-email-address«



More information about the KDevelop-devel mailing list