diff --git a/src/main/java/mp/code/intellij/actions/buffer/BufferAttachAction.java b/src/main/java/mp/code/intellij/actions/buffer/BufferAttachAction.java new file mode 100644 index 0000000..c915d85 --- /dev/null +++ b/src/main/java/mp/code/intellij/actions/buffer/BufferAttachAction.java @@ -0,0 +1,104 @@ +package mp.code.intellij.actions.buffer; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.TextEditor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import mp.code.BufferController; +import mp.code.data.TextChange; +import mp.code.exceptions.ControllerException; +import mp.code.intellij.CodeMP; +import mp.code.intellij.util.FileUtil; +import mp.code.intellij.util.InteractionUtil; +import mp.code.intellij.util.cb.BufferCallback; +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; +import java.util.Optional; +import java.util.OptionalLong; + +public class BufferAttachAction extends AnAction { + @Override + public void actionPerformed(@NotNull AnActionEvent e) { + Project proj = e.getProject(); + + String[] filetree = CodeMP.getActiveWorkspace().getFileTree(Optional.empty(), false); + int choice = Messages.showChooseDialog( + "Attach to which buffer?", + "CodeMP Buffer Attach", + filetree, + "", + Messages.getQuestionIcon() + ); + + // TODO check out of bounds but should be guaranteed by intellij + String path = filetree[choice]; + + Editor editor = FileUtil.getActiveEditorByPath(proj, path); + + if (editor == null) { + FileEditor currentEditor = FileEditorManager.getInstance(proj).getSelectedEditor(); + if(currentEditor == null) { + Messages.showErrorDialog( + "No file is currently open!", + "CodeMP Buffer Attach" + ); + return; + } + if (!(currentEditor instanceof TextEditor)) { + Messages.showErrorDialog( + "No text file is currently open!", + "CodeMP Buffer Attach" + ); + return; + } + editor = ((TextEditor) currentEditor).getEditor(); + } + + Optional controller = InteractionUtil.bufferAttach(proj, CodeMP.getActiveWorkspace(), path); + if(controller.isEmpty()) { + Messages.showErrorDialog( + "An unknown error has occurred!", + "CodeMP Buffer Attach" + ); + return; + } + + String remoteContent; + try { + remoteContent = controller.get().getContent(); + } catch (ControllerException ex) { + throw new RuntimeException(ex); + } + int localContentLen = editor.getDocument().getTextLength(); + + final Editor ed = editor; + ApplicationManager.getApplication().runWriteAction(() -> { + CommandProcessor.getInstance().executeCommand( + proj, + () -> ed.getDocument().replaceString(0, localContentLen, remoteContent), + "CodeMPBufferReceive", + "codemp-buffer-receive", + ed.getDocument() + ); + try { + + FileUtil.getAndRegisterBufferEquivalent(this, proj, controller.get()); + } catch(Exception ex) { + throw new RuntimeException(ex); + } + }); + controller.get().callback(buf -> new BufferCallback(proj).accept(buf)); + } + + @Override + public void update(@NotNull AnActionEvent e) { + e.getPresentation().setEnabled(CodeMP.isInWorkspace()); + } +} diff --git a/src/main/java/mp/code/intellij/actions/buffer/BufferCreateAction.java b/src/main/java/mp/code/intellij/actions/buffer/BufferCreateAction.java new file mode 100644 index 0000000..a79938e --- /dev/null +++ b/src/main/java/mp/code/intellij/actions/buffer/BufferCreateAction.java @@ -0,0 +1,30 @@ +package mp.code.intellij.actions.buffer; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.ui.Messages; +import mp.code.exceptions.ConnectionRemoteException; +import mp.code.intellij.CodeMP; +import org.jetbrains.annotations.NotNull; + +public class BufferCreateAction extends AnAction { + @Override + public void actionPerformed(@NotNull AnActionEvent e) { + String name = Messages.showInputDialog( + "Buffer path", + "CdeMP Buffer Create", + Messages.getQuestionIcon() + ); + try { + CodeMP.getActiveWorkspace().createBuffer(name); + Messages.showInfoMessage("Created buffer " + name, "CodeMP Buffer Create"); + } catch (ConnectionRemoteException ex) { + Messages.showErrorDialog("Error creating buffer: " + ex.toString(), "CodeMP Buffer Create"); + } + } + + @Override + public void update(@NotNull AnActionEvent e) { + e.getPresentation().setEnabled(CodeMP.isInWorkspace()); + } +} diff --git a/src/main/java/mp/code/intellij/actions/buffer/BufferDeleteAction.java b/src/main/java/mp/code/intellij/actions/buffer/BufferDeleteAction.java new file mode 100644 index 0000000..b2a90af --- /dev/null +++ b/src/main/java/mp/code/intellij/actions/buffer/BufferDeleteAction.java @@ -0,0 +1,30 @@ +package mp.code.intellij.actions.buffer; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.ui.Messages; +import mp.code.exceptions.ConnectionRemoteException; +import mp.code.intellij.CodeMP; +import org.jetbrains.annotations.NotNull; + +public class BufferDeleteAction extends AnAction { + @Override + public void actionPerformed(@NotNull AnActionEvent e) { + String name = Messages.showInputDialog( + "Buffer path", + "CdeMP Buffer Delete", + Messages.getQuestionIcon() + ); + try { + CodeMP.getActiveWorkspace().deleteBuffer(name); + Messages.showInfoMessage("Deleted buffer " + name, "CodeMP Buffer Create"); + } catch (ConnectionRemoteException ex) { + Messages.showErrorDialog("Error deleting buffer: " + ex.toString(), "CodeMP Buffer Create"); + } + } + + @Override + public void update(@NotNull AnActionEvent e) { + e.getPresentation().setEnabled(CodeMP.isInWorkspace()); + } +} diff --git a/src/main/java/mp/code/intellij/actions/buffer/BufferDetachAction.java b/src/main/java/mp/code/intellij/actions/buffer/BufferDetachAction.java new file mode 100644 index 0000000..16d9c6b --- /dev/null +++ b/src/main/java/mp/code/intellij/actions/buffer/BufferDetachAction.java @@ -0,0 +1,49 @@ +package mp.code.intellij.actions.buffer; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.ui.Messages; +import mp.code.BufferController; +import mp.code.intellij.CodeMP; +import org.jetbrains.annotations.NotNull; + +import java.nio.file.Path; +import java.util.Map; +import java.util.Optional; + +public class BufferDetachAction extends AnAction { + @Override + public void actionPerformed(@NotNull AnActionEvent e) { + String[] active_buffers = CodeMP.getActiveWorkspace().activeBuffers(); + int choice = Messages.showChooseDialog( + "Detach from which buffer?", + "CodeMP Buffer Detach", + active_buffers, + "", + Messages.getQuestionIcon() + ); + String path = active_buffers[choice]; + + Optional controller = CodeMP.getActiveWorkspace().getBuffer(path); + + if (controller.isEmpty()) { + Messages.showErrorDialog("No controller for buffer " + path, "CodeMP Buffer Detach"); + return; + } + + controller.get().clearCallback(); + for (Map.Entry entry : CodeMP.BUFFER_MAPPER.entrySet()) { + if (entry.getValue().equals(path)) { + CodeMP.BUFFER_MAPPER.remove(entry.getKey()); + break; + } + } + + Messages.showInfoMessage("Detached from buffer " + path, "CodeMP Buffer Detach"); + } + + @Override + public void update(@NotNull AnActionEvent e) { + e.getPresentation().setEnabled(CodeMP.isInWorkspace()); + } +} diff --git a/src/main/java/mp/code/intellij/actions/buffer/BufferShareAction.java b/src/main/java/mp/code/intellij/actions/buffer/BufferShareAction.java index 9242ca3..77ebc16 100644 --- a/src/main/java/mp/code/intellij/actions/buffer/BufferShareAction.java +++ b/src/main/java/mp/code/intellij/actions/buffer/BufferShareAction.java @@ -71,4 +71,9 @@ public class BufferShareAction extends AnAction { throw new RuntimeException(ex); } } + + @Override + public void update(@NotNull AnActionEvent e) { + e.getPresentation().setEnabled(CodeMP.isInWorkspace()); + } } diff --git a/src/main/java/mp/code/intellij/actions/buffer/BufferSyncAction.java b/src/main/java/mp/code/intellij/actions/buffer/BufferSyncAction.java new file mode 100644 index 0000000..432dc39 --- /dev/null +++ b/src/main/java/mp/code/intellij/actions/buffer/BufferSyncAction.java @@ -0,0 +1,70 @@ +package mp.code.intellij.actions.buffer; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.ui.Messages; +import mp.code.BufferController; +import mp.code.exceptions.ControllerException; +import mp.code.intellij.CodeMP; +import mp.code.intellij.util.FileUtil; + +import org.jetbrains.annotations.NotNull; + +import java.util.Optional; + +public class BufferSyncAction extends AnAction { + @Override + public void actionPerformed(@NotNull AnActionEvent e) { + // TODO if current buffer is managed, sync that instead of making user choose + + String[] active_buffers = CodeMP.getActiveWorkspace().activeBuffers(); + int choice = Messages.showChooseDialog( + "Detach from which buffer?", + "CodeMP Buffer Detach", + active_buffers, + "", + Messages.getQuestionIcon() + ); + String path = active_buffers[choice]; + + Optional controller = CodeMP.getActiveWorkspace().getBuffer(path); + if (controller.isEmpty()) { + Messages.showErrorDialog("No active controller for path " + path, "CodeMP Buffer Sync"); + return; + } + + Editor editor = FileUtil.getActiveEditorByPath(e.getProject(), path); + if (editor == null) { + Messages.showErrorDialog("No active buffer for path " + path, "CodeMP Buffer Sync"); + return; + } + + String remoteContent; + try { + remoteContent = controller.get().getContent(); + } catch (ControllerException ex) { + Messages.showErrorDialog("Controller failed returning path: " + path, "CodeMP Buffer Sync"); + return; + } + + ApplicationManager.getApplication().runWriteAction(() -> { + CommandProcessor.getInstance().executeCommand( + e.getProject(), + () -> editor.getDocument().replaceString(0, editor.getDocument().getTextLength(), remoteContent), + "CodeMPBufferReceive", + "codemp-buffer-receive", + editor.getDocument() + ); + }); + + Messages.showInfoMessage("Synched buffer " + path, "CodeMP Buffer Sync"); + } + + @Override + public void update(@NotNull AnActionEvent e) { + e.getPresentation().setEnabled(CodeMP.isInWorkspace()); + } +} diff --git a/src/main/java/mp/code/intellij/actions/workspace/WorkspaceCreateAction.java b/src/main/java/mp/code/intellij/actions/workspace/WorkspaceCreateAction.java index e51b0bb..8463d95 100644 --- a/src/main/java/mp/code/intellij/actions/workspace/WorkspaceCreateAction.java +++ b/src/main/java/mp/code/intellij/actions/workspace/WorkspaceCreateAction.java @@ -3,6 +3,8 @@ package mp.code.intellij.actions.workspace; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.ui.Messages; + +import mp.code.intellij.CodeMP; import mp.code.intellij.util.InteractionUtil; import org.jetbrains.annotations.NotNull; @@ -25,4 +27,9 @@ public class WorkspaceCreateAction extends AnAction { InteractionUtil.createWorkspace(e.getProject(), workspaceName, null); } + + @Override + public void update(@NotNull AnActionEvent e) { + e.getPresentation().setEnabled(CodeMP.isConnected()); + } } diff --git a/src/main/java/mp/code/intellij/actions/workspace/WorkspaceDeleteAction.java b/src/main/java/mp/code/intellij/actions/workspace/WorkspaceDeleteAction.java index ebd508d..3de5f0d 100644 --- a/src/main/java/mp/code/intellij/actions/workspace/WorkspaceDeleteAction.java +++ b/src/main/java/mp/code/intellij/actions/workspace/WorkspaceDeleteAction.java @@ -3,6 +3,8 @@ package mp.code.intellij.actions.workspace; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.ui.Messages; + +import mp.code.intellij.CodeMP; import mp.code.intellij.util.InteractionUtil; import org.jetbrains.annotations.NotNull; @@ -29,4 +31,9 @@ public class WorkspaceDeleteAction extends AnAction { InteractionUtil.deleteWorkspace(e.getProject(), availableWorkspaces[choice], null); } + + @Override + public void update(@NotNull AnActionEvent e) { + e.getPresentation().setEnabled(CodeMP.isConnected()); + } } diff --git a/src/main/java/mp/code/intellij/actions/workspace/WorkspaceInviteAction.java b/src/main/java/mp/code/intellij/actions/workspace/WorkspaceInviteAction.java index e58615b..60a180b 100644 --- a/src/main/java/mp/code/intellij/actions/workspace/WorkspaceInviteAction.java +++ b/src/main/java/mp/code/intellij/actions/workspace/WorkspaceInviteAction.java @@ -47,4 +47,9 @@ public class WorkspaceInviteAction extends AnAction { InteractionUtil.inviteToWorkspace(e.getProject(), availableWorkspaces[choice], userName, null); } + + @Override + public void update(@NotNull AnActionEvent e) { + e.getPresentation().setEnabled(CodeMP.isConnected()); + } } diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index b8a0d2e..95c9993 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -30,6 +30,16 @@ + + + + +