diff --git a/build.gradle b/build.gradle index 1432dfa..739bb9e 100644 --- a/build.gradle +++ b/build.gradle @@ -21,7 +21,7 @@ repositories { dependencies { implementation variantOf(libs.codemp) { - classifier osdetector.classifier + classifier 'all' } compileOnly libs.lombok diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index cf4ddcc..b65689f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -codemp = '0.7.3' +codemp = '0.8.0' lombok = '1.18.34' intellij-plugin = '2.0.1' git-version = '3.1.0' diff --git a/src/main/java/mp/code/intellij/CodeMP.java b/src/main/java/mp/code/intellij/CodeMP.java index cdb5197..f178bbb 100644 --- a/src/main/java/mp/code/intellij/CodeMP.java +++ b/src/main/java/mp/code/intellij/CodeMP.java @@ -52,8 +52,8 @@ public class CodeMP { .orElseThrow(IllegalStateException::new); } - public static void joinWorkspace(String workspaceId) throws ConnectionException { - CodeMP.getClient("join workspace").joinWorkspace(workspaceId); + public static void attachWorkspace(String workspaceId) throws ConnectionException { + CodeMP.getClient("attach workspace").attachWorkspace(workspaceId); ACTIVE_WORKSPACE_ID = workspaceId; } diff --git a/src/main/java/mp/code/intellij/actions/buffer/BufferAttachAction.java b/src/main/java/mp/code/intellij/actions/buffer/BufferAttachAction.java index 33878d9..56bb0b3 100644 --- a/src/main/java/mp/code/intellij/actions/buffer/BufferAttachAction.java +++ b/src/main/java/mp/code/intellij/actions/buffer/BufferAttachAction.java @@ -12,7 +12,6 @@ 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; @@ -20,16 +19,14 @@ 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); + String[] filetree = CodeMP.getActiveWorkspace().searchBuffers(Optional.empty()); int choice = Messages.showChooseDialog( "Attach to which buffer?", "CodeMP Buffer Attach", @@ -38,7 +35,6 @@ public class BufferAttachAction extends AnAction { Messages.getQuestionIcon() ); - // TODO check out of bounds but should be guaranteed by intellij String path = filetree[choice]; Editor editor = FileUtil.getActiveEditorByPath(proj, path); diff --git a/src/main/java/mp/code/intellij/actions/workspace/WorkspaceJoinAction.java b/src/main/java/mp/code/intellij/actions/workspace/WorkspaceAttachAction.java similarity index 76% rename from src/main/java/mp/code/intellij/actions/workspace/WorkspaceJoinAction.java rename to src/main/java/mp/code/intellij/actions/workspace/WorkspaceAttachAction.java index ebe45b6..9407d9a 100644 --- a/src/main/java/mp/code/intellij/actions/workspace/WorkspaceJoinAction.java +++ b/src/main/java/mp/code/intellij/actions/workspace/WorkspaceAttachAction.java @@ -8,28 +8,27 @@ import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.ui.Messages; import org.jetbrains.annotations.NotNull; -public class WorkspaceJoinAction extends AnAction { +public class WorkspaceAttachAction extends AnAction { @Override public void actionPerformed(@NotNull AnActionEvent e) { String[] availableWorkspaces = InteractionUtil.listWorkspaces(e.getProject(), true, true); if(availableWorkspaces.length == 0) { Messages.showErrorDialog( "There are no available workspaces. Ensure you have rights to access at least one!", - "CodeMP Join Workspace" + "CodeMP Attach To Workspace" ); return; } - int choice = Messages.showDialog( // TODO NOT THE ONE - e.getProject(), - "Please choose a workspace to join:", - "CodeMP Join Workspace", + int choice = Messages.showChooseDialog( + "Please choose a workspace to attach to:", + "CodeMP Attach Workspace", availableWorkspaces, - 0, + "", Messages.getQuestionIcon() ); - InteractionUtil.joinWorkspace(e.getProject(), availableWorkspaces[choice], null); + InteractionUtil.attachWorkspace(e.getProject(), availableWorkspaces[choice], null); } @Override 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 d54fac9..9c0e202 100644 --- a/src/main/java/mp/code/intellij/actions/workspace/WorkspaceDeleteAction.java +++ b/src/main/java/mp/code/intellij/actions/workspace/WorkspaceDeleteAction.java @@ -21,12 +21,11 @@ public class WorkspaceDeleteAction extends AnAction { return; } - int choice = Messages.showDialog( // TODO NOT THE ONE - e.getProject(), + int choice = Messages.showChooseDialog( "Please choose a workspace to delete:", "CodeMP Delete Workspace", availableWorkspaces, - 0, + "", Messages.getQuestionIcon() ); 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 fa4029f..f4f9c3c 100644 --- a/src/main/java/mp/code/intellij/actions/workspace/WorkspaceInviteAction.java +++ b/src/main/java/mp/code/intellij/actions/workspace/WorkspaceInviteAction.java @@ -8,9 +8,6 @@ import mp.code.intellij.CodeMP; import mp.code.intellij.util.InteractionUtil; import org.jetbrains.annotations.NotNull; -import java.util.Arrays; -import java.util.List; - public class WorkspaceInviteAction extends AnAction { @Override public void actionPerformed(@NotNull AnActionEvent e) { @@ -23,12 +20,11 @@ public class WorkspaceInviteAction extends AnAction { return; } - int choice = Messages.showDialog( // TODO NOT THE ONE - e.getProject(), + int choice = Messages.showChooseDialog( "Please choose a workspace to invite to:", "CodeMP Invite To Workspace", availableWorkspaces, - 0, + "", Messages.getQuestionIcon() ); diff --git a/src/main/java/mp/code/intellij/actions/workspace/WorkspaceLeaveAction.java b/src/main/java/mp/code/intellij/actions/workspace/WorkspaceLeaveAction.java index c99ed09..14aa693 100644 --- a/src/main/java/mp/code/intellij/actions/workspace/WorkspaceLeaveAction.java +++ b/src/main/java/mp/code/intellij/actions/workspace/WorkspaceLeaveAction.java @@ -12,7 +12,7 @@ import java.util.Objects; public class WorkspaceLeaveAction extends AnAction { @Override public void actionPerformed(@NotNull AnActionEvent e) { - String workspaceId = CodeMP.getActiveWorkspace().getWorkspaceId(); + String workspaceId = CodeMP.getActiveWorkspace().id(); InteractionUtil.leaveWorkspace(Objects.requireNonNull(e.getProject()), workspaceId, null); } diff --git a/src/main/java/mp/code/intellij/exceptions/ide/BadActionEventStateException.java b/src/main/java/mp/code/intellij/exceptions/ide/BadActionEventStateException.java deleted file mode 100644 index ebeaa08..0000000 --- a/src/main/java/mp/code/intellij/exceptions/ide/BadActionEventStateException.java +++ /dev/null @@ -1,13 +0,0 @@ -package mp.code.intellij.exceptions.ide; - -import mp.code.intellij.exceptions.CodeMPIJException; - -/** - * Fired when trying to use {@link com.intellij.openapi.actionSystem.AnActionEvent}'s context - * from a state where that use is not supported. - */ -public class BadActionEventStateException extends CodeMPIJException { - public BadActionEventStateException(String s) { - super(s); - } -} diff --git a/src/main/java/mp/code/intellij/exceptions/ide/BufferDetachException.java b/src/main/java/mp/code/intellij/exceptions/ide/BufferDetachException.java deleted file mode 100644 index 564f3d0..0000000 --- a/src/main/java/mp/code/intellij/exceptions/ide/BufferDetachException.java +++ /dev/null @@ -1,13 +0,0 @@ -package mp.code.intellij.exceptions.ide; - -import mp.code.intellij.exceptions.CodeMPIJException; - -/** - * Thrown upon failure to detach from a buffer. - */ -public class BufferDetachException extends CodeMPIJException { - - public BufferDetachException(String name) { - super(String.format("Could not detach from buffer named \"%s\"!", name)); - } -} diff --git a/src/main/java/mp/code/intellij/listeners/BufferEventListener.java b/src/main/java/mp/code/intellij/listeners/BufferEventListener.java index d5732e3..35b8e10 100644 --- a/src/main/java/mp/code/intellij/listeners/BufferEventListener.java +++ b/src/main/java/mp/code/intellij/listeners/BufferEventListener.java @@ -14,7 +14,6 @@ import org.jetbrains.annotations.NotNull; import java.util.Objects; import java.util.Optional; -import java.util.OptionalLong; public class BufferEventListener implements DocumentListener { @@ -51,8 +50,7 @@ public class BufferEventListener implements DocumentListener { controller.send(new TextChange( changeOffset, changeOffset + event.getOldFragment().length(), - newFragment.toString(), - OptionalLong.empty() + newFragment.toString() )); } catch(ControllerException e) { throw new RuntimeException(e); diff --git a/src/main/java/mp/code/intellij/listeners/CursorEventListener.java b/src/main/java/mp/code/intellij/listeners/CursorEventListener.java index 330b2bc..3c9f0e2 100644 --- a/src/main/java/mp/code/intellij/listeners/CursorEventListener.java +++ b/src/main/java/mp/code/intellij/listeners/CursorEventListener.java @@ -3,6 +3,7 @@ package mp.code.intellij.listeners; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.LogicalPosition; import com.intellij.openapi.vfs.VirtualFile; +import mp.code.data.Selection; import mp.code.exceptions.ControllerException; import mp.code.intellij.CodeMP; import mp.code.intellij.util.FileUtil; @@ -10,7 +11,6 @@ import com.intellij.openapi.editor.Caret; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.event.CaretEvent; import com.intellij.openapi.editor.event.CaretListener; -import mp.code.data.Cursor; import org.jetbrains.annotations.NotNull; @@ -21,7 +21,7 @@ public class CursorEventListener implements CaretListener { @Override public void caretPositionChanged(@NotNull CaretEvent event) { - // TODO instead of returning, should un-set remote ursor position (once) + // TODO instead of returning, should un-set remote cursor position (once) Caret caret = event.getCaret(); if(caret == null) return; @@ -68,13 +68,12 @@ public class CursorEventListener implements CaretListener { new Thread(() -> ApplicationManager.getApplication().runReadAction(() -> { try { - CodeMP.getActiveWorkspace().getCursor().send(new Cursor( + CodeMP.getActiveWorkspace().cursor().send(new Selection( startPos.line, startPos.column, endPos.line, endPos.column, - FileUtil.getRelativePath(editor.getProject(), editor.getVirtualFile()), - null + FileUtil.getRelativePath(editor.getProject(), editor.getVirtualFile()) )); } catch(ControllerException e) { throw new RuntimeException(e); @@ -87,11 +86,11 @@ public class CursorEventListener implements CaretListener { new Thread(() -> ApplicationManager.getApplication().runReadAction(() -> { try { CodeMP.getActiveWorkspace() - .getCursor() - .send(new Cursor(0, 0, 0, 0, "", null)); + .cursor() + .send(new Selection(0, 0, 0, 0, "")); } catch(ControllerException e) { throw new RuntimeException(e); } })).start(); } -} \ No newline at end of file +} diff --git a/src/main/java/mp/code/intellij/ui/CodeMPToolPanel.java b/src/main/java/mp/code/intellij/ui/CodeMPToolPanel.java index 313db7c..d2c04cb 100644 --- a/src/main/java/mp/code/intellij/ui/CodeMPToolPanel.java +++ b/src/main/java/mp/code/intellij/ui/CodeMPToolPanel.java @@ -25,10 +25,8 @@ import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.MouseEvent; import java.io.IOException; -import java.util.Arrays; import java.util.Objects; import java.util.Optional; -import java.util.OptionalLong; public class CodeMPToolPanel extends JPanel { public CodeMPToolPanel(Project project) { @@ -62,7 +60,7 @@ public class CodeMPToolPanel extends JPanel { TreePath path = tree.getPathForLocation(e.getX(), e.getY()); if(path == null) return; String workspaceName = path.getLastPathComponent().toString(); - InteractionUtil.joinWorkspace( + InteractionUtil.attachWorkspace( project, workspaceName, () -> CodeMPToolPanel.this.redraw(project) @@ -111,8 +109,7 @@ public class CodeMPToolPanel extends JPanel { controller.get().send(new TextChange( 0, 0, - ed.getDocument().getText(), - OptionalLong.empty() + ed.getDocument().getText() )); ApplicationManager.getApplication().runWriteAction(() -> { try { @@ -129,7 +126,7 @@ public class CodeMPToolPanel extends JPanel { }), BorderLayout.NORTH); Workspace ws = CodeMP.getActiveWorkspace(); - JTree tree = drawTree(ws.getWorkspaceId(), ws.getFileTree(Optional.empty(), false)); + JTree tree = drawTree(ws.id(), ws.searchBuffers(Optional.empty())); tree.addMouseListener(new SimpleMouseListener() { @Override public void mouseClicked(MouseEvent e) { @@ -158,7 +155,7 @@ public class CodeMPToolPanel extends JPanel { this.add(tree, BorderLayout.CENTER); - JList userlist = new JBList<>(ws.userList()); + JList userlist = new JBList<>(CodeMP.HIGHLIGHTER_MAP.keySet()); // TODO shouldn't use this this.add(userlist, BorderLayout.SOUTH); } } diff --git a/src/main/java/mp/code/intellij/util/FileUtil.java b/src/main/java/mp/code/intellij/util/FileUtil.java index e36ea52..7b391ad 100644 --- a/src/main/java/mp/code/intellij/util/FileUtil.java +++ b/src/main/java/mp/code/intellij/util/FileUtil.java @@ -75,12 +75,12 @@ public class FileUtil { return CodeMP.getClient("buffer access") .getWorkspace(path.getWorkspaceName()) .flatMap(ws -> { - String[] matches = ws.getFileTree(Optional.of(path.getRealPath()), true); + String[] matches = ws.searchBuffers(Optional.of(path.getRealPath())); if(matches.length == 0) return Optional.empty(); Optional controller = ws.getBuffer(path.getRealPath()); if(controller.isPresent()) return controller; try { - return Optional.of(ws.attachToBuffer(path.getRealPath())); + return Optional.of(ws.attachBuffer(path.getRealPath())); } catch(ConnectionException e) { return Optional.empty(); } diff --git a/src/main/java/mp/code/intellij/util/InteractionUtil.java b/src/main/java/mp/code/intellij/util/InteractionUtil.java index f4148f2..883f69e 100644 --- a/src/main/java/mp/code/intellij/util/InteractionUtil.java +++ b/src/main/java/mp/code/intellij/util/InteractionUtil.java @@ -25,6 +25,8 @@ import mp.code.intellij.listeners.CursorEventListener; import mp.code.intellij.settings.CodeMPSettings; import mp.code.intellij.ui.CodeMPToolPanel; import mp.code.intellij.util.cb.CursorCallback; +import mp.code.intellij.util.cb.WorkspaceCallback; +import org.apache.commons.lang3.ArrayUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -121,17 +123,17 @@ public class InteractionUtil { }); } - public static void joinWorkspace(@NotNull Project project, @NotNull String workspaceId, @Nullable Runnable after) { + public static void attachWorkspace(@NotNull Project project, @NotNull String workspaceId, @Nullable Runnable after) { ProgressManager.getInstance().run(new Task.Backgroundable(project, String.format("Joining workspace %s...", workspaceId)) { @Override public void run(@NotNull ProgressIndicator indicator) { try { - CodeMP.joinWorkspace(workspaceId); + CodeMP.attachWorkspace(workspaceId); MemoryManager.startWorkspaceLifetime(workspaceId); refreshToolWindow(project); } catch(ConnectionException e) { InteractionUtil.notifyError(project, String.format( - "Failed to join workspace %s!", + "Failed to attach to workspace %s!", workspaceId ), e); return; @@ -145,10 +147,14 @@ public class InteractionUtil { eventMulticaster.addDocumentListener(new BufferEventListener(), lifetime); eventMulticaster.addCaretListener(new CursorEventListener(), lifetime); - CodeMP.getActiveWorkspace().getCursor().callback(controller -> { + CodeMP.getActiveWorkspace().cursor().callback(controller -> { new CursorCallback(this.myProject).accept(controller); }); + CodeMP.getActiveWorkspace().callback(receiver -> { + new WorkspaceCallback(this.myProject).accept(receiver); + }); + if(after != null) after.run(); notifyInfo( @@ -169,7 +175,7 @@ public class InteractionUtil { client.deleteWorkspace(workspaceId); Optional ws = client.getWorkspace("workspace leave"); - if(ws.isPresent() && ws.get().getWorkspaceId().equals(workspaceId)) { + if(ws.isPresent() && ws.get().id().equals(workspaceId)) { CodeMP.leaveWorkspace(); MemoryManager.endWorkspaceLifetime(workspaceId); } @@ -181,11 +187,11 @@ public class InteractionUtil { notifyInfo( project, "Success", - String.format("Joined workspace %s!", workspaceId) + String.format("Deleted workspace %s!", workspaceId) ); } catch(ConnectionException e) { InteractionUtil.notifyError(project, String.format( - "Failed to join workspace %s!", + "Failed to delete workspace %s!", workspaceId ), e); } @@ -210,10 +216,19 @@ public class InteractionUtil { }); } - public static String[] listWorkspaces(Project project, boolean owned, boolean invited) { + public static String[] listWorkspaces(Project project, boolean owned, boolean joined) { try { Client client = CodeMP.getClient("drawActiveWorkspaces"); - return client.listWorkspaces(owned, invited); + + String[] ownedWorkspaces; + if(owned) ownedWorkspaces = client.fetchOwnedWorkspaces(); + else ownedWorkspaces = new String[0]; + + String[] joinedWorkspaces; + if(joined) joinedWorkspaces = client.fetchJoinedWorkspaces(); + else joinedWorkspaces = new String[0]; + + return ArrayUtils.addAll(ownedWorkspaces, joinedWorkspaces); } catch(ConnectionRemoteException exception) { notifyError(project, "Failed to list workspaces!", exception); return new String[0]; @@ -222,12 +237,12 @@ public class InteractionUtil { public static Optional bufferAttach(Project project, Workspace workspace, String path) { try { - BufferController controller = workspace.attachToBuffer(path); - MemoryManager.startBufferLifetime(workspace.getWorkspaceId(), path); + BufferController controller = workspace.attachBuffer(path); + MemoryManager.startBufferLifetime(workspace.id(), path); notifyInfo(project, "Success!", String.format( "Successfully attached to buffer %s on workspace %s!", path, - workspace.getWorkspaceId()) + workspace.id()) ); return Optional.of(controller); } catch(ConnectionException e) { diff --git a/src/main/java/mp/code/intellij/util/cb/BufferCallback.java b/src/main/java/mp/code/intellij/util/cb/BufferCallback.java index ee6d569..6efcc92 100644 --- a/src/main/java/mp/code/intellij/util/cb/BufferCallback.java +++ b/src/main/java/mp/code/intellij/util/cb/BufferCallback.java @@ -7,7 +7,7 @@ import com.intellij.openapi.project.Project; import lombok.RequiredArgsConstructor; import mp.code.BufferController; import mp.code.Extensions; -import mp.code.data.TextChange; +import mp.code.data.BufferUpdate; import mp.code.exceptions.ControllerException; import mp.code.intellij.CodeMP; import mp.code.intellij.util.FileUtil; @@ -30,35 +30,40 @@ public class BufferCallback implements Consumer { ApplicationManager.getApplication().runReadAction(() -> { Editor editor = FileUtil.getActiveEditorByPath(this.project, bufferController.getName()); ApplicationManager.getApplication().invokeLaterOnWriteThread(() -> { - List changeList = new ArrayList<>(); + List updateList = new ArrayList<>(); while(true) { - Optional changeOptional; + Optional updateOptional; try { - changeOptional = bufferController.tryRecv(); + updateOptional = bufferController.tryRecv(); } catch(ControllerException ex) { throw new RuntimeException(ex); } - if(changeOptional.isEmpty()) + if(updateOptional.isEmpty()) break; - TextChange change = changeOptional.get(); + BufferUpdate update = updateOptional.get(); CodeMP.LOGGER.debug(String.format( "Received text change %s from offset %d to %d!", - change.content, - change.start, - change.end + update.change.content, + update.change.startIdx, + update.change.endIdx )); - changeList.add(change); + updateList.add(update); } ApplicationManager.getApplication().runWriteAction(() -> { CommandProcessor.getInstance().executeCommand( this.project, - () -> changeList.forEach((change) -> { - editor.getDocument().replaceString((int) change.start, (int) change.end, change.content); + () -> updateList.forEach((update) -> { + editor.getDocument().replaceString( + (int) update.change.startIdx, + (int) update.change.endIdx, + update.change.content + ); + bufferController.ack(update.version); // check for validity, force-sync if mismatch // TODO: prompt instead of doing it silently - if(change.hash.isPresent() && change.hash.getAsLong() != Extensions.hash(editor.getDocument().getText())) { + if(update.hash.isPresent() && update.hash.getAsLong() != Extensions.hash(editor.getDocument().getText())) { try { editor.getDocument().setText(bufferController.getContent()); } catch(ControllerException ignored) {} // ignore exception diff --git a/src/main/java/mp/code/intellij/util/cb/CursorCallback.java b/src/main/java/mp/code/intellij/util/cb/CursorCallback.java index 05d2b52..14ca54a 100644 --- a/src/main/java/mp/code/intellij/util/cb/CursorCallback.java +++ b/src/main/java/mp/code/intellij/util/cb/CursorCallback.java @@ -39,24 +39,24 @@ public class CursorCallback implements Consumer { CodeMP.LOGGER.debug(String.format( "Cursor moved by user %s! Start pos: %dx %dy; end pos: %dx %dy in buffer %s!", event.user, - event.startCol, - event.startRow, - event.endCol, - event.endRow, - event.buffer + event.selection.startCol, + event.selection.startRow, + event.selection.endCol, + event.selection.endRow, + event.selection.buffer )); try { ApplicationManager.getApplication().runReadAction(() -> { - Editor editor = FileUtil.getActiveEditorByPath(this.project, event.buffer); + Editor editor = FileUtil.getActiveEditorByPath(this.project, event.selection.buffer); if(editor == null) { RangeHighlighter previous = CodeMP.HIGHLIGHTER_MAP.remove(event.user); if(previous != null) previous.dispose(); return; } - int startOffset = editor.getDocument().getLineStartOffset(event.startRow) + event.startCol; - int endOffset = editor.getDocument().getLineStartOffset(event.endRow) + event.endCol; + int startOffset = editor.getDocument().getLineStartOffset(event.selection.startRow) + event.selection.startCol; + int endOffset = editor.getDocument().getLineStartOffset(event.selection.endRow) + event.selection.endCol; int documentLength = editor.getDocument().getTextLength(); if(startOffset > documentLength || endOffset > documentLength) { diff --git a/src/main/java/mp/code/intellij/util/cb/WorkspaceCallback.java b/src/main/java/mp/code/intellij/util/cb/WorkspaceCallback.java new file mode 100644 index 0000000..966e2ca --- /dev/null +++ b/src/main/java/mp/code/intellij/util/cb/WorkspaceCallback.java @@ -0,0 +1,46 @@ +package mp.code.intellij.util.cb; + +import com.intellij.openapi.editor.markup.RangeHighlighter; +import com.intellij.openapi.project.Project; +import lombok.RequiredArgsConstructor; +import mp.code.Workspace; +import mp.code.exceptions.ControllerException; +import mp.code.intellij.CodeMP; +import mp.code.intellij.util.InteractionUtil; + +import java.util.Optional; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.function.Consumer; + +@RequiredArgsConstructor +@SuppressWarnings("OptionalGetWithoutIsPresent") +public class WorkspaceCallback implements Consumer { + private static final Executor WORKSPACE_EXECUTOR = Executors.newSingleThreadExecutor(); + private final Project project; + + @Override + public void accept(Workspace workspace) { + WORKSPACE_EXECUTOR.execute(() -> { + try { + while(true) { + Optional possibleEvent = workspace.tryRecv(); + if(possibleEvent.isEmpty()) return; + Workspace.Event event = possibleEvent.get(); + + switch(event.getType()) { + case USER_JOIN, FILE_TREE_UPDATED -> {} + case USER_LEAVE -> { + RangeHighlighter prev = CodeMP.HIGHLIGHTER_MAP.remove(event.getUserLeft().get()); + if(prev != null) prev.dispose(); + InteractionUtil.refreshToolWindow(this.project); + } + } + InteractionUtil.refreshToolWindow(this.project); + } + } catch(ControllerException ex) { + InteractionUtil.notifyError(project, "Error receiving event", ex); + } + }); + } +} diff --git a/src/main/java/mp/code/intellij/vfs/CodeMPDirectory.java b/src/main/java/mp/code/intellij/vfs/CodeMPDirectory.java index aa96b83..fbe0a61 100644 --- a/src/main/java/mp/code/intellij/vfs/CodeMPDirectory.java +++ b/src/main/java/mp/code/intellij/vfs/CodeMPDirectory.java @@ -38,7 +38,7 @@ public class CodeMPDirectory extends CodeMPFile { return CodeMP.getClient("get folder children") .getWorkspace(this.path.getWorkspaceName()) .map(ws -> - Arrays.stream(ws.getFileTree(Optional.of(this.path.getRealPath()), false)) + Arrays.stream(ws.searchBuffers(Optional.of(this.path.getRealPath()))) .map(p -> new CodeMPPath(this.path.getWorkspaceName(), p)) .map(CodeMPPath::join) .map(this.fileSystem::findFileByPath) diff --git a/src/main/java/mp/code/intellij/vfs/CodeMPFile.java b/src/main/java/mp/code/intellij/vfs/CodeMPFile.java index 4694975..74befcd 100644 --- a/src/main/java/mp/code/intellij/vfs/CodeMPFile.java +++ b/src/main/java/mp/code/intellij/vfs/CodeMPFile.java @@ -51,11 +51,15 @@ public class CodeMPFile extends VirtualFile { @Override public boolean isValid() { + return false; + /* TODO return CodeMP.getClient("validity check") .getWorkspace(this.path.getWorkspaceName()) + .map(ws -> ws.getBuffer(this.path.getRealPath()).isPresent()) .map(ws -> ws.getFileTree(Optional.of(this.path.getRealPath()), true)) .map(buf -> buf.length != 0) .orElse(false); + */ } @Override diff --git a/src/main/java/mp/code/intellij/vfs/CodeMPFileSystem.java b/src/main/java/mp/code/intellij/vfs/CodeMPFileSystem.java index 09debf8..1ce184e 100644 --- a/src/main/java/mp/code/intellij/vfs/CodeMPFileSystem.java +++ b/src/main/java/mp/code/intellij/vfs/CodeMPFileSystem.java @@ -68,10 +68,14 @@ public class CodeMPFileSystem extends VirtualFileSystem { // implements NonPhysi } private CodeMPFile fileOrFolderByPath(CodeMPPath cmpPath) { + return null; + /* TODO return CodeMP.getClient("file seek") .getWorkspace(cmpPath.getWorkspaceName()) .filter(ws -> ws.getFileTree(Optional.ofNullable(cmpPath.getRealPath()), true).length != 0).map(ws -> new CodeMPFile(this, cmpPath)) .orElseGet(() -> new CodeMPDirectory(this, cmpPath)); + + */ } @@ -132,7 +136,7 @@ public class CodeMPFileSystem extends VirtualFileSystem { // implements NonPhysi if(ws.isPresent()) { CodeMPPath newFilePath = parent.path.resolve(fileName); ws.get().createBuffer(newFilePath.getRealPath()); - ws.get().attachToBuffer(newFilePath.getRealPath()); + ws.get().attachBuffer(newFilePath.getRealPath()); return new CodeMPFile(this, newFilePath); } else { throw new IOException("failed to find workspace!"); // TODO do it better @@ -170,7 +174,7 @@ public class CodeMPFileSystem extends VirtualFileSystem { // implements NonPhysi .orElseThrow(() -> new IOException("Non existing buffer for old file!")); BufferController destinationController = FileUtil.getRelevantBufferController(cfile.path) .orElseThrow(() -> new IOException("Non existing buffer for new file!")); - destinationController.send(new TextChange(0, 0, oldController.getContent(), OptionalLong.empty())); + destinationController.send(new TextChange(0, 0, oldController.getContent())); return newFile; } catch(ControllerException ex) { throw new IOException(ex); diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index b0ad25f..f4042f2 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -1,7 +1,7 @@ mp.code.intellij CodeMP - CodeMP + CodeMP A plugin for MultiPlayer code editing across different IDEs. @@ -15,8 +15,8 @@ - + + - diff --git a/src/main/resources/META-INF/pluginIcon.svg b/src/main/resources/META-INF/pluginIcon.svg index b0179ec..fdaba1f 100644 --- a/src/main/resources/META-INF/pluginIcon.svg +++ b/src/main/resources/META-INF/pluginIcon.svg @@ -2,13 +2,13 @@ + inkscape:current-layer="layer2" /> + + + + transform="matrix(0.85361601,0,0,0.85361601,-26.16631,-11.14309)"> - + diff --git a/src/main/resources/icons/codempToolWindow.svg b/src/main/resources/icons/codempToolWindow.svg new file mode 100644 index 0000000..87a08c1 --- /dev/null +++ b/src/main/resources/icons/codempToolWindow.svg @@ -0,0 +1,61 @@ + + + + + + + + + + + + diff --git a/src/main/resources/icons/codempToolWindow2.svg b/src/main/resources/icons/codempToolWindow2.svg new file mode 100644 index 0000000..acba689 --- /dev/null +++ b/src/main/resources/icons/codempToolWindow2.svg @@ -0,0 +1,61 @@ + + + + + + + + + + + +