package org.python.pydev.shared_ui.content_assist;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import org.eclipse.jface.text.contentassist.ContentAssistEvent;
import org.eclipse.jface.text.contentassist.ContentAssistant;
import org.eclipse.jface.text.contentassist.ICompletionListener;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Table;
import org.python.pydev.shared_core.log.Log;
import org.python.pydev.shared_core.utils.PlatformUtils;
public class ContentAssistHackingAroundBugs {
public static void fixAssistBugs(final ContentAssistant assistant) {
if (PlatformUtils.isLinuxPlatform()) {
// Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=508245 (hack can be removed when that's fixed).
assistant.addCompletionListener(new ICompletionListener() {
Table fTable;
Listener fKeyDownListener;
boolean fCalled = false;
@Override
public void selectionChanged(ICompletionProposal proposal, boolean smartToggle) {
// We do it in selectionChanged (and not on assistSessionStarted) because the table is only created
// at this point.
if (!fCalled) {
fCalled = true;
} else {
return;
}
try {
Field fProposalPopupField = ContentAssistant.class.getDeclaredField("fProposalPopup");
fProposalPopupField.setAccessible(true);
final Object completionProposalPopup = fProposalPopupField.get(assistant);
Field fProposalTableField = completionProposalPopup.getClass()
.getDeclaredField("fProposalTable");
fProposalTableField.setAccessible(true);
Table table = (Table) fProposalTableField.get(completionProposalPopup);
if (table == null || table.isDisposed()) {
return;
}
fKeyDownListener = new Listener() {
@Override
public void handleEvent(Event event) {
if (event.character == '\n' || event.character == '\r') {
try {
Method m = completionProposalPopup.getClass()
.getDeclaredMethod("insertSelectedProposalWithMask", int.class);
m.setAccessible(true);
m.invoke(completionProposalPopup, event.stateMask);
} catch (Throwable e) {
Log.log(e);
}
}
}
};
table.addListener(SWT.KeyDown, fKeyDownListener);
fTable = table;
} catch (Throwable e) {
// Just ignore if this hack stops working.
}
}
@Override
public void assistSessionStarted(ContentAssistEvent event) {
}
@Override
public void assistSessionEnded(ContentAssistEvent event) {
if (fCalled) {
fCalled = false;
if (fTable != null && !fTable.isDisposed() && fKeyDownListener != null) {
fTable.removeListener(SWT.KeyDown, fKeyDownListener);
}
fTable = null;
fKeyDownListener = null;
}
}
});
}
}
}