eventQueue = new LinkedTransferQueue<>();
@@ -36,6 +37,7 @@ public synchronized void start() {
thread = new WorkerThread(eventQueue);
thread.start();
+ this.running = true;
}
@Override
@@ -44,6 +46,12 @@ public synchronized void stop() {
thread.interrupt();
thread = null;
}
+ this.running = false;
+ }
+
+ @Override
+ public boolean isRunning() {
+ return running;
}
@Override
diff --git a/src/main/java/com/kite/intellij/editor/events/DefaultEditorEventListener.java b/src/main/java/com/kite/intellij/editor/events/DefaultEditorEventListener.java
index 0464f2e8..070261fe 100644
--- a/src/main/java/com/kite/intellij/editor/events/DefaultEditorEventListener.java
+++ b/src/main/java/com/kite/intellij/editor/events/DefaultEditorEventListener.java
@@ -1,415 +1,43 @@
package com.kite.intellij.editor.events;
-import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.intellij.ide.FrameStateListener;
-import com.intellij.openapi.Disposable;
-import com.intellij.openapi.application.Application;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.components.AbstractProjectComponent;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.editor.Caret;
-import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.editor.EditorFactory;
-import com.intellij.openapi.editor.event.*;
-import com.intellij.openapi.editor.ex.DocumentEx;
-import com.intellij.openapi.editor.ex.EditorEx;
-import com.intellij.openapi.editor.ex.FocusChangeListener;
-import com.intellij.openapi.fileEditor.FileDocumentManager;
-import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Key;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.PsiDocumentManager;
-import com.intellij.util.Alarm;
-import com.kite.intellij.KiteConstants;
-import com.kite.intellij.backend.KiteServerSettingsService;
-import com.kite.intellij.backend.model.EventType;
-import com.kite.intellij.backend.model.TextSelection;
-import com.kite.intellij.editor.util.FileEditorUtil;
-import com.kite.intellij.lang.KiteLanguageSupport;
+import com.intellij.openapi.startup.ProjectActivity;
+import com.intellij.openapi.util.Disposer;
+import com.kite.intellij.KiteProjectLifecycleService;
import com.kite.intellij.platform.KitePlatform;
-import com.kite.intellij.platform.fs.CanonicalFilePath;
-import com.kite.intellij.platform.fs.CanonicalFilePathFactory;
+import kotlin.Unit;
+import kotlin.coroutines.Continuation;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
-import javax.annotation.Nonnull;
-import java.awt.*;
import java.util.Map;
-import java.util.Set;
/**
* Listens to IntelliJ's events and executes the coresponding Kite events whenever necessary.
*
* It will only react to events if the current platform is supported by Kite.
*
- */
-public class DefaultEditorEventListener extends AbstractProjectComponent implements EditorEventListener, FrameStateListener, Disposable {
- private static final Logger LOG = Logger.getInstance("#kite.editorEvent");
- private static final Key KEY_FLUSH_ON_DOC_COMMIT = Key.create("kite.docFlush");
-
- protected final Alarm editAlarm;
- protected final Map pendingEditorChangeRequests = Maps.newHashMap();
- private final KiteEventQueue eventQueue;
- private final int alarmDelayMillis;
- private final Set currentlyModifiedDocuments = Sets.newConcurrentHashSet();
- private final CanonicalFilePathFactory filePathFactory;
- private final FileEditorManager fileEditorManager;
-
- //lock to synchronize on when accessing the request event maps
- private final Object requestLock = new Object();
-
- @SuppressWarnings("unused")
- public DefaultEditorEventListener(Project project) {
- this(project,
- KiteConstants.DEFAULT_QUEUE_TIMEOUT_MILLIS,
- CanonicalFilePathFactory.getInstance(),
- KiteConstants.ALARM_DELAY_MILLIS);
- }
-
- protected DefaultEditorEventListener(Project project, int queueIntervalMillis, CanonicalFilePathFactory filePathFactory, int alarmDelayMillis) {
- super(project);
-
- this.eventQueue = new AsyncKiteEventQueue();
- this.alarmDelayMillis = alarmDelayMillis;
- this.fileEditorManager = FileEditorManager.getInstance(myProject);
- this.filePathFactory = filePathFactory;
-
- this.editAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD, this);
- }
-
- @Override
- public KiteEventQueue getEventQueue() {
- return eventQueue;
- }
-
- public void awaitEvents() {
- if (LOG.isTraceEnabled()) {
- LOG.trace("awaitEvents");
- }
-
- if (isEventDispatchThread()) {
- synchronized (requestLock) {
- //editAlarm.flush() can not be used because it doesn't wrap with an outer write session
- //and calls invokeLater for the runnables
- editAlarm.cancelAllRequests();
-
- //we need to iterate on a copy because the runnables remove the map entry on their own
- if (!pendingEditorChangeRequests.isEmpty()) {
- for (Runnable runnable : Lists.newArrayList(pendingEditorChangeRequests.values())) {
- runnable.run();
- }
-
- pendingEditorChangeRequests.clear();
- }
- }
- }
- }
+ */
+public class DefaultEditorEventListener implements ProjectActivity {
+ private final Map listenerByProject = Maps.newHashMap();
+ @Nullable
@Override
- public void dispose() {
- eventQueue.stop();
- }
-
- @Override
- public void projectOpened() {
+ public Object execute(@NotNull Project project, @NotNull Continuation super Unit> continuation) {
if (!KitePlatform.isOsVersionSupported()) {
- return;
- }
-
- eventQueue.start();
-
- EditorFactory editorFactory = EditorFactory.getInstance();
-
- EditorEventMulticaster eventMulticaster = editorFactory.getEventMulticaster();
-
- eventMulticaster.addDocumentListener(new DocumentListener() {
- @Override
- public void beforeDocumentChange(@NotNull DocumentEvent e) {
- Document document = e.getDocument();
-
- VirtualFile file = FileDocumentManager.getInstance().getFile(document);
- if (file == null || !file.isInLocalFileSystem()) {
- return;
- }
-
- if (!Boolean.TRUE.equals(KEY_FLUSH_ON_DOC_COMMIT.get(document))) {
- KEY_FLUSH_ON_DOC_COMMIT.set(document, Boolean.TRUE);
-
- //we need to flush pending events (for the current file) on document flush
- //the code completion commits and then calls the completion provider
- //we can't flush pending edit events in our completion provider because this will lead to a dead lock
- // - EDT calls completion in a pooled thread
- // - pooled thread calls completion -> completion calls flush -> flushed actions must be run on EDT
- // - waiting on the EDT here will dead-lock our application
- // we're not invoking PsiDocumentManagerBase.addRunOnCommit directly,
- // because it changed to a non-static method in 2020.2
- PsiDocumentManager.getInstance(myProject).performForCommittedDocument(document, () -> {
- //the commit action is only run once, we need to re-register before the next change event
- if (LOG.isTraceEnabled()) {
- LOG.trace("awaitEvents on commit");
- }
-
- try {
- awaitEvents();
- } finally {
- KEY_FLUSH_ON_DOC_COMMIT.set(document, null);
- }
- });
- }
-
- //this call must not be added to the alarm ticker because Alarm on 171.x doesn't seem to guarantee
- //execution order and thus the beforeDocumentChange event might be called after the documentChange
- //which is added later to the alarm and this breaks our logic
- //beforeDocumentChange is rather cheap, so we call it directly
- DefaultEditorEventListener.this.beforeDocumentChange(e);
- }
-
- @Override
- public void documentChanged(@NotNull DocumentEvent e) {
- Document document = e.getDocument();
- VirtualFile file = FileDocumentManager.getInstance().getFile(document);
- if (file == null || !file.isInLocalFileSystem()) {
- return;
- }
-
- if (LOG.isTraceEnabled()) {
- LOG.trace("Edit event \"" + e.getNewFragment() + "\"");
- }
-
- addOverridingRequest(pendingEditorChangeRequests, document, editAlarm, () -> DefaultEditorEventListener.this.documentChanged(e));
- }
- }, this);
-
- eventMulticaster.addCaretListener(new CaretListener() {
- @Override
- public void caretPositionChanged(@NotNull CaretEvent e) {
- Document document = e.getEditor().getDocument();
-
- VirtualFile file = FileDocumentManager.getInstance().getFile(document);
- if (file == null || !file.isInLocalFileSystem()) {
- return;
- }
-
- addOverridingRequest(pendingEditorChangeRequests, document, editAlarm, () -> DefaultEditorEventListener.this.caretPositionChanged(e));
-
- }
- }, this);
-
- // We don't subscribe with myProject.getMessageBus().connect(myProject).subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER
- // because the the FILE_EDITOR_MANAGER event is only triggered when a new editor is created,
- // we listen for focus changes (e.g. by tab activation) below but attach to each new editor
- // we must handle editors restored at startup, though. Extra careful testing in the new IJ branches must be
- // done to make sure that restored files generate focus events
- editorFactory.addEditorFactoryListener(new EditorFactoryListener() {
- @Override
- public void editorCreated(@NotNull EditorFactoryEvent event) {
- Editor editor = event.getEditor();
- if (!(editor instanceof EditorEx)) {
- return;
- }
-
- ((EditorEx) editor).addFocusListener(new FocusChangeListener() {
- @Override
- public void focusGained(@NotNull Editor editor) {
- if (editor instanceof EditorEx) {
- VirtualFile virtualFile = ((EditorEx) editor).getVirtualFile();
- if (virtualFile != null) {
- DefaultEditorEventListener.this.fileFocused(editor, virtualFile);
- }
- }
- }
-
- @Override
- public void focusLost(@NotNull Editor editor) {
- }
- }, DefaultEditorEventListener.this);
- }
- }, this);
-
- ApplicationManager.getApplication().getMessageBus().connect(this).subscribe(FrameStateListener.TOPIC, this);
- }
-
- @Override
- public void projectClosed() {
- eventQueue.stop();
- }
-
- /**
- * Called when the IntelliJ window's frame is activated.
- * If there is a current editor open and if it has the focus then a focus event is send to kite.
- */
- @Override
- public void onFrameActivated() {
- Editor editor = fileEditorManager.getSelectedTextEditor();
- if (editor == null) {
- return;
- }
-
- CanonicalFilePath path = filePathFactory.createFor(editor, CanonicalFilePathFactory.Context.Event);
- if (path != null) {
- eventQueue.addEvent(KiteEventFactory.create(EventType.FOCUS, path, editor));
- if (LOG.isDebugEnabled()) {
- LOG.debug("Focus event after frame activation");
- }
- }
- }
-
- public void fileFocused(@Nonnull Editor editor, @Nonnull VirtualFile file) {
- if (editor.isDisposed() || editor.isOneLineMode() || editor.isViewer()) {
- return;
- }
-
- CanonicalFilePath filePath = filePathFactory.createFor(editor, CanonicalFilePathFactory.Context.Event);
- if (filePath == null) {
- return;
- }
-
- if (file.getLength() > KiteServerSettingsService.getInstance().getMaxFileSizeBytes()) {
- eventQueue.addEvent(KiteEventFactory.createSkipEvent(filePath));
- } else {
- eventQueue.addEvent(KiteEventFactory.create(EventType.FOCUS, filePath, editor));
- }
- }
-
- /**
- * Registers a new request which handles an editor event.
- *
- * @param requestMap The map where the new request is inserted and any previous event of the same kind is removed from
- * @param key
- * @param alarm
- * @param newRequest
- * @param
- */
- protected void addOverridingRequest(Map requestMap, T key, Alarm alarm, Runnable newRequest) {
- synchronized (requestLock) {
- Runnable oldRequest = requestMap.get(key);
- if (oldRequest != null) {
- requestMap.remove(key);
- alarm.cancelRequest(oldRequest);
-
- if (LOG.isTraceEnabled()) {
- LOG.trace("Dropping request due to new editor action");
- }
- }
- }
-
- Runnable runnable = () -> {
- //this is not totally safe because (in theory) it might happen that there was another key added for key in the meantime
- synchronized (requestLock) {
- requestMap.remove(key);
- }
-
- newRequest.run();
- };
-
- synchronized (requestLock) {
- requestMap.put(key, runnable);
+ return null;
}
- alarm.addRequest(runnable, alarmDelayMillis);
- }
-
- private void caretPositionChanged(CaretEvent e) {
- if (LOG.isTraceEnabled()) {
- LOG.trace("caretPositionChanged");
- }
-
- Caret caret = e.getCaret();
- if (caret == null) {
- return;
+ if (!listenerByProject.containsKey(project)){
+ listenerByProject.put(project, new ProjectEditorEventListener(project));
}
- Editor editor = e.getEditor();
- if (editor.isDisposed()) {
- return;
- }
+ ProjectEditorEventListener projectEditorEventListener = listenerByProject.get(project);
+ Disposer.register(project.getService(KiteProjectLifecycleService.class), projectEditorEventListener);
- CanonicalFilePath filePath = filePathFactory.createFor(e.getEditor(), CanonicalFilePathFactory.Context.Event);
- if (filePath == null) {
- return;
- }
-
- if (e.getEditor().getDocument().getTextLength() > KiteServerSettingsService.getInstance().getMaxFileSizeBytes()) {
- //text length is != byte length but decoding is expensive
- if (LOG.isTraceEnabled()) {
- LOG.trace("Sending skip event instead of caret change for " + filePath);
- }
- eventQueue.addEvent(KiteEventFactory.createSkipEvent(filePath));
- return;
- }
-
- TextSelection selection;
- if (caret.hasSelection()) {
- selection = TextSelection.create(caret.getSelectionStart(), caret.getSelectionEnd());
- } else {
- selection = TextSelection.create(caret.getOffset());
- }
-
- // http status listener updates only if the current file is supported by Kite,
- boolean supported = KiteLanguageSupport.isSupported(editor, KiteLanguageSupport.Feature.BasicSupport);
- eventQueue.addEvent(KiteEventFactory.create(EventType.SELECTION, filePath, FileEditorUtil.contentOf(editor), selection, editor.getDocument(), supported));
- }
-
- private void beforeDocumentChange(DocumentEvent event) {
- if (LOG.isTraceEnabled()) {
- LOG.trace("beforeDocumentChanged");
- }
-
- Document document = event.getDocument();
- if (document instanceof DocumentEx && document.isInBulkUpdate()) {
- return;
- }
-
- CanonicalFilePath filePath = filePathFactory.createFor(document, CanonicalFilePathFactory.Context.Event);
- if (filePath != null && document.getTextLength() <= KiteServerSettingsService.getInstance().getMaxFileSizeBytes()) {
- //text length is != file size with non-ascii content. decoding into bytes is expensive, though.
- currentlyModifiedDocuments.add(filePath);
- }
- }
-
- private void documentChanged(DocumentEvent event) {
- if (LOG.isTraceEnabled()) {
- LOG.trace("documentChanged");
- }
-
- Document document = event.getDocument();
- if (document instanceof DocumentEx && document.isInBulkUpdate()) {
- return;
- }
-
- CanonicalFilePath filePath = filePathFactory.createFor(document, CanonicalFilePathFactory.Context.Event);
- if (filePath == null) {
- //may happen in test cases or for documents which do not represent a file system element, e.g. a LightVirtualFile used to do code completions etc.
- return;
- }
-
- try {
- final Editor textEditor = fileEditorManager.getSelectedTextEditor();
- if (textEditor == null || !textEditor.getDocument().equals(document)) {
- //a document modification without an editor could be a refactoring
- //IntelliJ does not automatically save changes after a refactoring, so have to send events for these files, too
- if (LOG.isTraceEnabled()) {
- LOG.trace("Ignoring change outside of the current editor: " + filePath.asOSDelimitedPath());
- }
- return;
- }
-
- //null file paths might happen in test cases, for example, when the document is not yet attached to an actual VirtualFile/PsiFile.
- if (currentlyModifiedDocuments.contains(filePath)) {
- int editorOffset = textEditor.getCaretModel().getOffset();
- eventQueue.addEvent(KiteEventFactory.create(EventType.EDIT, filePath, FileEditorUtil.contentOf(document), TextSelection.create(editorOffset), document, true));
- }
- } finally {
- currentlyModifiedDocuments.remove(filePath);
- }
- }
+ projectEditorEventListener.execute();
- // taken from JetBrain's Alarm as it was removed from 183.x
- private static boolean isEventDispatchThread() {
- Application app = ApplicationManager.getApplication();
- return app != null && app.isDispatchThread() || EventQueue.isDispatchThread();
+ return null;
}
}
diff --git a/src/main/java/com/kite/intellij/editor/events/KiteEventQueue.java b/src/main/java/com/kite/intellij/editor/events/KiteEventQueue.java
index b1ad9a60..04b5d007 100644
--- a/src/main/java/com/kite/intellij/editor/events/KiteEventQueue.java
+++ b/src/main/java/com/kite/intellij/editor/events/KiteEventQueue.java
@@ -70,6 +70,12 @@ static KiteEventQueue getInstance(Project project) {
*/
void addEvent(KiteEvent newEvent);
+ /**
+ * Indicates the queue is running or not.
+ * @return weather the queue is running or not.
+ */
+ boolean isRunning();
+
@FunctionalInterface
interface KiteQueueComputable {
T compute() throws KiteHttpException;
diff --git a/src/main/java/com/kite/intellij/editor/events/ProjectEditorEventListener.java b/src/main/java/com/kite/intellij/editor/events/ProjectEditorEventListener.java
new file mode 100644
index 00000000..11baefa5
--- /dev/null
+++ b/src/main/java/com/kite/intellij/editor/events/ProjectEditorEventListener.java
@@ -0,0 +1,409 @@
+package com.kite.intellij.editor.events;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.intellij.ide.FrameStateListener;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.application.Application;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Caret;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.EditorFactory;
+import com.intellij.openapi.editor.event.*;
+import com.intellij.openapi.editor.ex.DocumentEx;
+import com.intellij.openapi.editor.ex.EditorEx;
+import com.intellij.openapi.editor.ex.FocusChangeListener;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.fileEditor.FileEditorManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.wm.IdeFrame;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.util.Alarm;
+import com.kite.intellij.KiteConstants;
+import com.kite.intellij.backend.KiteServerSettingsService;
+import com.kite.intellij.backend.model.EventType;
+import com.kite.intellij.backend.model.TextSelection;
+import com.kite.intellij.editor.util.FileEditorUtil;
+import com.kite.intellij.lang.KiteLanguageSupport;
+import com.kite.intellij.platform.fs.CanonicalFilePath;
+import com.kite.intellij.platform.fs.CanonicalFilePathFactory;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.annotation.Nonnull;
+import java.awt.*;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Listens to IntelliJ's events and executes the coresponding Kite events whenever necessary.
+ *
+ * It will only react to events if the current platform is supported by Kite.
+ *
+ */
+public class ProjectEditorEventListener implements EditorEventListener, FrameStateListener, Disposable {
+ private static final Logger LOG = Logger.getInstance("#kite.editorEvent");
+ private static final Key KEY_FLUSH_ON_DOC_COMMIT = Key.create("kite.docFlush");
+
+ protected final Alarm editAlarm;
+ protected final Map pendingEditorChangeRequests = Maps.newHashMap();
+ private final int alarmDelayMillis;
+ private final Set currentlyModifiedDocuments = Sets.newConcurrentHashSet();
+ private final CanonicalFilePathFactory filePathFactory;
+
+ //lock to synchronize on when accessing the request event maps
+ private final Object requestLock = new Object();
+
+ private final Project myProject;
+
+ private final KiteEventQueue eventQueue;
+ private final FileEditorManager fileEditorManager;
+
+ protected ProjectEditorEventListener(Project project) {
+ this.myProject = project;
+ this.eventQueue = new AsyncKiteEventQueue();
+ this.fileEditorManager = FileEditorManager.getInstance(project);
+
+ this.alarmDelayMillis = KiteConstants.ALARM_DELAY_MILLIS;
+ this.filePathFactory = CanonicalFilePathFactory.getInstance();
+
+ this.editAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD, this);
+ }
+
+ @Override
+ public KiteEventQueue getEventQueue() {
+ return eventQueue;
+ }
+
+ public void awaitEvents() {
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("awaitEvents");
+ }
+
+ if (isEventDispatchThread()) {
+ synchronized (requestLock) {
+ //editAlarm.flush() can not be used because it doesn't wrap with an outer write session
+ //and calls invokeLater for the runnables
+ editAlarm.cancelAllRequests();
+
+ //we need to iterate on a copy because the runnables remove the map entry on their own
+ if (!pendingEditorChangeRequests.isEmpty()) {
+ for (Runnable runnable : Lists.newArrayList(pendingEditorChangeRequests.values())) {
+ runnable.run();
+ }
+
+ pendingEditorChangeRequests.clear();
+ }
+ }
+ }
+ }
+
+ @Override
+ public void dispose() {
+ eventQueue.stop();
+ }
+
+
+ @Nullable
+ public Object execute() {
+ // This is strange. why could it be started twice?
+ if (!eventQueue.isRunning())
+ eventQueue.start();
+
+ EditorFactory editorFactory = EditorFactory.getInstance();
+
+ EditorEventMulticaster eventMulticaster = editorFactory.getEventMulticaster();
+
+ eventMulticaster.addDocumentListener(new DocumentListener() {
+ @Override
+ public void beforeDocumentChange(@NotNull DocumentEvent e) {
+ Document document = e.getDocument();
+
+ VirtualFile file = FileDocumentManager.getInstance().getFile(document);
+ if (file == null || !file.isInLocalFileSystem()) {
+ return;
+ }
+
+ if (!Boolean.TRUE.equals(KEY_FLUSH_ON_DOC_COMMIT.get(document))) {
+ KEY_FLUSH_ON_DOC_COMMIT.set(document, Boolean.TRUE);
+
+ //we need to flush pending events (for the current file) on document flush
+ //the code completion commits and then calls the completion provider
+ //we can't flush pending edit events in our completion provider because this will lead to a dead lock
+ // - EDT calls completion in a pooled thread
+ // - pooled thread calls completion -> completion calls flush -> flushed actions must be run on EDT
+ // - waiting on the EDT here will dead-lock our application
+ // we're not invoking PsiDocumentManagerBase.addRunOnCommit directly,
+ // because it changed to a non-static method in 2020.2
+ PsiDocumentManager.getInstance(myProject).performForCommittedDocument(document, () -> {
+ //the commit action is only run once, we need to re-register before the next change event
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("awaitEvents on commit");
+ }
+
+ try {
+ awaitEvents();
+ } finally {
+ KEY_FLUSH_ON_DOC_COMMIT.set(document, null);
+ }
+ });
+ }
+
+ //this call must not be added to the alarm ticker because Alarm on 171.x doesn't seem to guarantee
+ //execution order and thus the beforeDocumentChange event might be called after the documentChange
+ //which is added later to the alarm and this breaks our logic
+ //beforeDocumentChange is rather cheap, so we call it directly
+ ProjectEditorEventListener.this.beforeDocumentChange(e);
+ }
+
+ @Override
+ public void documentChanged(@NotNull DocumentEvent e) {
+ Document document = e.getDocument();
+ VirtualFile file = FileDocumentManager.getInstance().getFile(document);
+ if (file == null || !file.isInLocalFileSystem()) {
+ return;
+ }
+
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("Edit event \"" + e.getNewFragment() + "\"");
+ }
+
+ addOverridingRequest(pendingEditorChangeRequests, document, editAlarm, () -> ProjectEditorEventListener.this.documentChanged(e));
+ }
+ }, this);
+
+ eventMulticaster.addCaretListener(new CaretListener() {
+ @Override
+ public void caretPositionChanged(@NotNull CaretEvent e) {
+ Document document = e.getEditor().getDocument();
+
+ VirtualFile file = FileDocumentManager.getInstance().getFile(document);
+ if (file == null || !file.isInLocalFileSystem()) {
+ return;
+ }
+
+ addOverridingRequest(pendingEditorChangeRequests, document, editAlarm, () -> ProjectEditorEventListener.this.caretPositionChanged(e));
+
+ }
+ }, this);
+
+ // We don't subscribe with myProject.getMessageBus().connect(myProject).subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER
+ // because the the FILE_EDITOR_MANAGER event is only triggered when a new editor is created,
+ // we listen for focus changes (e.g. by tab activation) below but attach to each new editor
+ // we must handle editors restored at startup, though. Extra careful testing in the new IJ branches must be
+ // done to make sure that restored files generate focus events
+ editorFactory.addEditorFactoryListener(new EditorFactoryListener() {
+ @Override
+ public void editorCreated(@NotNull EditorFactoryEvent event) {
+ Editor editor = event.getEditor();
+ if (!(editor instanceof EditorEx)) {
+ return;
+ }
+
+ ((EditorEx) editor).addFocusListener(new FocusChangeListener() {
+ @Override
+ public void focusGained(@NotNull Editor editor) {
+ if (editor instanceof EditorEx) {
+ VirtualFile virtualFile = ((EditorEx) editor).getVirtualFile();
+ if (virtualFile != null) {
+ ProjectEditorEventListener.this.fileFocused(editor, virtualFile);
+ }
+ }
+ }
+
+ }, ProjectEditorEventListener.this);
+ }
+ }, this);
+
+ ApplicationManager.getApplication().getMessageBus().connect(this).subscribe(FrameStateListener.TOPIC, this);
+
+ return null;
+ }
+
+ /**
+ * Called when the IntelliJ window's frame is activated.
+ * If there is a current editor open and if it has the focus then a focus event is send to kite.
+ */
+ @Override
+ public void onFrameActivated(@NotNull IdeFrame frame) {
+ Project project = frame.getProject();
+ if (project == null || project.isDisposed()){
+ return;
+ }
+
+ Editor editor = fileEditorManager.getSelectedTextEditor();
+ if (editor == null) {
+ return;
+ }
+
+ CanonicalFilePath path = filePathFactory.createFor(editor, CanonicalFilePathFactory.Context.Event);
+ if (path != null) {
+ eventQueue.addEvent(KiteEventFactory.create(EventType.FOCUS, path, editor));
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Focus event after frame activation");
+ }
+ }
+ }
+
+ public void fileFocused(@Nonnull Editor editor, @Nonnull VirtualFile file) {
+ if (editor.isDisposed() || editor.isOneLineMode() || editor.isViewer()) {
+ return;
+ }
+
+ CanonicalFilePath filePath = filePathFactory.createFor(editor, CanonicalFilePathFactory.Context.Event);
+ if (filePath == null) {
+ return;
+ }
+
+ if (file.getLength() > KiteServerSettingsService.getInstance().getMaxFileSizeBytes()) {
+ eventQueue.addEvent(KiteEventFactory.createSkipEvent(filePath));
+ } else {
+ eventQueue.addEvent(KiteEventFactory.create(EventType.FOCUS, filePath, editor));
+ }
+ }
+
+ /**
+ * Registers a new request which handles an editor event.
+ *
+ * @param requestMap The map where the new request is inserted and any previous event of the same kind is removed from
+ * @param key
+ * @param alarm
+ * @param newRequest
+ * @param
+ */
+ protected void addOverridingRequest(Map requestMap, T key, Alarm alarm, Runnable newRequest) {
+ synchronized (requestLock) {
+ Runnable oldRequest = requestMap.get(key);
+ if (oldRequest != null) {
+ requestMap.remove(key);
+ alarm.cancelRequest(oldRequest);
+
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("Dropping request due to new editor action");
+ }
+ }
+ }
+
+ Runnable runnable = () -> {
+ //this is not totally safe because (in theory) it might happen that there was another key added for key in the meantime
+ synchronized (requestLock) {
+ requestMap.remove(key);
+ }
+
+ newRequest.run();
+ };
+
+ synchronized (requestLock) {
+ requestMap.put(key, runnable);
+ }
+
+ alarm.addRequest(runnable, alarmDelayMillis);
+ }
+
+ private void caretPositionChanged(CaretEvent e) {
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("caretPositionChanged");
+ }
+
+ Caret caret = e.getCaret();
+ if (caret == null) {
+ return;
+ }
+
+ Editor editor = e.getEditor();
+ if (editor.isDisposed()) {
+ return;
+ }
+
+ CanonicalFilePath filePath = filePathFactory.createFor(e.getEditor(), CanonicalFilePathFactory.Context.Event);
+ if (filePath == null) {
+ return;
+ }
+
+ if (e.getEditor().getDocument().getTextLength() > KiteServerSettingsService.getInstance().getMaxFileSizeBytes()) {
+ //text length is != byte length but decoding is expensive
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("Sending skip event instead of caret change for " + filePath);
+ }
+ eventQueue.addEvent(KiteEventFactory.createSkipEvent(filePath));
+ return;
+ }
+
+ TextSelection selection;
+ if (caret.hasSelection()) {
+ selection = TextSelection.create(caret.getSelectionStart(), caret.getSelectionEnd());
+ } else {
+ selection = TextSelection.create(caret.getOffset());
+ }
+
+ // http status listener updates only if the current file is supported by Kite,
+ boolean supported = KiteLanguageSupport.isSupported(editor, KiteLanguageSupport.Feature.BasicSupport);
+ eventQueue.addEvent(KiteEventFactory.create(EventType.SELECTION, filePath, FileEditorUtil.contentOf(editor), selection, editor.getDocument(), supported));
+ }
+
+ private void beforeDocumentChange(DocumentEvent event) {
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("beforeDocumentChanged");
+ }
+
+ Document document = event.getDocument();
+ if (document instanceof DocumentEx && document.isInBulkUpdate()) {
+ return;
+ }
+
+ CanonicalFilePath filePath = filePathFactory.createFor(document, CanonicalFilePathFactory.Context.Event);
+ if (filePath != null && document.getTextLength() <= KiteServerSettingsService.getInstance().getMaxFileSizeBytes()) {
+ //text length is != file size with non-ascii content. decoding into bytes is expensive, though.
+ currentlyModifiedDocuments.add(filePath);
+ }
+ }
+
+ private void documentChanged(DocumentEvent event) {
+
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("documentChanged");
+ }
+
+ Document document = event.getDocument();
+ if (document instanceof DocumentEx && document.isInBulkUpdate()) {
+ return;
+ }
+
+ CanonicalFilePath filePath = filePathFactory.createFor(document, CanonicalFilePathFactory.Context.Event);
+ if (filePath == null) {
+ //may happen in test cases or for documents which do not represent a file system element, e.g. a LightVirtualFile used to do code completions etc.
+ return;
+ }
+
+ try {
+ final Editor textEditor = fileEditorManager.getSelectedTextEditor();
+ if (textEditor == null || !textEditor.getDocument().equals(document)) {
+ //a document modification without an editor could be a refactoring
+ //IntelliJ does not automatically save changes after a refactoring, so have to send events for these files, too
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("Ignoring change outside of the current editor: " + filePath.asOSDelimitedPath());
+ }
+ return;
+ }
+
+ //null file paths might happen in test cases, for example, when the document is not yet attached to an actual VirtualFile/PsiFile.
+ if (currentlyModifiedDocuments.contains(filePath)) {
+ int editorOffset = textEditor.getCaretModel().getOffset();
+ eventQueue.addEvent(KiteEventFactory.create(EventType.EDIT, filePath, FileEditorUtil.contentOf(document), TextSelection.create(editorOffset), document, true));
+ }
+ } finally {
+ currentlyModifiedDocuments.remove(filePath);
+ }
+ }
+
+ // taken from JetBrain's Alarm as it was removed from 183.x
+ private static boolean isEventDispatchThread() {
+ Application app = ApplicationManager.getApplication();
+ return app != null && app.isDispatchThread() || EventQueue.isDispatchThread();
+ }
+}
diff --git a/src/main/java/com/kite/intellij/editor/events/TestcaseEditorEventListener.java b/src/main/java/com/kite/intellij/editor/events/TestcaseEditorEventListener.java
index f4398105..e57672b4 100644
--- a/src/main/java/com/kite/intellij/editor/events/TestcaseEditorEventListener.java
+++ b/src/main/java/com/kite/intellij/editor/events/TestcaseEditorEventListener.java
@@ -23,11 +23,8 @@
@SuppressWarnings("ComponentNotRegistered")
@TestOnly
public class TestcaseEditorEventListener extends DefaultEditorEventListener {
- public TestcaseEditorEventListener(Project project) {
- super(project,
- KiteConstants.DEFAULT_QUEUE_TIMEOUT_MILLIS,
- CanonicalFilePathFactory.getInstance(),
- KiteConstants.ALARM_DELAY_MILLIS);
+ public TestcaseEditorEventListener() {
+ super();
}
public static void sleepForQueueWork(Project project) throws InterruptedException {
diff --git a/src/main/java/com/kite/intellij/lang/documentation/DocumentationCleanup.java b/src/main/java/com/kite/intellij/lang/documentation/DocumentationCleanup.java
index c491cfe0..ddc191a5 100644
--- a/src/main/java/com/kite/intellij/lang/documentation/DocumentationCleanup.java
+++ b/src/main/java/com/kite/intellij/lang/documentation/DocumentationCleanup.java
@@ -5,6 +5,7 @@
import com.kite.intellij.backend.response.SymbolReportResponse;
import com.kite.intellij.backend.response.ValueReportResponse;
import org.jsoup.Jsoup;
+import org.jsoup.safety.Safelist;
import org.jsoup.safety.Whitelist;
/**
@@ -12,12 +13,12 @@
*
*/
class DocumentationCleanup {
- private static final Whitelist WHITELIST = Whitelist.relaxed()
+ private static final Safelist SAFELIST = Safelist.relaxed()
.addAttributes(":all", "class", "style", "title")
.addProtocols("a", "href", "kite", "#");
private static String cleanup(String html) {
- return Jsoup.clean(html, WHITELIST);
+ return Jsoup.clean(html, SAFELIST);
}
static HoverResponse cleanup(HoverResponse hover) {
diff --git a/src/main/java/com/kite/intellij/lang/documentation/KiteDocumentationRendererService.java b/src/main/java/com/kite/intellij/lang/documentation/KiteDocumentationRendererService.java
index b64c31c4..be2571cf 100644
--- a/src/main/java/com/kite/intellij/lang/documentation/KiteDocumentationRendererService.java
+++ b/src/main/java/com/kite/intellij/lang/documentation/KiteDocumentationRendererService.java
@@ -1,7 +1,6 @@
package com.kite.intellij.lang.documentation;
import com.intellij.openapi.Disposable;
-import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
@@ -22,7 +21,7 @@ public KiteDocumentationRendererService() {
@Nonnull
public static KiteDocumentationRendererService getInstance(Project project) {
- return ServiceManager.getService(project, KiteDocumentationRendererService.class);
+ return project.getService(KiteDocumentationRendererService.class);
}
public KiteDocumentationRenderer getDetailedRenderer() {
diff --git a/src/main/java/com/kite/intellij/lang/documentation/linkHandler/KiteDocumentFileLinkHandler.java b/src/main/java/com/kite/intellij/lang/documentation/linkHandler/KiteDocumentFileLinkHandler.java
index cd55dca2..e6df704a 100644
--- a/src/main/java/com/kite/intellij/lang/documentation/linkHandler/KiteDocumentFileLinkHandler.java
+++ b/src/main/java/com/kite/intellij/lang/documentation/linkHandler/KiteDocumentFileLinkHandler.java
@@ -15,6 +15,7 @@
import javax.annotation.Nonnull;
import java.net.URI;
+import java.util.List;
import java.util.Optional;
/**
@@ -79,8 +80,8 @@ public void postRender(String link, LinkRenderContext renderContext) {
VirtualFile file = fileOpt.get();
- FileEditorProvider[] providers = FileEditorProviderManager.getInstance().getProviders(renderContext.getProject(), file);
- if (providers.length > 0) {
+ List providers = FileEditorProviderManager.getInstance().getProviderList(renderContext.getProject(), file);
+ if (!providers.isEmpty()) {
//configured line at column 0, the logical line passed to the descriptor seems to start at 0
OpenFileDescriptor descriptor = new OpenFileDescriptor(renderContext.getProject(), file, linkData.getLine().orElse(1) - 1, 0);
FileEditorManager.getInstance(renderContext.getProject()).openTextEditor(descriptor, true);
diff --git a/src/main/java/com/kite/intellij/notifications/KiteServiceNotificationsListener.java b/src/main/java/com/kite/intellij/notifications/KiteServiceNotificationsListener.java
index ea4b5a4b..3777170c 100644
--- a/src/main/java/com/kite/intellij/notifications/KiteServiceNotificationsListener.java
+++ b/src/main/java/com/kite/intellij/notifications/KiteServiceNotificationsListener.java
@@ -2,13 +2,15 @@
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.project.ProjectManagerListener;
+import com.intellij.openapi.startup.ProjectActivity;
import com.intellij.openapi.startup.StartupManager;
import com.kite.intellij.KiteProjectLifecycleService;
import com.kite.intellij.backend.KiteApiService;
import com.kite.intellij.backend.json.KiteJsonParsing;
import com.kite.intellij.backend.model.KiteServiceNotification;
import com.kite.intellij.ui.notifications.KiteNotifications;
+import kotlin.Unit;
+import kotlin.coroutines.Continuation;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
@@ -17,13 +19,14 @@
* Listens for HTTP responses with status 503 (service unavailable) and displays
* a notification if the HTTP response's body contained one.
*/
-public class KiteServiceNotificationsListener implements ProjectManagerListener {
+public class KiteServiceNotificationsListener implements ProjectActivity {
private static final Logger LOG = Logger.getInstance("#kite.notifications");
+ @org.jetbrains.annotations.Nullable
@Override
- public void projectOpened(@NotNull Project project) {
+ public Object execute(@NotNull Project project, @NotNull Continuation super Unit> continuation) {
if (project.isDefault()) {
- return;
+ return null;
}
StartupManager.getInstance(project).runAfterOpened(() -> {
@@ -45,6 +48,7 @@ public void projectOpened(@NotNull Project project) {
return false;
}, KiteProjectLifecycleService.getInstance(project));
});
+ return null;
}
private void handleKiteNotification(@NotNull Project project, @Nullable String body) {
diff --git a/src/main/java/com/kite/intellij/platform/KiteDetector.java b/src/main/java/com/kite/intellij/platform/KiteDetector.java
index 95e114e6..63964842 100644
--- a/src/main/java/com/kite/intellij/platform/KiteDetector.java
+++ b/src/main/java/com/kite/intellij/platform/KiteDetector.java
@@ -1,6 +1,6 @@
package com.kite.intellij.platform;
-import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.SystemInfo;
import com.kite.intellij.platform.exec.ExecutableDetector;
import com.kite.intellij.platform.exec.GenericProcessLauncher;
@@ -51,7 +51,7 @@ public KiteDetector() {
@Nonnull
public static KiteDetector getInstance() {
- return ServiceManager.getService(KiteDetector.class);
+ return ApplicationManager.getApplication().getService(KiteDetector.class);
}
@Override
diff --git a/src/main/java/com/kite/intellij/platform/KitePlatform.java b/src/main/java/com/kite/intellij/platform/KitePlatform.java
index 6de67dd5..d67ea2a8 100644
--- a/src/main/java/com/kite/intellij/platform/KitePlatform.java
+++ b/src/main/java/com/kite/intellij/platform/KitePlatform.java
@@ -19,12 +19,14 @@ public class KitePlatform {
public static boolean isOsVersionSupported() {
if (SystemInfo.isMac) {
LOG.debug("OS: Mac" + SystemInfo.getMacOSVersionCode());
- return SystemInfo.isMacOSYosemite;
+
+ // Under JAVA 17, MAC already have enough version for this.
+ return true;
+ //return SystemInfo.isMacOSYosemite;
}
if (SystemInfo.isWindows) {
- LOG.debug("OS: Windows " + SystemInfo.isWin7OrNewer + ", 64 bit: " + SystemInfo.is64Bit);
- return SystemInfo.isWin7OrNewer /*&& SystemInfo.is64Bit*/; //the arch seems to equal the Java VM arch, but we need the installed OS architecture, disabled for now
+ return true;
}
if (SystemInfo.isLinux) {
@@ -47,4 +49,4 @@ public static boolean isOsVersionNotSupported() {
return !isOsVersionSupported();
}
}
-
\ No newline at end of file
+
diff --git a/src/main/java/com/kite/intellij/platform/KitePlatformComponent.java b/src/main/java/com/kite/intellij/platform/KitePlatformComponent.java
index ee28d104..6beca60a 100644
--- a/src/main/java/com/kite/intellij/platform/KitePlatformComponent.java
+++ b/src/main/java/com/kite/intellij/platform/KitePlatformComponent.java
@@ -1,49 +1,35 @@
package com.kite.intellij.platform;
import com.intellij.notification.Notification;
-import com.intellij.notification.NotificationListener;
import com.intellij.notification.NotificationType;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.startup.ProjectActivity;
import com.kite.intellij.Icons;
import com.kite.intellij.ui.notifications.KiteNotifications;
+import kotlin.Unit;
+import kotlin.coroutines.Continuation;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.annotation.Nonnull;
/**
* Project component which displays a warning if the current OS or OS version is not supported by Kite.
*/
-public class KitePlatformComponent implements com.intellij.openapi.components.ProjectComponent {
- private final Project project;
-
- public KitePlatformComponent(Project project) {
- this.project = project;
- }
-
- @Nonnull
- public static KitePlatformComponent getInstance(Project project) {
- return project.getComponent(KitePlatformComponent.class);
- }
-
- @Nonnull
- @Override
- public String getComponentName() {
- return "kite.PlatformComponent";
- }
-
+public class KitePlatformComponent implements ProjectActivity {
+ @Nullable
@Override
- public void projectOpened() {
+ public Object execute(@NotNull Project project, @NotNull Continuation super Unit> continuation) {
if (KitePlatform.isOsVersionNotSupported()) {
String title = "Kite";
String subtitle = "Unsupported platform";
String content = "Kite is currently not yet available for your system. Please check kite.com for the currently supported platforms.";
- Notification notification = new Notification(KiteNotifications.KITE_GROUP.getDisplayId(), Icons.KiteSmall, title, subtitle, content, NotificationType.ERROR, new NotificationListener.UrlOpeningListener(false));
+ Notification notification = new Notification(KiteNotifications.KITE_GROUP.getDisplayId(), title, content, NotificationType.ERROR);
+ notification.setSubtitle(subtitle);
+ notification.setIcon(Icons.KiteSmall);
notification.notify(project);
}
- }
-
- @Override
- public void projectClosed() {
-
+ return null;
}
}
diff --git a/src/main/java/com/kite/intellij/platform/exec/GenericProcessWatcher.java b/src/main/java/com/kite/intellij/platform/exec/GenericProcessWatcher.java
index c1813502..10062f52 100644
--- a/src/main/java/com/kite/intellij/platform/exec/GenericProcessWatcher.java
+++ b/src/main/java/com/kite/intellij/platform/exec/GenericProcessWatcher.java
@@ -5,7 +5,7 @@
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.util.SystemProperties;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
import javax.annotation.Nonnull;
import java.nio.file.Files;
diff --git a/src/main/java/com/kite/intellij/platform/fs/CanonicalFilePathFactory.java b/src/main/java/com/kite/intellij/platform/fs/CanonicalFilePathFactory.java
index e7f3c93d..d839bd4d 100644
--- a/src/main/java/com/kite/intellij/platform/fs/CanonicalFilePathFactory.java
+++ b/src/main/java/com/kite/intellij/platform/fs/CanonicalFilePathFactory.java
@@ -1,5 +1,6 @@
package com.kite.intellij.platform.fs;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
@@ -17,7 +18,7 @@
public interface CanonicalFilePathFactory {
@Nonnull
static CanonicalFilePathFactory getInstance() {
- return ServiceManager.getService(CanonicalFilePathFactory.class);
+ return ApplicationManager.getApplication().getService(CanonicalFilePathFactory.class);
}
@Nullable
diff --git a/src/main/java/com/kite/intellij/settings/KiteSettingsService.java b/src/main/java/com/kite/intellij/settings/KiteSettingsService.java
index 262c767f..a2b6d1c4 100644
--- a/src/main/java/com/kite/intellij/settings/KiteSettingsService.java
+++ b/src/main/java/com/kite/intellij/settings/KiteSettingsService.java
@@ -2,8 +2,8 @@
import com.google.common.collect.Lists;
import com.intellij.openapi.Disposable;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.PersistentStateComponent;
-import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import com.intellij.openapi.util.Disposer;
@@ -27,7 +27,7 @@ public KiteSettingsService() {
}
public static KiteSettingsService getInstance() {
- return ServiceManager.getService(KiteSettingsService.class);
+ return ApplicationManager.getApplication().getService(KiteSettingsService.class);
}
@Nonnull
diff --git a/src/main/java/com/kite/intellij/startup/KiteAutomaticInstallNotification.java b/src/main/java/com/kite/intellij/startup/KiteAutomaticInstallNotification.java
index dc950f1c..5e1fb898 100644
--- a/src/main/java/com/kite/intellij/startup/KiteAutomaticInstallNotification.java
+++ b/src/main/java/com/kite/intellij/startup/KiteAutomaticInstallNotification.java
@@ -33,11 +33,10 @@ public static void showNotification(@Nullable Project project, @NotNull Runnable
private static class InstallNotification extends Notification implements NotificationFullContent {
private InstallNotification(@NotNull Runnable onInstallCallback) {
super(KiteNotifications.KITE_GROUP.getDisplayId(),
- Icons.KiteSmall,
- "Kite", "",
+ "Kite",
"Kite requires the Kite Copilot desktop application to provide completions and documentation. Please install it to use Kite.",
- NotificationType.INFORMATION, null);
-
+ NotificationType.INFORMATION);
+ this.setIcon(Icons.KiteSmall);
addAction(new NotificationAction("Install") {
@Override
public void actionPerformed(@NotNull AnActionEvent e, @NotNull Notification notification) {
diff --git a/src/main/java/com/kite/intellij/startup/KiteDownloadPausedNotification.java b/src/main/java/com/kite/intellij/startup/KiteDownloadPausedNotification.java
index a8c1c8d8..18293807 100644
--- a/src/main/java/com/kite/intellij/startup/KiteDownloadPausedNotification.java
+++ b/src/main/java/com/kite/intellij/startup/KiteDownloadPausedNotification.java
@@ -31,11 +31,10 @@ public static void showNotification(@Nullable Project project) {
private static class PausedNotification extends Notification implements NotificationFullContent {
private PausedNotification() {
super(KiteNotifications.KITE_GROUP.getDisplayId(),
- Icons.KiteSmall,
- "Temporarily unable to install", "",
+ "Temporarily unable to install",
"Kite requires the Kite Copilot to function. However, it cannot be downloaded for the next few weeks. This plugin will notify you when it's available again.",
- NotificationType.INFORMATION, null);
-
+ NotificationType.INFORMATION);
+ this.setIcon(Icons.KiteSmall);
addAction(new NotificationAction("Close") {
@Override
public void actionPerformed(@NotNull AnActionEvent e, @NotNull Notification notification) {
diff --git a/src/main/java/com/kite/intellij/startup/KiteDownloadUnpausedNotification.java b/src/main/java/com/kite/intellij/startup/KiteDownloadUnpausedNotification.java
index a10b7f88..037d2593 100644
--- a/src/main/java/com/kite/intellij/startup/KiteDownloadUnpausedNotification.java
+++ b/src/main/java/com/kite/intellij/startup/KiteDownloadUnpausedNotification.java
@@ -33,12 +33,12 @@ public static void showNotification(@Nullable Project project, @NotNull Runnable
private static class UnpausedNotification extends Notification implements NotificationFullContent {
private UnpausedNotification(@NotNull Runnable onInstallCallback) {
super(KiteNotifications.KITE_GROUP.getDisplayId(),
- Icons.KiteSmall,
- "Kite", "",
+ "Kite",
"The Kite Engine application is installable again. " +
"Kite requires the Kite Engine desktop application to provide completions and documentation. " +
"Please install it to use Kite.",
- NotificationType.INFORMATION, null);
+ NotificationType.INFORMATION);
+ this.setIcon(Icons.KiteSmall);
addAction(new NotificationAction("Install") {
@Override
diff --git a/src/main/java/com/kite/intellij/startup/KiteProjectManagerListener.java b/src/main/java/com/kite/intellij/startup/KiteProjectManagerListener.java
index 2ed674eb..b7738c9d 100644
--- a/src/main/java/com/kite/intellij/startup/KiteProjectManagerListener.java
+++ b/src/main/java/com/kite/intellij/startup/KiteProjectManagerListener.java
@@ -5,14 +5,17 @@
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.project.ProjectManagerListener;
+import com.intellij.openapi.startup.ProjectActivity;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtilRt;
import com.kite.intellij.platform.KiteDetector;
import com.kite.intellij.platform.KiteInstallService;
import com.kite.intellij.settings.KiteSettingsService;
+import kotlin.Unit;
+import kotlin.coroutines.Continuation;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
@@ -25,14 +28,15 @@
* notifications have to be displayed. The application listener has no project and may be executed before a project
* window is shown.
*/
-public class KiteProjectManagerListener implements ProjectManagerListener {
+public class KiteProjectManagerListener implements ProjectActivity {
private static final Logger LOG = Logger.getInstance("#kite.startup");
private static volatile boolean firstProjectOpened;
+ @Nullable
@Override
- public void projectOpened(@NotNull Project project) {
+ public Object execute(@NotNull Project project, @NotNull Continuation super Unit> continuation) {
if (project.isDefault() || firstProjectOpened) {
- return;
+ return null;
}
StartupManager.getInstance(project).runAfterOpened(() -> {
@@ -45,8 +49,8 @@ public void projectOpened(@NotNull Project project) {
ApplicationManager.getApplication().executeOnPooledThread(() -> onAppStarting(project));
}
});
+ return null;
}
-
private void onAppStarting(@NotNull Project project) {
if (KiteDetector.getInstance().isRunning()) {
return;
@@ -135,8 +139,6 @@ private boolean downloadAndInstallKite() {
* @return {@code true} if the current IDE is incompatible with the autostart feature.
*/
private static boolean disallowKitedAutostart() {
- return SystemInfo.isWin7OrNewer
- && !SystemInfo.isWin8OrNewer
- && ApplicationInfo.getInstance().getBuild().getBaselineVersion() == 193;
+ return false;
}
}
diff --git a/src/main/java/com/kite/intellij/startup/NotificationRegistration.java b/src/main/java/com/kite/intellij/startup/NotificationRegistration.java
index 48ef3273..fdb36cf9 100644
--- a/src/main/java/com/kite/intellij/startup/NotificationRegistration.java
+++ b/src/main/java/com/kite/intellij/startup/NotificationRegistration.java
@@ -1,8 +1,8 @@
package com.kite.intellij.startup;
-import com.intellij.openapi.application.PreloadingActivity;
-import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.ide.ApplicationInitializedListener;
import com.kite.intellij.ui.notifications.KiteNotifications;
+import kotlinx.coroutines.CoroutineScope;
import javax.annotation.Nonnull;
@@ -10,12 +10,12 @@
* This preloading activity takes care of the Kite notification group.
*
*/
-public class NotificationRegistration extends PreloadingActivity {
+public class NotificationRegistration implements ApplicationInitializedListener {
public NotificationRegistration() {
}
- @Override
- public void preload(@Nonnull ProgressIndicator indicator) {
+
+ public void execute(CoroutineScope asyncScope) {
// access the Kite notification group to force it to initialize
KiteNotifications.KITE_GROUP.getDisplayId();
}
diff --git a/src/main/java/com/kite/intellij/status/KiteStatusBarWidget.java b/src/main/java/com/kite/intellij/status/KiteStatusBarWidget.java
index 7f530069..b7fdc2e9 100644
--- a/src/main/java/com/kite/intellij/status/KiteStatusBarWidget.java
+++ b/src/main/java/com/kite/intellij/status/KiteStatusBarWidget.java
@@ -66,7 +66,7 @@ public KiteStatusBarWidget(@NotNull Project project) {
iconLabel = new JBLabel();
iconLabel.putClientProperty(UIUtil.CENTER_TOOLTIP_DEFAULT, Boolean.TRUE);
iconLabel.setOpaque(true);
- iconLabel.setBorder(WidgetBorder.ICON);
+ //iconLabel.setBorder(WidgetBorder.ICON);
connectionStatusListener = (connectionAvailable, error) -> {
if (!connectionAvailable) {
@@ -126,7 +126,7 @@ public String ID() {
public void install(@Nonnull StatusBar statusBar) {
super.install(statusBar);
- Editor editor = FileEditorManager.getInstance(myProject).getSelectedTextEditor();
+ Editor editor = FileEditorManager.getInstance(getProject()).getSelectedTextEditor();
CanonicalFilePath currentEditorFile = editor == null ? null : CanonicalFilePathFactory.getInstance().createFor(editor, CanonicalFilePathFactory.Context.Event);
Pair status = computeIconStatus(currentEditorFile, null, KiteApiService.getInstance());
updateStatusbarIcon(status);
@@ -157,7 +157,6 @@ public void dispose() {
*
* @param event The event
*/
- @Override
public void selectionChanged(@NotNull FileEditorManagerEvent event) {
refreshStatusIconAsync();
}
@@ -237,7 +236,7 @@ public boolean openStatusPanel() {
kiteStatusResponse != null ? kiteStatusResponse.getButton() : null);
//the swing component must be made visible in the AWT EDT
- UIUtil.invokeLaterIfNeeded(() -> popupController.show(KiteStatusBarWidget.this, myProject, model));
+ UIUtil.invokeLaterIfNeeded(() -> popupController.show(KiteStatusBarWidget.this, getProject(), model));
} catch (Exception e) {
LOG.error("Error while retrieving kite status", e);
}
@@ -308,7 +307,7 @@ static Pair computeIconStatus(@Nullable CanonicalFilePath cu
}
private void closePopup() {
- JBPopup currentPopup = popupController.getCurrentPopup(myProject);
+ JBPopup currentPopup = popupController.getCurrentPopup(getProject());
if (currentPopup != null) {
currentPopup.closeOk(null);
}
@@ -316,7 +315,7 @@ private void closePopup() {
private void updateStatusbarIcon(@Nullable Pair iconAndText) {
// myProject may be null if this widget is already disposed
- if (isDisposed() || myProject.isDisposed()) {
+ if (isDisposed() || getProject().isDisposed()) {
return;
}
@@ -332,7 +331,7 @@ private void updateStatusbarIcon(@Nullable Pair iconAndText)
// disabled for now, as Kite's message is too long
//iconLabel.setText(iconAndText.second);
} else {
- iconLabel.setBorder(WidgetBorder.ICON);
+ //iconLabel.setBorder(WidgetBorder.ICON);
}
});
}
diff --git a/src/main/java/com/kite/intellij/status/KiteStatusBarWidgetFactory.java b/src/main/java/com/kite/intellij/status/KiteStatusBarWidgetFactory.java
new file mode 100644
index 00000000..db98a98a
--- /dev/null
+++ b/src/main/java/com/kite/intellij/status/KiteStatusBarWidgetFactory.java
@@ -0,0 +1,25 @@
+package com.kite.intellij.status;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.NlsContexts;
+import com.intellij.openapi.wm.StatusBarWidget;
+import com.intellij.openapi.wm.StatusBarWidgetFactory;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+public class KiteStatusBarWidgetFactory implements StatusBarWidgetFactory {
+ @Override
+ public @NotNull @NonNls String getId() {
+ return "kite.statusbar.widgetfactory";
+ }
+
+ @Override
+ public @NotNull @NlsContexts.ConfigurableName String getDisplayName() {
+ return "Kite";
+ }
+
+ @Override
+ public @NotNull StatusBarWidget createWidget(@NotNull Project project) {
+ return new KiteStatusBarWidget(project);
+ }
+}
diff --git a/src/main/java/com/kite/intellij/status/KiteStatusBarWidgetProvider.java b/src/main/java/com/kite/intellij/status/KiteStatusBarWidgetProvider.java
deleted file mode 100644
index 42011eaf..00000000
--- a/src/main/java/com/kite/intellij/status/KiteStatusBarWidgetProvider.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.kite.intellij.status;
-
-import com.intellij.diagnostic.IdeMessagePanel;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.wm.StatusBar;
-import com.intellij.openapi.wm.StatusBarWidget;
-import com.intellij.openapi.wm.StatusBarWidgetProvider;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class KiteStatusBarWidgetProvider implements StatusBarWidgetProvider {
- @Override
- public @Nullable StatusBarWidget getWidget(@NotNull Project project) {
- return new KiteStatusBarWidget(project);
- }
-
- @Override
- public @NotNull String getAnchor() {
- return StatusBar.Anchors.before(IdeMessagePanel.FATAL_ERROR);
- }
-}
diff --git a/src/main/java/com/kite/intellij/status/KiteStatusModel.java b/src/main/java/com/kite/intellij/status/KiteStatusModel.java
index 9f02bc79..d6c417d9 100644
--- a/src/main/java/com/kite/intellij/status/KiteStatusModel.java
+++ b/src/main/java/com/kite/intellij/status/KiteStatusModel.java
@@ -21,7 +21,7 @@
import com.kite.intellij.platform.KiteDetector;
import com.kite.intellij.platform.fs.CanonicalFilePath;
import com.kite.intellij.util.KiteBrowserUtil;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nonnull;
diff --git a/src/main/java/com/kite/intellij/ui/KiteThemeUtil.java b/src/main/java/com/kite/intellij/ui/KiteThemeUtil.java
index 09f07aef..7c358af5 100644
--- a/src/main/java/com/kite/intellij/ui/KiteThemeUtil.java
+++ b/src/main/java/com/kite/intellij/ui/KiteThemeUtil.java
@@ -19,7 +19,6 @@
* look&feel.
*
*/
-@SuppressWarnings("UseJBColor")
public class KiteThemeUtil {
private KiteThemeUtil() {
}
@@ -47,7 +46,7 @@ public static boolean isConsistentToLookAndFeel(EditorColorsScheme scheme) {
public static Color getPanelBackground(EditorColorsScheme colorScheme) {
if (isConsistentToLookAndFeel(colorScheme)) {
//the default light look&feel has a yellow bg color in 161.x, at least
- return new JBColor(() -> UIManager.getColor("Panel.background"));
+ return JBColor.lazy(() -> UIManager.getColor("Panel.background"));
}
//the theme doesn't fit to the look&feel, i.e. probably a light theme for a dark look&feel (or a dark theme for a light look&feel)
diff --git a/src/main/java/com/kite/intellij/ui/html/InvalidHTMLException.java b/src/main/java/com/kite/intellij/ui/html/InvalidHTMLException.java
index f84c4338..b4fb74e8 100644
--- a/src/main/java/com/kite/intellij/ui/html/InvalidHTMLException.java
+++ b/src/main/java/com/kite/intellij/ui/html/InvalidHTMLException.java
@@ -1,6 +1,6 @@
package com.kite.intellij.ui.html;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.Nullable;
public class InvalidHTMLException extends RuntimeException {
diff --git a/src/main/java/com/kite/intellij/ui/html/KiteXHTMLPanel.java b/src/main/java/com/kite/intellij/ui/html/KiteXHTMLPanel.java
index 417a0d4d..7cae3ad6 100644
--- a/src/main/java/com/kite/intellij/ui/html/KiteXHTMLPanel.java
+++ b/src/main/java/com/kite/intellij/ui/html/KiteXHTMLPanel.java
@@ -140,19 +140,19 @@ public void log(String where, Level level, String msg, Throwable throwable) {
public void setLevel(String logger, Level level) {
Logger log = LOGGERS.get(logger);
if (log != null) {
- org.apache.log4j.Level targetLevel;
+ com.intellij.openapi.diagnostic.LogLevel targetLevel;
if (level == Level.ALL) {
- targetLevel = org.apache.log4j.Level.ERROR;
+ targetLevel = com.intellij.openapi.diagnostic.LogLevel.ERROR;
} else if (level == Level.SEVERE) {
- targetLevel = org.apache.log4j.Level.ERROR;
+ targetLevel = com.intellij.openapi.diagnostic.LogLevel.ERROR;
} else if (level == Level.WARNING) {
- targetLevel = org.apache.log4j.Level.WARN;
+ targetLevel = com.intellij.openapi.diagnostic.LogLevel.WARNING;
} else if (level == Level.INFO) {
- targetLevel = org.apache.log4j.Level.INFO;
+ targetLevel = com.intellij.openapi.diagnostic.LogLevel.INFO;
} else if (level == Level.FINE) {
- targetLevel = org.apache.log4j.Level.DEBUG;
+ targetLevel = com.intellij.openapi.diagnostic.LogLevel.DEBUG;
} else {
- targetLevel = org.apache.log4j.Level.TRACE;
+ targetLevel = com.intellij.openapi.diagnostic.LogLevel.TRACE;
}
log.setLevel(targetLevel);
diff --git a/src/main/java/com/kite/intellij/ui/notifications/KiteNotifications.java b/src/main/java/com/kite/intellij/ui/notifications/KiteNotifications.java
index df2d66b2..49dd259d 100644
--- a/src/main/java/com/kite/intellij/ui/notifications/KiteNotifications.java
+++ b/src/main/java/com/kite/intellij/ui/notifications/KiteNotifications.java
@@ -15,7 +15,7 @@
import javax.annotation.Nullable;
public class KiteNotifications {
- public static final NotificationGroup KITE_GROUP = new NotificationGroup("Kite", NotificationDisplayType.STICKY_BALLOON, true);
+ public static final NotificationGroup KITE_GROUP = NotificationGroupManager.getInstance().getNotificationGroup("Kite");
public static void showServiceNotification(@Nullable Project project, @Nonnull KiteServiceNotification kiteNotification) {
// don't show more than one notification at a time
@@ -65,7 +65,8 @@ public void actionPerformed(@NotNull AnActionEvent e, @NotNull Notification noti
private static class KiteServiceUINotification extends Notification implements NotificationFullContent, KiteNotification {
public KiteServiceUINotification(@NotNull NotificationType type) {
- super(KiteNotifications.KITE_GROUP.getDisplayId(), Icons.KiteSmall, type);
+ super(KiteNotifications.KITE_GROUP.getDisplayId(), "", type);
+ this.setIcon(Icons.KiteSmall);
}
}
}
diff --git a/src/main/java/com/kite/intellij/util/SwingDebugUtil.java b/src/main/java/com/kite/intellij/util/SwingDebugUtil.java
index 041d60c2..1e0cee8f 100644
--- a/src/main/java/com/kite/intellij/util/SwingDebugUtil.java
+++ b/src/main/java/com/kite/intellij/util/SwingDebugUtil.java
@@ -1,6 +1,6 @@
package com.kite.intellij.util;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
import javax.swing.*;
import java.awt.*;
diff --git a/src/main/java/com/kite/intellij/welcome/KiteOnboardingManager.java b/src/main/java/com/kite/intellij/welcome/KiteOnboardingManager.java
index 7f4d547f..c3d133ae 100644
--- a/src/main/java/com/kite/intellij/welcome/KiteOnboardingManager.java
+++ b/src/main/java/com/kite/intellij/welcome/KiteOnboardingManager.java
@@ -157,7 +157,7 @@ public static void showErrorNotification(@Nullable Project project, @Nullable St
new KiteWelcomeNotification(
"We were unable to open the tutorial",
message.toString(),
- NotificationType.ERROR, null
+ NotificationType.ERROR
).notify(project);
}
}
diff --git a/src/main/java/com/kite/intellij/welcome/KiteWelcomeNotification.java b/src/main/java/com/kite/intellij/welcome/KiteWelcomeNotification.java
index bbd15ce1..edfda08a 100644
--- a/src/main/java/com/kite/intellij/welcome/KiteWelcomeNotification.java
+++ b/src/main/java/com/kite/intellij/welcome/KiteWelcomeNotification.java
@@ -16,7 +16,8 @@
*
*/
class KiteWelcomeNotification extends Notification implements KiteNotification, NotificationFullContent {
- public KiteWelcomeNotification(@Nullable String title, @Nullable String content, @Nonnull NotificationType type, @Nullable NotificationListener listener) {
- super(KiteNotifications.KITE_GROUP.getDisplayId(), Icons.KiteSmall, title, null, content, type, listener);
+ public KiteWelcomeNotification(@Nullable String title, @Nullable String content, @Nonnull NotificationType type) {
+ super(KiteNotifications.KITE_GROUP.getDisplayId(), title == null ? "Kite" : title, content == null ? "" : content, type);
+ this.setIcon(Icons.KiteSmall);
}
}
diff --git a/src/main/java/com/kite/intellij/welcome/KiteWelcomeProjectListener.java b/src/main/java/com/kite/intellij/welcome/KiteWelcomeProjectListener.java
index 11309fc2..a7d4036a 100644
--- a/src/main/java/com/kite/intellij/welcome/KiteWelcomeProjectListener.java
+++ b/src/main/java/com/kite/intellij/welcome/KiteWelcomeProjectListener.java
@@ -9,11 +9,12 @@
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.project.ProjectManagerListener;
+import com.intellij.openapi.startup.ProjectActivity;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.util.messages.MessageBusConnection;
import com.kite.intellij.KiteConstants;
+import com.kite.intellij.KiteProjectLifecycleService;
import com.kite.intellij.backend.KiteApiService;
import com.kite.intellij.backend.KiteServerSettings;
import com.kite.intellij.backend.http.KiteHttpException;
@@ -21,7 +22,10 @@
import com.kite.intellij.settings.KiteSettingsService;
import com.kite.intellij.startup.KiteAutostartListener;
import com.kite.intellij.util.KiteBrowserUtil;
+import kotlin.Unit;
+import kotlin.coroutines.Continuation;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.annotation.Nonnull;
import javax.swing.*;
@@ -33,17 +37,18 @@
* The notification contains a link to the public http url and an ignore action to suppress the message on next startup.
*
*/
-public class KiteWelcomeProjectListener implements ProjectManagerListener, DumbAware {
+public class KiteWelcomeProjectListener implements ProjectActivity, DumbAware {
private static final Logger LOG = Logger.getInstance("#kite.welcome");
+ @Nullable
@Override
- public void projectOpened(@NotNull Project project) {
- StartupManager.getInstance(project).runWhenProjectIsInitialized(() -> {
+ public Object execute(@NotNull Project project, @NotNull Continuation super Unit> continuation) {
+ StartupManager.getInstance(project).runAfterOpened(() -> {
Application app = ApplicationManager.getApplication();
- MessageBusConnection connection = app.getMessageBus().connect(project);
+ MessageBusConnection connection = app.getMessageBus().connect(project.getService(KiteProjectLifecycleService.class));
// if this plugin starts kited, then do onboarding as soon as it's available
- connection.subscribe(KiteAutostartListener.TOPIC, () -> {
+ connection.subscribe(KiteAutostartListener.TOPIC, (KiteAutostartListener) () -> {
JFrame frame = WindowManager.getInstance().getFrame(project);
if (frame != null && frame.isActive()) {
app.executeOnPooledThread(() -> doOnboarding(project));
@@ -59,8 +64,10 @@ public void projectOpened(@NotNull Project project) {
}
}
});
+ return null;
}
+
private void doOnboarding(@NotNull Project project) {
assert ApplicationManager.getApplication().isUnitTestMode() || !ApplicationManager.getApplication().isDispatchThread();
@@ -96,7 +103,7 @@ private void doOnboarding(@NotNull Project project) {
Notification notification = new KiteWelcomeNotification(
"Welcome to the future of programming.",
"Kite is now integrated with your IDE.",
- NotificationType.INFORMATION, null);
+ NotificationType.INFORMATION);
notification.addAction(new ShowKiteDocsAction(notification, "Learn how to use Kite"));
notification.addAction(new DisableWelcomeInfoAction(notification));
notification.notify(project);
@@ -114,7 +121,7 @@ private void doOnboardingAction(@Nonnull KiteLanguage language, Project project)
Notification notification = new KiteWelcomeNotification("Welcome to Kite!",
"We've setup an interactive tutorial for you, but we have docs to get you started too!
",
- NotificationType.INFORMATION, null);
+ NotificationType.INFORMATION);
notification.addAction(new ShowKiteDocsAction(notification, "Learn more about Kite"));
notification.addAction(new DisableWelcomeInfoAction(notification));
notification.notify(project);
diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml
index 9e33db4c..9f942b05 100644
--- a/src/main/resources/META-INF/plugin.xml
+++ b/src/main/resources/META-INF/plugin.xml
@@ -23,15 +23,8 @@
-
-
-
-
+
@@ -83,9 +76,7 @@
-
-
-
+
Kite
kiteCodeNavIntention
+
+
+
+
+
+
+
diff --git a/src/test/java/com/kite/intellij/editor/completion/KiteCompletionAutoinsertTest.java b/src/test/java/com/kite/intellij/editor/completion/KiteCompletionAutoinsertTest.java
index 3df29867..910879b3 100644
--- a/src/test/java/com/kite/intellij/editor/completion/KiteCompletionAutoinsertTest.java
+++ b/src/test/java/com/kite/intellij/editor/completion/KiteCompletionAutoinsertTest.java
@@ -10,7 +10,7 @@
import com.kite.intellij.editor.events.TestcaseEditorEventListener;
import com.kite.intellij.settings.KiteSettingsService;
import com.kite.intellij.test.KiteLightFixtureTest;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.junit.Assert;
import org.junit.Test;
diff --git a/src/test/java/com/kite/intellij/editor/events/DefaultEditorEventListenerTest.java b/src/test/java/com/kite/intellij/editor/events/DefaultEditorEventListenerTest.java
index d6e7f711..f63b8ef9 100644
--- a/src/test/java/com/kite/intellij/editor/events/DefaultEditorEventListenerTest.java
+++ b/src/test/java/com/kite/intellij/editor/events/DefaultEditorEventListenerTest.java
@@ -173,7 +173,7 @@ public void testUnsupportedFilesWhitelisting() throws Exception {
@Test
public void testOnFrameActivation() throws Exception {
- DefaultEditorEventListener eventListener = (DefaultEditorEventListener) EditorEventListener.getInstance(getProject());
+ ProjectEditorEventListener eventListener = (ProjectEditorEventListener) EditorEventListener.getInstance(getProject());
MockKiteApiService api = MockKiteApiService.getInstance();
Assert.assertTrue("No api calls expected before the edit events", api.getCallHistory().isEmpty());
@@ -224,7 +224,7 @@ public void testAwaitEventsInSwingThread() throws Exception {
AtomicBoolean inAwaitCall = new AtomicBoolean(false);
List performedRequests = new CopyOnWriteArrayList<>();
- DefaultEditorEventListener listener = new DefaultEditorEventListener(getProject(), 500, CanonicalFilePathFactory.getInstance(), 500) {
+ ProjectEditorEventListener listener = new ProjectEditorEventListener(getProject()) {
@Override
public void awaitEvents() {
awaitWasCalled.set(true);
diff --git a/src/test/java/com/kite/intellij/editor/events/EditorEventLatencyTest.java b/src/test/java/com/kite/intellij/editor/events/EditorEventLatencyTest.java
index a408c8fc..70af9de9 100644
--- a/src/test/java/com/kite/intellij/editor/events/EditorEventLatencyTest.java
+++ b/src/test/java/com/kite/intellij/editor/events/EditorEventLatencyTest.java
@@ -6,7 +6,7 @@
import com.kite.intellij.backend.MockKiteApiService;
import com.kite.intellij.backend.http.test.MockKiteHttpConnection;
import com.kite.intellij.test.KiteLightFixtureTest;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
diff --git a/src/test/java/com/kite/intellij/test/KiteTestUtils.java b/src/test/java/com/kite/intellij/test/KiteTestUtils.java
index 54bd8b14..88f5de22 100644
--- a/src/test/java/com/kite/intellij/test/KiteTestUtils.java
+++ b/src/test/java/com/kite/intellij/test/KiteTestUtils.java
@@ -7,7 +7,7 @@
import com.intellij.openapi.util.io.StreamUtil;
import com.intellij.psi.PsiFile;
import com.intellij.testFramework.fixtures.CodeInsightTestFixture;
-import com.kite.intellij.editor.events.DefaultEditorEventListener;
+import com.kite.intellij.editor.events.ProjectEditorEventListener;
import com.kite.intellij.editor.events.EditorEventListener;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
@@ -133,11 +133,11 @@ public static void configureByFileAndFocus(String filePath, CodeInsightTestFixtu
public static void emulateFocusEvent(PsiFile psiFile) {
Project project = psiFile.getProject();
Editor selectedTextEditor = FileEditorManager.getInstance(project).getSelectedTextEditor();
- ((DefaultEditorEventListener) EditorEventListener.getInstance(project)).fileFocused(selectedTextEditor, psiFile.getVirtualFile());
+ ((ProjectEditorEventListener) EditorEventListener.getInstance(project)).fileFocused(selectedTextEditor, psiFile.getVirtualFile());
}
public static void emulatedFrameActivation(Project project) {
- ((DefaultEditorEventListener) EditorEventListener.getInstance(project)).onFrameActivated();
+ ((ProjectEditorEventListener) EditorEventListener.getInstance(project)).onFrameActivated();
}
private static String trimHtmlWhitespace(String prettyHtml) {
diff --git a/src/test/java/com/kite/testrunner/TestRunnerUtil.java b/src/test/java/com/kite/testrunner/TestRunnerUtil.java
index 36f3fd4d..6e22a9b1 100644
--- a/src/test/java/com/kite/testrunner/TestRunnerUtil.java
+++ b/src/test/java/com/kite/testrunner/TestRunnerUtil.java
@@ -13,7 +13,7 @@
import com.intellij.util.ThrowableRunnable;
import com.kite.intellij.action.signatureInfo.KiteSignaturePopupManager;
import com.kite.intellij.editor.events.TestcaseEditorEventListener;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
import org.jetbrains.ide.PooledThreadExecutor;
import javax.annotation.Nonnull;
diff --git a/src/test/java/com/kite/testrunner/TestStepHelper.java b/src/test/java/com/kite/testrunner/TestStepHelper.java
index c08f1a76..29ca7d8c 100644
--- a/src/test/java/com/kite/testrunner/TestStepHelper.java
+++ b/src/test/java/com/kite/testrunner/TestStepHelper.java
@@ -6,7 +6,7 @@
import com.intellij.psi.PsiDocumentManager;
import com.kite.intellij.editor.events.TestcaseEditorEventListener;
import com.kite.testrunner.model.TestStep;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
import org.jetbrains.ide.PooledThreadExecutor;
import javax.annotation.Nonnull;
diff --git a/src/test/java/com/kite/testrunner/actions/RemoveTextAction.java b/src/test/java/com/kite/testrunner/actions/RemoveTextAction.java
index 108e27ee..3b8411cf 100644
--- a/src/test/java/com/kite/testrunner/actions/RemoveTextAction.java
+++ b/src/test/java/com/kite/testrunner/actions/RemoveTextAction.java
@@ -11,7 +11,7 @@
import com.kite.testrunner.TestRunnerUtil;
import com.kite.testrunner.model.TestStep;
import org.apache.commons.codec.digest.DigestUtils;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
import java.nio.charset.StandardCharsets;
diff --git a/src/test/java/com/kite/testrunner/expectations/RequestExpectation.java b/src/test/java/com/kite/testrunner/expectations/RequestExpectation.java
index 3cc89588..88f62670 100644
--- a/src/test/java/com/kite/testrunner/expectations/RequestExpectation.java
+++ b/src/test/java/com/kite/testrunner/expectations/RequestExpectation.java
@@ -10,7 +10,7 @@
import com.kite.testrunner.TestFailedException;
import com.kite.testrunner.TestRunnerUtil;
import com.kite.testrunner.model.TestStep;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
import java.util.Collections;
import java.util.LinkedList;