1
0
mirror of https://github.com/chylex/IntelliJ-IdeaVim.git synced 2025-04-16 11:15:41 +02:00
IntelliJ-IdeaVim/src/main/java/com/maddyhome/idea/vim/group/WindowGroup.java
2022-11-01 20:00:07 +02:00

185 lines
7.5 KiB
Java

/*
* Copyright 2022 The IdeaVim authors
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE.txt file or at
* https://opensource.org/licenses/MIT.
*/
package com.maddyhome.idea.vim.group;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx;
import com.intellij.openapi.fileEditor.impl.EditorComposite;
import com.intellij.openapi.fileEditor.impl.EditorWindow;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.concurrency.annotations.RequiresReadLock;
import com.maddyhome.idea.vim.VimPlugin;
import com.maddyhome.idea.vim.api.ExecutionContext;
import com.maddyhome.idea.vim.helper.MessageHelper;
import com.maddyhome.idea.vim.helper.RWLockLabel;
import com.maddyhome.idea.vim.newapi.IjExecutionContext;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.util.List;
import java.util.*;
public class WindowGroup extends WindowGroupBase {
@Override
public void closeCurrentWindow(@NotNull ExecutionContext context) {
final FileEditorManagerEx fileEditorManager = getFileEditorManager((DataContext)context.getContext());
final EditorWindow window = fileEditorManager.getSplitters().getCurrentWindow();
if (window != null) {
window.closeAllExcept(null);
}
}
@Override
public void closeAllExceptCurrent(@NotNull ExecutionContext context) {
final FileEditorManagerEx fileEditorManager = getFileEditorManager(((DataContext)context.getContext()));
final EditorWindow current = fileEditorManager.getCurrentWindow();
for (final EditorWindow window : fileEditorManager.getWindows()) {
if (window != current) {
window.closeAllExcept(null);
}
}
}
public void closeAllExceptCurrentTab(@NotNull DataContext context) {
final EditorWindow currentWindow = getFileEditorManager(context).getCurrentWindow();
currentWindow.closeAllExcept(currentWindow.getSelectedFile());
}
public void closeAll(@NotNull ExecutionContext context) {
getFileEditorManager(((IjExecutionContext) context).getContext()).closeAllFiles();
}
@Override
public void selectNextWindow(@NotNull ExecutionContext context) {
final FileEditorManagerEx fileEditorManager = getFileEditorManager(((DataContext)context.getContext()));
final EditorWindow current = fileEditorManager.getCurrentWindow();
if (current != null) {
fileEditorManager.getNextWindow(current).setAsCurrentWindow(true);
}
}
@Override
public void selectPreviousWindow(@NotNull ExecutionContext context) {
final FileEditorManagerEx fileEditorManager = getFileEditorManager(((DataContext)context.getContext()));
final EditorWindow current = fileEditorManager.getCurrentWindow();
if (current != null) {
fileEditorManager.getPrevWindow(current).setAsCurrentWindow(true);
}
}
@Override
public void selectWindow(@NotNull ExecutionContext context, int index) {
final FileEditorManagerEx fileEditorManager = getFileEditorManager(((DataContext)context.getContext()));
final EditorWindow[] windows = fileEditorManager.getWindows();
if (index - 1 < windows.length) {
windows[index - 1].setAsCurrentWindow(true);
}
}
@Override
public void splitWindowHorizontal(@NotNull ExecutionContext context, @NotNull String filename) {
splitWindow(SwingConstants.HORIZONTAL, (DataContext)context.getContext(), filename);
}
@Override
public void splitWindowVertical(@NotNull ExecutionContext context, @NotNull String filename) {
splitWindow(SwingConstants.VERTICAL, (DataContext)context.getContext(), filename);
}
@Override
@RWLockLabel.Readonly
@RequiresReadLock
public void selectWindowInRow(@NotNull ExecutionContext context, int relativePosition, boolean vertical) {
final FileEditorManagerEx fileEditorManager = getFileEditorManager(((DataContext)context.getContext()));
final EditorWindow currentWindow = fileEditorManager.getCurrentWindow();
if (currentWindow != null) {
final EditorWindow[] windows = fileEditorManager.getWindows();
final List<EditorWindow> row = findWindowsInRow(currentWindow, Arrays.asList(windows), vertical);
selectWindow(currentWindow, row, relativePosition);
}
}
private void selectWindow(@NotNull EditorWindow currentWindow, @NotNull List<EditorWindow> windows,
int relativePosition) {
final int pos = windows.indexOf(currentWindow);
final int selected = pos + relativePosition;
final int normalized = Math.max(0, Math.min(selected, windows.size() - 1));
windows.get(normalized).setAsCurrentWindow(true);
}
private static @NotNull List<EditorWindow> findWindowsInRow(@NotNull EditorWindow anchor,
@NotNull List<EditorWindow> windows, final boolean vertical) {
final Rectangle anchorRect = getEditorWindowRectangle(anchor);
if (anchorRect != null) {
final List<EditorWindow> result = new ArrayList<>();
final double coord = vertical ? anchorRect.getX() : anchorRect.getY();
for (EditorWindow window : windows) {
final Rectangle rect = getEditorWindowRectangle(window);
if (rect != null) {
final double min = vertical ? rect.getX() : rect.getY();
final double max = min + (vertical ? rect.getWidth() : rect.getHeight());
if (coord >= min && coord <= max) {
result.add(window);
}
}
}
result.sort((window1, window2) -> {
final Rectangle rect1 = getEditorWindowRectangle(window1);
final Rectangle rect2 = getEditorWindowRectangle(window2);
if (rect1 != null && rect2 != null) {
final double diff = vertical ? (rect1.getY() - rect2.getY()) : (rect1.getX() - rect2.getX());
return diff < 0 ? -1 : diff > 0 ? 1 : 0;
}
return 0;
});
return result;
}
return Collections.singletonList(anchor);
}
private static @NotNull FileEditorManagerEx getFileEditorManager(@NotNull DataContext context) {
final Project project = PlatformDataKeys.PROJECT.getData(context);
return FileEditorManagerEx.getInstanceEx(Objects.requireNonNull(project));
}
private void splitWindow(int orientation, @NotNull DataContext context, @NotNull String filename) {
final Project project = PlatformDataKeys.PROJECT.getData(context);
if (project == null) return;
final FileEditorManagerEx fileEditorManager = FileEditorManagerEx.getInstanceEx(project);
VirtualFile virtualFile = null;
if (filename.length() > 0) {
virtualFile = VimPlugin.getFile().findFile(filename, project);
if (virtualFile == null) {
VimPlugin.showMessage(MessageHelper.message("could.not.find.file.0", filename));
return;
}
}
final EditorWindow editorWindow = fileEditorManager.getSplitters().getCurrentWindow();
if (editorWindow != null) {
editorWindow.split(orientation, true, virtualFile, true);
}
}
private static @Nullable Rectangle getEditorWindowRectangle(@NotNull EditorWindow window) {
final EditorComposite editor = window.getSelectedComposite();
if (editor != null) {
final Point point = editor.getComponent().getLocationOnScreen();
final Dimension dimension = editor.getComponent().getSize();
return new Rectangle(point, dimension);
}
return null;
}
}