0

I have an Eclipse plug-in that I created to add Code Completion entries. I configured Eclipse to automatically show code completion as I type (Windows | Preferences | PyDev | Editor | Code Completion | Request completion on all letter chars and '_'?). At first when I typed I kept getting the templates showing instead of my code completion entries, so I removed all the templates ( Windows | Preferences | PyDev | Templates --selected all, then "Remove"). Now when I type it works properly for every other key pressed. For example, when I type 'print', the code completion list drops down with my entries as expected when I press 'p'. However, when I press 'r', the list disappears. When I press 'i' the list shows again, but disappears when I press the next key ('n'), etc. Is this a Pydev defect, or am I doing something wrong? It works fine for the templates and other default code completion, just not for my plug-in. Here is a code snipped of a watered down version of my code:

//...
public class MyPlugin implements IPyDevCompletionParticipant
@Override
public Collection<Object> getGlobalCompletions(CompletionRequest arg0,
    ICompletionState arg1) throws MisconfigurationException {
    String replacementString = "{" + arg0.qualifier + "}";
    int replacementOffset = arg0.documentOffset - arg0.qlen;
    int replacementLength = arg0.qlen;
    int cursorPosition = arg0.documentOffset;
    String displayString = arg0.qualifier;
    final IContextInformation contextInformation = new ContextInformation(
            "displayStr", "message");
    String additionalProposalInfo = "additionalProposalInfo";
    final String bundle = "com.github.EclipseChameleonPlugins";
    final org.eclipse.swt.graphics.Image image = new org.eclipse.swt.graphics.Image(getDisplay(), locateFile(bundle, "icons/smiley.gif").getPath());
    arg0.showTemplates = false;

    final CompletionProposal proposal = new CompletionProposal(
        replacementString, replacementOffset, replacementLength,
        cursorPosition, image, displayString, contextInformation, additionalProposalInfo);

    List<ICompletionProposal> proposals = new ArrayList<ICompletionProposal>();
    // ADD IT...
    proposals.add(proposal);
    final Collection<Object> returnProposals = new ArrayList<Object>(
            proposals);
    return returnProposals;
}

I have searched Google and StackOverflow, and have seen very little about code development for PyDev plug-ins, and nothing that mentions or addresses this issue.

Here are a few of the links I have looked at, but none have answered my question:

Community
  • 1
  • 1
MrMobileMan
  • 152
  • 1
  • 8

1 Answers1

1

Well, plain PyDev behaves as expected for me (i.e.: the code completions appear on all the key strokes).

Now, let's see if we can track it down a bit better:

  1. instead of removing the templates, what you should do is go to the preferences > pydev > editor > code completion (ctx insensitive and common tokens) and disable the 'use common tokens auto code completion?'.

  2. The reference code for you to follow is: com.python.pydev.codecompletion.participant.ImportsCompletionParticipant and com.python.pydev.codecompletion.ctxinsensitive.CtxParticipant (i.e.: the IPyDevCompletionParticipant interface -- as you're doing already)

  3. I think the main issue you're having is because you're not implementing the additional extensions for completions (to validate its context and keep it there) -- either you can make your own subclass of org.python.pydev.editor.codecompletion.AbstractPyCompletionProposalExtension2 or you can use org.python.pydev.editor.codecompletion.PyLinkedModeCompletionProposal (just constructing it with the proper parameters -- I believe it supports having a null IToken -- and you can pass an image to it which will be used if the token is null).

  4. You should probably not mess with the CompletionRequest at that point (when it gets there to an extension it should be considered immutable -- even if it's not in reality).

Fabio Zadrozny
  • 24,814
  • 4
  • 66
  • 78
  • Thanks for the quick response! In answer to your 4 items: (1) 'use common tokens auto code completion' was unchecked, and I was still getting the templates showing up as a second set of code completions--I could toggle between the two with ctrl+space, but didn't want that, so I had to remove the templates under "Templates". (2) OK... (3) That looks promising... I'll give it a try... (4) Was just trying things that didn't work, and forgot to clean that up--good catch. – MrMobileMan Dec 29 '14 at 22:50
  • I implement IPyDevCompletionParticipant while the reference code implements this class + IPyDevCompletionParticipant2. When I try to implement this 2nd interface, I implement the necessary methods (namely computeConsoleCompletions(...)), but it has an IScriptConsoleViewer in the signature that Eclipse is unable to find for me until I added the PyDev shared_interactive_console jar. Am I going about this the right way? I set a break point and it is not hitting the breakpoint in the computeConsoleCompletions(...) method... – MrMobileMan Dec 29 '14 at 23:56
  • The IPyDevCompletionParticipant2.computeConsoleCompletions is not needed -- that's only needed to add completions when a code-completion is asked in the console -- what's needed is ICompletionProposalExtension2 and ICompletionProposalExtension -- which the AbstractPyCompletionProposalExtension2 provides. – Fabio Zadrozny Dec 30 '14 at 00:02
  • I changed the class signature to: "... implements IPyDevCompletionParticipant, IPyDevCompletionParticipant2, ICompletionProposalExtension2, ICompletionProposalExtension" and implemented the necessary methods, but I am still not hitting any of the newly added methods (breakpoints)... Do I need to add anything to my plugin.xml file, to use another extension point? – MrMobileMan Dec 30 '14 at 00:21
  • The only thing you need to do is add an extension point to register your IPyDevCompletionParticipant subclass: -- apart from that, have you tried extending AbstractPyCompletionProposalExtension2? (which has much of that protocol implemented already) – Fabio Zadrozny Dec 30 '14 at 00:43
  • I have had the extension set for pydev_completion in the plugin.xml file, and that's how the plugin is getting triggered. I now am using the following class signature (includnig extending AbstractPyCompletionProposalExtension2) and implementing the needed methods: "public class MyPlugin extends AbstractPyCompletionProposalExtension2 implements IPyDevCompletionParticipant, IPyDevCompletionParticipant2, ICompletionProposalExtension2, ICompletionProposalExtension" I tried switching from Java 8 to Java 7, but get the same results... – MrMobileMan Dec 30 '14 at 16:55
  • ...namely, when I press 'zzzzz' for example, the first 'z' works properly, and I see output from the 0 argument constructor and the "getGlobalCompletionRequest()" methods, and I get the drop-down as expected. However, the 2nd 'z' just causes the drop-down to hide, with none of my methods being hit. For the 0 argument constructor I am now required to call the super constructor, and am using: "super(null, fLen, fLen, fLen, fAdditionalProposalInfo);"--I'm using nulls & 0's for values--but I don't think this would cause the problem... Ideas? – MrMobileMan Dec 30 '14 at 16:56
  • I think that just passing 0s is your problem... (offsets must be correct for it to work). – Fabio Zadrozny Dec 30 '14 at 17:08
  • What should the super() call look like? The 0 arg constructor gets called and has no inputs, then must call super(...) on the first line of the constructor... ideas? – MrMobileMan Dec 30 '14 at 17:14
  • Do you have the code on github so that can take a look there (this thread is becoming too big). – Fabio Zadrozny Dec 30 '14 at 17:15
  • Please let me know if you are able to reproduce this... Thanks! – MrMobileMan Jan 05 '15 at 20:07
  • I'm thinking this is a PyDev defect, as I am NOT seeing this issue with my content-assist/code completion plug-ins for Java, JavaScript, XML, Text, C, or C++... – MrMobileMan Jan 22 '15 at 22:47
  • Ok, just created a pull request for you where it's working. I changed it to work with a SourceToken to make it easier (but it would also work if you created the org.python.pydev.editor.codecompletion.PyLinkedModeCompletionProposal or a subclass of org.python.pydev.editor.codecompletion.AbstractPyCompletionProposalExtension2 and configured it properly). – Fabio Zadrozny Jan 23 '15 at 15:12
  • As a note for the future, the working example lives at: https://github.com/fabioz/PythonPluginProofOfConc and all the code needed (besides registering in the plugin.xml) is in https://github.com/fabioz/PythonPluginProofOfConc/blob/master/PythonPluginProofOfConcept/src/com/github/EclipseChameleonPlugins/ChameleonPythonCompletionProposalComputer.java (method getGlobalCompletions) – Fabio Zadrozny Jan 26 '15 at 00:32
  • Your solution returns SourceTokens instead of CompletionProposals, but I need to return CompletionProposals to replace the typed text with my own text. Using SourceTokens does make it so that it does not drop every other keystroke, BUT it does not allow me to replace the typed text with my own text, which is what I need it to do. – MrMobileMan Feb 04 '15 at 19:57
  • Take a look at org.python.pydev.editor.codecompletion.AbstractPyCodeCompletion.changeItokenToCompletionPropostal(CompletionRequest, List, List, boolean, ICompletionState), which is what converts the IToken to the actual PyLinkedModeCompletionProposal used (which will then properly work for completions in PyDev -- that same code has a simpler version which configured a PyCompletionProposal which is a bit simpler than the PyLinkedModeCompletionProposal and should also work -- albeit with less features). – Fabio Zadrozny Feb 05 '15 at 00:14
  • I'm trying to have something that supports spaces. For example, a plugin that will replace "one tree," "two trees," or "three trees," for example, with the Spanish equivalents, for example: "un arbol," "dos arboles," "tres arboles," but whenever I press the space bar, even with your code, it starts a new token. I am, however, able to create this plug-in with expected behavior w/o any problems for Java, JavaScript, C, C++, and text/html. It seems like a defect in PyDev to me. If you can update the github example to support multiple words, or update PyDev to support it, that would be great. – MrMobileMan Feb 10 '15 at 17:40
  • Hi, unfortunately I don't have time to do that (so, I can't give you any timeline on that as I'm on to doing other things as there are enough details for you to get to that already, but that code is all open source, -- see: http://pydev.org/developers.html for getting it -- so, you can take a look at it and I'm sure it can be tweaked to support any kind of completion you want -- in the worst case having to change something in PyDev itself). I can however offer commercial support to do things for you if you want... (mail me at fabioz.pydev at gmail dot com if you're interested). – Fabio Zadrozny Feb 11 '15 at 17:58
  • This answers my original question, so I will mark it as answered. Thanks for all your help! I still have an unanswered question, and have added it here: http://stackoverflow.com/questions/29609408/pydev-custom-code-complete-plug-in-stops-at-each-new-word – MrMobileMan Apr 13 '15 at 15:39