From 5622cf64f3d53f9114f16f64d7c3a1a3d3918cc4 Mon Sep 17 00:00:00 2001 From: zaaarf Date: Thu, 16 Nov 2023 02:59:49 +0100 Subject: [PATCH] feat: implemented JoinAction, sending/receiving cursor position --- .../intellij/actions/ConnectAction.java | 16 ++- .../codemp/intellij/actions/JoinAction.java | 106 ++++++++++++++++++ .../listeners/CursorEventListener.java | 31 +++++ src/main/resources/META-INF/plugin.xml | 9 +- 4 files changed, 157 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/codemp/intellij/actions/JoinAction.java create mode 100644 src/main/java/com/codemp/intellij/listeners/CursorEventListener.java diff --git a/src/main/java/com/codemp/intellij/actions/ConnectAction.java b/src/main/java/com/codemp/intellij/actions/ConnectAction.java index fe05e13..990df4c 100644 --- a/src/main/java/com/codemp/intellij/actions/ConnectAction.java +++ b/src/main/java/com/codemp/intellij/actions/ConnectAction.java @@ -4,20 +4,32 @@ import com.codemp.intellij.jni.CodeMPHandler; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.ui.Messages; +import cz.adamh.utils.NativeUtils; import org.jetbrains.annotations.NotNull; +import java.io.IOException; + public class ConnectAction extends AnAction { static { + /*try { + NativeUtils.loadLibraryFromJar("/resources/libHelloJNI.so"); + } catch(IOException e) { + throw new RuntimeException(e); + }*/ System.load("O:/dev/IRL/Rust/codemp/client/intellij/target/debug/codemp_intellij.dll"); } @Override public void actionPerformed(@NotNull AnActionEvent e) { - String url = Messages.showInputDialog("URL to CodeMP instance:", "CodeMP", Messages.getQuestionIcon()); + String url = Messages.showInputDialog("URL to CodeMP instance:", "CodeMP Connect", Messages.getQuestionIcon()); + if(url == null || url.isBlank()) + url = "http://alemi.dev:50051"; + try { CodeMPHandler.connect(url); - Messages.showInfoMessage(String.format("Connected to %s!", url), "CodeMP"); + //Messages.showInfoMessage(String.format("Connected to %s!", url), "CodeMP"); + System.out.printf("Connected to %s!%n", url); } catch(Exception ex) { Messages.showErrorDialog(String.format("Failed to connect to %s: %s!", url, ex.getMessage()), "CodeMP"); } diff --git a/src/main/java/com/codemp/intellij/actions/JoinAction.java b/src/main/java/com/codemp/intellij/actions/JoinAction.java new file mode 100644 index 0000000..8ebab61 --- /dev/null +++ b/src/main/java/com/codemp/intellij/actions/JoinAction.java @@ -0,0 +1,106 @@ +package com.codemp.intellij.actions; + +import com.codemp.intellij.jni.CodeMPHandler; +import com.codemp.intellij.jni.CursorEventWrapper; +import com.codemp.intellij.jni.CursorHandler; +import com.codemp.intellij.listeners.CursorEventListener; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.editor.markup.HighlighterLayer; +import com.intellij.openapi.editor.markup.HighlighterTargetArea; +import com.intellij.openapi.editor.markup.RangeHighlighter; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.Task; +import com.intellij.openapi.ui.Messages; +import com.intellij.ui.JBColor; +import org.jetbrains.annotations.NotNull; + +import java.awt.*; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +public class JoinAction extends AnAction { + + private final Map highlighterMap = new HashMap<>(); + + private static final TextAttributes HIGHLIGHTED = new TextAttributes( + null, JBColor.BLUE, null, null, Font.PLAIN + ); + + @Override + public void actionPerformed(@NotNull AnActionEvent e) { + String session = Messages.showInputDialog( + "Session to connect to:", + "CodeMP Join", + Messages.getQuestionIcon()); + if(session == null || session.isBlank()) + session = "default"; + + try { + CursorHandler cursorHandler = CodeMPHandler.join(session); + EditorFactory.getInstance() + .getEventMulticaster() + .addCaretListener(new CursorEventListener()); + //Messages.showInfoMessage(String.format("Joined %s!", session), "CodeMP"); + System.out.printf(String.format("Joined %s!", session)); + Editor editor = FileEditorManager.getInstance(Objects.requireNonNull(e.getProject())) + .getSelectedTextEditor(); + assert editor != null; + Document document = editor.getDocument(); + ProgressManager.getInstance().run(new Task.Backgroundable(e.getProject(), "Awaiting CodeMP cursor events") { + @Override + public void run(@NotNull ProgressIndicator indicator) { + while(true) { + try { + CursorEventWrapper event = cursorHandler.recv(); + ApplicationManager.getApplication().invokeLater(() -> { + try { + RangeHighlighter h = highlighterMap.get(event.getUser()); + if(h != null) + h.dispose(); + + System.out.printf( + "Cursor moved by user %s! Start pos: x%d y%d; end pos: x%d y%d with buffer %s%n\n", + event.getUser(), + event.getStartCol(), event.getStartCol(), + event.getEndRow(), event.getEndCol(), + event.getBuffer()); + + highlighterMap.put(event.getUser(), editor + .getMarkupModel() + .addRangeHighlighter(TextAttributesKey.createTextAttributesKey("codemp", HIGHLIGHTED), + document.getLineStartOffset(event.getStartRow()) + event.getStartCol(), + document.getLineStartOffset(event.getEndRow()) + event.getEndCol(), + HighlighterLayer.SELECTION, + HighlighterTargetArea.EXACT_RANGE + )); + } catch(Exception ex) { + throw new RuntimeException(); + } + }); + } catch(Exception ex) { + throw new RuntimeException(ex); + } + } + } + }); + + } catch(Exception ex) { + Messages.showErrorDialog(String.format( + "Failed to join session %s: %s!", + session, + ex.getMessage()), + "CodeMP Join"); + } + } +} diff --git a/src/main/java/com/codemp/intellij/listeners/CursorEventListener.java b/src/main/java/com/codemp/intellij/listeners/CursorEventListener.java new file mode 100644 index 0000000..8a6260f --- /dev/null +++ b/src/main/java/com/codemp/intellij/listeners/CursorEventListener.java @@ -0,0 +1,31 @@ +package com.codemp.intellij.listeners; + +import com.codemp.intellij.jni.CodeMPHandler; +import com.intellij.openapi.editor.Caret; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.VisualPosition; +import com.intellij.openapi.editor.event.CaretEvent; +import com.intellij.openapi.editor.event.CaretListener; +import org.jetbrains.annotations.NotNull; + +public class CursorEventListener implements CaretListener { + @Override + public void caretPositionChanged(@NotNull CaretEvent event) { + System.out.println("called!"); + Caret caret = event.getCaret(); + if(caret == null) + return; + System.out.println("valid caret!"); + + try { + VisualPosition startPos = caret.getSelectionStartPosition(); + VisualPosition endPos = caret.getSelectionEndPosition(); + System.out.printf("start %dx %dy end %dx %dy", startPos.line, startPos.column, endPos.line, endPos.column); + CodeMPHandler.getCursor().send( + "", startPos.line, startPos.column, endPos.line, endPos.column + ); + } catch(Exception ex) { + throw new RuntimeException(ex); + } + } +} diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 52af888..6d9d430 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -23,14 +23,17 @@ com.intellij.modules.platform - + - + + + + - \ No newline at end of file +