mirror of
https://github.com/chylex/IntelliJ-IdeaVim.git
synced 2025-04-16 11:15:41 +02:00
185 lines
7.5 KiB
Java
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;
|
|
}
|
|
}
|