Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

This doc has moved to the github.com/antlr/jetbrains repo

https://raw.githubusercontent.com/antlr/jetbrains/master/doc/plugin-dev-notes.md

Useful projects

https://github.com/nicoulaj/idea-markdown

...

You also need to invalidate tree upon editor changes

/** Invalidate tree upon doc change */
public void registerStructureViewModel(final Editor editor, final STGroupStructureViewModel model) {
final Document doc = editor.getDocument();
final DocumentListener listener = new DocumentAdapter() {
@Override
 public void documentChanged(DocumentEvent e) { model.invalidate(); }
};
DocumentListener oldListener = doc.getUserData(EDITOR_STRUCTVIEW_LISTENER_KEY);
if ( oldListener!=null ) {
doc.removeDocumentListener(oldListener);
}
doc.putUserData(EDITOR_STRUCTVIEW_LISTENER_KEY, listener);
doc.addDocumentListener(listener);
}

In the view model, we set 

 
/** force rebuild; see {@link #getRoot()} */
public void invalidate() {
parseTree = null;
}
/** If parseTree==null, this will return a StructureViewTreeElement with
* getValue()==null, which forces rebuild in {@link com.intellij.ide.impl.StructureViewWrapperImpl#rebuild()}
*/
@NotNull
@Override
public StructureViewTreeElement getRoot() {
return new STGroupRootStructureViewTreeElement(parseTree,file);
}

Resolving references

All PsiElement can getReference() and getReferences() which return PsiReference.  That reference can really be anything we want. I see PsiBreakStatementImpl returning a PsiLabelReference that wraps the break statement and the identifier in the break statement. 

...

http://confluence.jetbrains.com/display/IntelliJIDEA/Annotator

Annotator helps highlight and annotate any code based on specific rules.

Doc:

The third level of highlighting is performed through the Annotator interface. A plugin can register one or more annotators in the com.intellij.annotator extension point, and these annotators are called during the background highlighting pass to process the elements in the PSI tree of the custom language. Annotators can analyze not only the syntax, but also the semantics of the text in the language, and thus can provide much more complex syntax and error highlighting logic. The annotator can also provide quick fixes to problems it detects.

...

       final JList list = new JBList(stack);
// PopupChooserBuilder builder = new PopupChooserBuilder(list);
 JBPopupFactory factory = JBPopupFactory.getInstance();
PopupChooserBuilder builder = factory.createListPopupBuilder(list);
JBPopup popup = builder.createPopup();

MouseEvent mouseEvent = event.getMouseEvent();
Point point = mouseEvent.getPoint();
Dimension dimension = popup.getContent().getLayout().preferredLayoutSize(builder.getScrollPane());
System.out.println(dimension);
int height = dimension.height;
point.translate(10, -height);
RelativePoint where = new RelativePoint(mouseEvent.getComponent(), point);
popup.show(where);

Code for a balloon.

JBPopupFactory popupFactory = JBPopupFactory.getInstance();
BalloonBuilder builder =
popupFactory.createHtmlTextBalloonBuilder(Utils.join(stack.toArray(), "<br>"),
MessageType.INFO, null);
builder.setHideOnClickOutside(true);
Balloon balloon = builder.createBalloon();
MouseEvent mouseEvent = event.getMouseEvent();
Point point = mouseEvent.getPoint();
point.translate(10, -15);
RelativePoint where = new RelativePoint(mouseEvent.getComponent(), point);
balloon.show(where, Balloon.Position.above);

...