IDEA-63852 Add Ctrl + Shift + T to reopen last closed code tab

This commit is contained in:
Konstantin Bulenkov
2012-06-05 10:02:33 +02:00
parent ac3a910061
commit 3b741cc670
4 changed files with 103 additions and 4 deletions
@@ -33,15 +33,14 @@ import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx;
import com.intellij.openapi.fileTypes.FileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Splitter;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Iconable;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.*;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.ui.LayeredIcon;
import com.intellij.util.IconUtil;
import com.intellij.util.containers.Stack;
import com.intellij.util.ui.EmptyIcon;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
@@ -74,6 +73,15 @@ public class EditorWindow {
private boolean myIsDisposed = false;
private static final Icon PIN_ICON = AllIcons.Nodes.TabPin;
public static final Key<Integer> INITIAL_INDEX_KEY = Key.create("initial editor index");
private Stack<Pair<String, Integer>> myRemovedTabs = new Stack<Pair<String, Integer>>(UISettings.getInstance().EDITOR_TAB_LIMIT) {
@Override
public void push(Pair<String, Integer> pair) {
if (size() >= UISettings.getInstance().EDITOR_TAB_LIMIT) {
remove(0);
}
super.push(pair);
}
};
protected EditorWindow(final EditorsSplitters owner) {
myOwner = owner;
@@ -264,6 +272,21 @@ public class EditorWindow {
closeFile(file, unsplit, true);
}
public boolean hasClosedTabs() {
return !myRemovedTabs.empty();
}
public void restoreClosedTab() {
assert hasClosedTabs() : "Nothing to restore";
final Pair<String, Integer> info = myRemovedTabs.pop();
final VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(info.getFirst());
final Integer second = info.getSecond();
if (file != null) {
getManager().openFileImpl4(this, file, true, null, true, second == null ? -1 : second.intValue());
}
}
public void closeFile(final VirtualFile file, final boolean unsplit, final boolean transferFocus) {
final FileEditorManagerImpl editorManager = getManager();
editorManager.runChange(new FileEditorManagerChange() {
@@ -282,6 +305,7 @@ public class EditorWindow {
final int componentIndex = findComponentIndex(editor.getComponent());
if (componentIndex >= 0) { // editor could close itself on decomposition
final int indexToSelect = calcIndexToSelect(file, componentIndex);
myRemovedTabs.push(Pair.create(file.getUrl(), componentIndex));
final ActionCallback removeTab = myTabbedPane.removeTabAt(componentIndex, indexToSelect, transferFocus);
final Runnable disposer = new Runnable() {
public void run() {
@@ -683,6 +683,16 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
final boolean focusEditor,
@Nullable final HistoryEntry entry,
boolean current) {
return openFileImpl4(window, file, focusEditor, entry, current, -1);
}
@NotNull
Pair<FileEditor[], FileEditorProvider[]> openFileImpl4(@NotNull final EditorWindow window,
@NotNull final VirtualFile file,
final boolean focusEditor,
@Nullable final HistoryEntry entry,
boolean current,
int index) {
// Open file
FileEditor[] editors;
FileEditorProvider[] providers;
@@ -748,6 +758,10 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
// Now we have to create EditorComposite and insert it into the TabbedEditorComponent.
// After that we have to select opened editor.
newSelectedComposite = new EditorWithProviderComposite(file, editors, providers, this);
if (index >= 0) {
newSelectedComposite.getFile().putUserData(EditorWindow.INITIAL_INDEX_KEY, index);
}
}
window.setEditor(newSelectedComposite, focusEditor);
@@ -0,0 +1,59 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.fileEditor.impl;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
/**
* @author Konstantin Bulenkov
*/
public class ReopenClosedTabAction extends AnAction {
public ReopenClosedTabAction() {
super("Reopen Closed Tab");
}
@Override
public void actionPerformed(AnActionEvent e) {
final EditorWindow window = getEditorWindow(e);
if (window != null) {
window.restoreClosedTab();
}
}
@Nullable
private static EditorWindow getEditorWindow(AnActionEvent e) {
final Component component = e.getData(PlatformDataKeys.CONTEXT_COMPONENT);
if (component != null) {
final EditorsSplitters splitters = UIUtil.getParentOfType(EditorsSplitters.class, component);
if (splitters != null) {
return splitters.getCurrentWindow();
}
}
return null;
}
@Override
public void update(AnActionEvent e) {
final EditorWindow window = getEditorWindow(e);
e.getPresentation().setEnabled(window != null && window.hasClosedTabs());
}
}
@@ -331,6 +331,7 @@
<action id="CloseAllUnpinnedEditors" class="com.intellij.ide.actions.CloseAllUnpinnedEditorsAction"/>
</group>
<separator/>
<action id="ReopenClosedTab" class="com.intellij.openapi.fileEditor.impl.ReopenClosedTabAction" />
<action id="SplitVertically" class="com.intellij.ide.actions.SplitVerticallyAction" icon="AllIcons.Actions.SplitVertically"/>
<action id="SplitHorizontally" class="com.intellij.ide.actions.SplitHorizontallyAction" icon="AllIcons.Actions.SplitHorizontally"/>
<action id="ChangeSplitOrientation" class="com.intellij.ide.actions.ChangeSplitterOrientationAction"/>
@@ -422,6 +423,7 @@
<separator/>
<reference ref="NextTab"/>
<reference ref="PreviousTab"/>
<reference ref="ReopenClosedTab"/>
<separator/>
<reference ref="Unsplit"/>
<reference ref="UnsplitAll"/>