PyDev custom code complete plug-in only detects every other key stroke - eclipse-plugin

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:
Auto-completion in PyDev
Code completion for custom modules not working with PyDev
pydev remote debuging - code completion in interactive console?

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:
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?'.
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)
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).
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).

Related

Plugin that runs tests based on file of user

I am developing a Plugin for IntelliJ for teaching purposes, where students write some code and the teacher can write tests and the students can run those tests and see if they are doing it all correctly. It would be great if I would get the file the user is writing in as a java class so that I can run the functions of that class from within another function and test it as if I would have written it.
What I have as of now:
In the Main Toolbar I have a button, where the students should be able to run the tests. I have a class that extends AnAction, now I have no Idea what I should write in it:
#Override
public void actionPerformed(AnActionEvent e) {
}
I have been going through the IntelliJ documentation for some time now and as by now I do not get any further. I sure hope that the experienced developers that can be found here can manybe give me a hint or two.
Thanks a lot in advance :)
If I understand correctly, the students would be programming within a project within IntelliJ?
Then you can get the path to the project that they are working on using the AnActionEvent event.
Project project = event.getProject();
String projectBasePath = project.getBasePath();
You could use this to send the entire src folder to your computer and do what it is that you need to do there?
But, it also sounds like you would want the students to run the test functions on their side via the plugin. In that case, one option that I know of is to again use the project.getBasePath(), or get them to select a file using a GUI, and then use ProcessBuilder to compile, run, test, etc their Java classes. You can run any Windows / shell command this way and pipe the output into the IDE, or your own tool window.
public void actionPerformed(AnActionEvent event) {
Project project = event.getProject();
String projectBasePath = project.getBasePath();
ProcessBuilder pb = new ProcessBuilder();
pb.directory(projectBasepath);
pb.command("cmd", "/k", "javac src\*.java")
pb.redirectErrorStream(true);
Process process = pb.start();
BufferedReader reader = new BufferedReader(newInputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
int exitCode = process.waitFor();
System.out.println("\nExited with error code : " + exitCode);
... // anything else you need to do
}
Let me know if this makes sense - maybe I can help you out more if you give me more specific questions.

Manually trigger completion popup in IntelliJ Platform SDK

I am developing a plugin for the IntelliJ Platform. I have created an implementation of CompletionContributor, and it is successfully giving suggestions. I'm currently overriding the invokeAutoPopup method to trigger the completion popup. I'm using an implementation of InsertHandler to add additional text to the document immediately after making the selected insertion.
However, I'd like to make it so that when a user successfully inserts the suggestion, they are immediately prompted with another completion popup. For example, in this InsertHandler (written in Kotlin), after selecting a method, they should be immediately given suggestions about the parameters to that method:
val handler = InsertHandler<LookupElement> { context: InsertionContext, element: LookupElement ->
val offset = context.tailOffset
context.document.insertString(offset, "()")
context.editor.caretModel.moveToOffset(offset + 1)
TODO("trigger popup")
}
Or immediately after selecting a field, they could be given methods that they can call on that field:
val handler = InsertHandler<LookupElement> { context: InsertionContext, element: LookupElement ->
val offset = context.tailOffset
context.document.insertString(offset, ".")
context.editor.caretModel.moveToOffset(offset + 1)
TODO("trigger popup")
}
In other words, I'd like to make it so that after inserting suggested text, it is as if the user pressed Ctrl+Space. Is this possible? Am I approaching the problem in the right way? Is there something in my code above that's missing the point? (Solutions in either Java or Kotlin would be welcome.)
If autopopup completion is enough for your needs, you could try invoking com.intellij.codeInsight.AutoPopupController.getInstance(context.project).scheduleAutoPopup(context.editor).

Howto tell PowerBuilder to pass options to a JVM when starting?

What I want to do?
I want to create and consume java objects in PowerBuilder and call methods on it. This should happen with less overhead possible.
I do not want to consume java webservices!
So I've a working sample in which I can create a java object, call a method on this object and output the result from the called method.
Everything is working as expected. I'm using Java 1.8.0_31.
But now I want to attach my java IDE (IntelliJ) to the running JVM (started by PowerBuilder) to debug the java code which gets called by PowerBuilder.
And now my question.
How do I tell PowerBuilder to add special options when starting the JVM?
In special I want to add the following option(s) in some way:
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
The JVM is created like following:
LONG ll_result
inv_java = CREATE JavaVM
ll_result = inv_java.CreateJavaVM("C:\Development\tms java\pbJavaTest", FALSE)
CHOOSE CASE ll_result
CASE 1
CASE 0
CASE -1
MessageBox ( "", "jvm.dll was not found in the classpath.")
CASE -2
MessageBox ( "", "pbejbclient90.jar file was not found." )
CASE ELSE
MessageBox ( "", "Unknown result (" + String (ll_result ) +")" )
END CHOOSE
In the PowerBuilder help I found something about overriding the static registry classpath. There is something written about custom properties which sounds like what I'm looking for.
But there's no example on how to add JVM options to override default behavior.
Does anyone have a clue on how to tell PowerBuilder to use my options?
Or does anyone have any advice which could guide me in the right direction?
Update 1
I found an old post which solved my initial issue.
If someone else want to know how it works take a look at this post:
http://nntp-archive.sybase.com/nntp-archive/action/article/%3C46262213.6742.1681692777#sybase.com%3E
Hi, you need to set some windows registry entries.
Under HKEY_LOCAL_MACHINE\SOFTWARE\Sybase\Powerbuilder\9.0\Java, there
are two folders: PBIDEConfig and PBRTConfig. The first one is used when
you run your application from within the IDE, and the latter is used
when you run your compiled application. Those two folders can have
PBJVMconfig and PBJVMprops folders within them.
PBJVMconfig is for JVM configuration options such as -Xms. You have to
specify incremental key values starting from "0" by one, and one special
key "Count" to tell Powerbuilder how many options exists to enumerate.
PBJVMprops is for all -D options. You do not need to specify -D for
PBJVMProps, just the name of the property and its value, and as many
properties as you wish.
Let me give some examples:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Sybase\PowerBuilder\9.0\Java\PBIDEConfig\PBJVMprops]
"java.security.auth.login.config"="auth.conf"
"user.language"="en"
[HKEY_LOCAL_MACHINE\SOFTWARE\Sybase\PowerBuilder\9.0\Java\PBRTConfig\PBJVMconfig]
"0"="-client"
"1"="-Xms128m"
"2"="-Xmx512m"
"Count"="3"
[HKEY_LOCAL_MACHINE\SOFTWARE\Sybase\PowerBuilder\9.0\Java\PBRTConfig\PBJVMprops]
"java.security.auth.login.config"="auth.conf"
"user.language"="en"
Regards,
Gokhan Demir
But now there's another issue...
PB isn't able to create EJB Proxies for my sample class which is really simple with java 1.8.0_31. They were created with the default version, which is 1.6.0_24.
public class Simple
{
public Simple()
{
}
public static String getValue()
{
return "blubber";
}
public int getInt32Value()
{
return 123456;
}
public double getDoubleVaue()
{
return 123.123;
}
public static void main(String[] args)
{
System.out.println(Simple.getValue());
}
}
The error is the following. :D
---------- Deploy: Deploy of project p_genapp_ejbclientproxy (15:35:18)
Retrieving PowerBuilder Proxies from EJB...
Generation Errors: Error: class not found: (
Deployment Error: No files returned for package/component 'Simple'. Error code: Unknown. Proxy was not created.
Done.
---------- Finished Deploy of project p_genapp_ejbclientproxy (15:35:19)
So the whole way isn't a option because we do not want to change the JAVA settings in PB back and forth just to generate new EJB Proxies for changed JAVA objects in the future...
So one option to test will be creating COM wrappers for JAVA classes to use them in PB...

Get pluginId stored in the IPreferenceNode in Eclipse

I am developing a plugin, in my plugin I want to get another plugin ID. I use the following code:
PreferenceManager pm = PlatformUI.getWorkbench( ).getPreferenceManager();
List<IPreferenceNode> list = pm.getElements(PreferenceManager.PRE_ORDER);
String pluginid;
// restoreDefValues("org.eclipse.ant.ui");
for(IPreferenceNode node : list){
the code to find the node related to the plugin;
}
When I debug the program, I can clearly see that in variable node(IPreferenceNode), it has the value of the pluginId. However, I check the document of IPreferenceNode, it seems that the neither IPreferenceNode nor the class PreferenceNode, provide a method to return the value of pluginId. I tried node.toString() as well, couldn't get the pluginId. So what should I do? Is there any other ways to get a plugin ID from another plugin?
Preference nodes created using the org.eclipse.ui.preferencePages extension point will actually be instances of org.eclipse.ui.internal.dialogs.WorkbenchPreferenceNode. The super class of this (WorkbenchPreferenceExtensionNode) contains the plugin id.
These classes are internal so you should not try to use them directly. However they implement org.eclipse.ui.IPluginContribution which can be used and has a getPluginId() method.
So something like:
if (node instanceof IPluginContribution) {
pluginId = ((IPluginContribution)node).getPluginId();
}
should work.

JFrame in remote between JDK 5 (Server) and 6 (Client - VisualVM)

So I have a little trouble on the opening of a JFrame. I searched extensively on the net, but I really can not find a solution ...
I explained the situation:
I need to develop an application that needs to retrieve information tracking application while meeting new safety standards. For that I use JMX that allows monitoring and VisualVM to see these information.
I therefore I connect without problems (recently ^ ^) to JMX since VisualVM.
There is thus in a VisualVM plugin for recovering information on MBean, including those on Methods (Operations tab in the plugin).
This allows among others to stop a service or create an event.
My problem then comes when I try to display a result of statistics.
In fact, I must show, at the click of a button from the list of methods in the "Operations", a window with a table in HTML (titles, colors and everything else).
For that I use a JFrame:
public JFrame displayHTMLJFrame(String HTML, String title){
JFrame fen = new JFrame();
fen.setSize(1000, 800);
fen.setTitle(title);
JEditorPane pan = new JEditorPane();
pan.setEditorKit(new HTMLEditorKit());
pan.setEditable(false);
pan.setText(HTML);
fen.add(pan);
return fen;
}
I call it in my method:
public JFrame displayHtmlSqlStatOK_VM(){
return displayHTMLJFrame(displaySQLStat(sqlStatOK, firstMessageDate), "SqlStatOK");
}
The method must therefore giving me back my JFrame, but she generates an error:
Problem invoking displayHtmlSqlStatOK_VM : java.rmi.UnmarshalException: error unmarshalling return; nested
exception is:
java.io.InvalidClassException: javax.swing.JFrame; local class incompatible: stream classdesc serialVersionUID =
-5208364155946320552, local class serialVersionUID = -2386951414768123374
I saw on the internet that this was a version problem (Serialization), and I believe strongly that it comes from the fact that I have this:
Server - JDK5 <----> Client (VisualVM) - JDK6
Knowing that I can not to change the server version (costs too important ...) as advocated by some sites and forums.
My question is as follows:
Can I display this damn window keeping my current architecture (JDK5 server side and client side JDK6)?
I could maybe force the issue? Tell him that there's nothing bad that can run my code? Finally I'm asking him but he does not answer me maybe to you he will tell you ... (Yes I crack ^^).
Thank you very much to those who read me and help me!
If you need more info do not hesitate.
EDIT
The solution to my problem might be elsewhere, because in fact I just want a table with minimal formatting (this is just for viewing application for an for an officer to have his little table him possibly putting critical data in red...).
But I have nowhere found a list of types that I can return with VisualVM ... This does not however seem to me too much to ask.
After I had thought of a backup solution, which would be to create a temporary HTML file and open it automatically in the browser, but right after that is perhaps not very clean ... But if it can work ^^
I am open to any area of ​​research!
It looks like you are sending instance javax.swing.JFrame over the JMX connection - this is a bad idea.
Well good I found myself, as a great :)
Thank you bye!
..........
Just kidding of course I will give the solution that I found ^ ^
So here's what I did:
My display to be done on the client (normal...) my code to display a JFrame that I had set up on the server was displayed obviously ... On the server xD
I didn't want to change the customer (VisualVM) to allow users maximum flexibility. However I realized that to display my HTML table to be rendered usable (with colors and everything) I had to change the client (as JMX does not support the type JFrame as type back an operation).
My operation running from the MBeans plugin for VisualVM, it was necessary that I find the source code for it to say "Be careful if you see that I give you the HTML you display it in a JFrame".
Here is my approach:
- Get the sources
The link SVN to get sources VisualVM is as follows:
https: //svn.java.net/svn/visualvm~svn/branches/release134
If like me you have trouble with the SVN client includes in NetBeans because you are behind a proxy, you can do it by command line:
svn --config-option servers:global:http-proxy-host=MY_PROXY_HOST --config-option servers:global:http-proxy-port=MY_PROXY_PORT checkout https: //svn.java.net/svn/visualvm~svn/branches/release134 sources-visualvm
Putting you on your destination folder of course (cd C:\Users\me\Documents\SourcesVisualVM example).
- Adding the platform VisualVM
NetBeans needs the platform VisualVM to create modules (plugins) for it. For this, go to "Tools" -> "NetBeans Platforms".
Then click "Add Platform ..." at the bottom left of the window and select the folder to the bin downloaded at this address: http:// visualvm.java.net/download.html
You should have this:
http://img15.hostingpics.net/pics/543268screen1.png
- Adding sources in the workspace (NetBeansProjects)
Copy/paste downloaded sources (SVN from the link above) to your NetBeans workspace (by default in C:\Users\XXX\Documents\NetBeansProjects).
- Ouverture du projet du plugin MBeans
In NetBeans, right click in the Project Explorer (or go to the menu "Files") and click "Open Project ...".
You will then have a list of projects in your workspace.
Open the project "mbeans" found in "release134" -> "Plugins", as below:
http://img15.hostingpics.net/pics/310487screen2.png
- Changing the file "platform.properties"
To build plugin you must define some variables for your platform.
To do this, open the file platform.properties in the directory release134\plugins\nbproject of your workspace.
Replace the content (by changing the paths compared to yours):
cluster.path=\
C:\\Program Files\\java6\\visualvm_134\\platform:\
C:\\Program Files\\java6\\visualvm_134\\profiler
# Deprecated since 5.0u1; for compatibility with 5.0:
disabled.clusters=
nbjdk.active=default
nbplatform.active=VisualVM_1.3.4
suite.dir=${basedir}
harness.dir= C:\\Program Files\\NetBeans 7.1.2\\harness
- Changing the class XMBeanOperations
To add our feature (displaying an HTML table), you must change the class that processes operations, namely the class XMBeanOperations in package com.sun.tools.visualvm . modules.mbeans.
At line 173, replace:
if (entryIf.getReturnType() != null &&
!entryIf.getReturnType().equals(Void.TYPE.getName()) &&
!entryIf.getReturnType().equals(Void.class.getName()))
fireChangedNotification(OPERATION_INVOCATION_EVENT, button, result);
By :
if (entryIf.getReturnType() != null &&
!entryIf.getReturnType().equals(Void.TYPE.getName()) &&
!entryIf.getReturnType().equals(Void.class.getName())) {
if (entryIf.getReturnType() instanceof String) {
String res = result + "";
if (res.indexOf("<html>") != -1) {
JFrame frame = displayHTMLJFrame(res, button.getText());
frame.setVisible(true);
}
else
fireChangedNotification(OPERATION_INVOCATION_EVENT, button, result);
} else
fireChangedNotification(OPERATION_INVOCATION_EVENT, button, result);
}
With the method of creating the JFrame that you place above "void performInvokeRequest (final JButton button)" for example:
// Display a frame with HTML code
public JFrame displayHTMLJFrame(String HTML, String title){
JFrame fen = new JFrame();
fen.setSize(1000, 800);
fen.setTitle(title);
JEditorPane pan = new JEditorPane();
pan.setEditorKit(new HTMLEditorKit());
pan.setEditable(false);
pan.setText(HTML);
fen.add(pan);
return fen;
}
We can see that we already did a test on the return type, if it is a String which is returned, if the case, if we see in this string the balise , then we replace the result of the click by opening a JFrame with the string you put in, what makes us display our HTML code!
- Creating a .nbm
The file .nbm is the deployment file of your plugin. Simply right-click your project (in the Project Explorer) and click on "Create NBM".
Your file .nbm will be created in the folder "build" the root of your project.
- Installing the plugin in VisualVM
To install your plugin, you must just go in VisualVM, go into "Tools" -> "Plugins" tab and then "Downloaded", click "Add Plugins ...". Select your plugin .nbm then click "Install". Then follow the instructions.
Useful Sources
http: //docs.oracle.com/javase/6/docs/technotes/guides/visualvm/
http: //visualvm.java.net/"]http://visualvm.java.net/
http: //visualvm.java.net/api-quickstart.html (Créer un plugin VisualVM avec NetBeans)
Thank you very much for your help Tomas Hurka ;)