From 1eff9d840fa38ee0c1a7e12a01ead06f28ad3d0b Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Tue, 7 Oct 2014 11:55:32 +0200 Subject: [PATCH] Save scratch files creation history in workspace.xml Move last used on top --- .../ide/scratch/NewScratchFileAction.java | 51 +++++++++++++++---- .../intellij/ide/scratch/ScratchWidget.java | 2 +- .../ide/scratch/ScratchpadManager.java | 4 -- .../ide/scratch/ScratchpadManagerImpl.java | 28 +++++++--- 4 files changed, 63 insertions(+), 22 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/scratch/NewScratchFileAction.java b/platform/lang-impl/src/com/intellij/ide/scratch/NewScratchFileAction.java index 790b36b414cb..8e15a6ce5a36 100644 --- a/platform/lang-impl/src/com/intellij/ide/scratch/NewScratchFileAction.java +++ b/platform/lang-impl/src/com/intellij/ide/scratch/NewScratchFileAction.java @@ -16,6 +16,7 @@ package com.intellij.ide.scratch; import com.intellij.featureStatistics.FeatureUsageTracker; +import com.intellij.ide.util.PropertiesComponent; import com.intellij.lang.Language; import com.intellij.lang.LanguageUtil; import com.intellij.lang.StdLanguages; @@ -36,13 +37,15 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; import com.intellij.util.Consumer; -import com.intellij.util.ObjectUtils; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.EmptyIcon; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; +import java.util.ArrayList; +import java.util.Comparator; import java.util.List; /** @@ -59,19 +62,29 @@ public class NewScratchFileAction extends AnAction implements DumbAware { public void update(@NotNull AnActionEvent e) { e.getPresentation().setEnabledAndVisible(e.getProject() != null && Registry.is("ide.scratch.enabled")); } + + public static List getLastUsedLanguagesIds(Project project) { + String[] values = PropertiesComponent.getInstance(project).getValues(ScratchpadManager.class.getName()); + if (values == null) { + return ContainerUtil.emptyList(); + } + return ContainerUtil.list(values); + } + @Override public void actionPerformed(@NotNull AnActionEvent e) { final Project project = e.getProject(); if (project == null) return; - Language previous = ScratchpadManager.getInstance(project).getLatestLanguage(); - if (previous == null) { - PsiFile file = e.getData(CommonDataKeys.PSI_FILE); - if (file != null) { - previous = file.getLanguage(); - } + + Language context = null; + PsiFile file = e.getData(CommonDataKeys.PSI_FILE); + + if (file != null) { + context = file.getLanguage(); } - ListPopup popup = buildLanguagePopup(previous, new Consumer() { + + ListPopup popup = buildLanguagePopup(project, context, new Consumer() { @Override public void consume(Language language) { FeatureUsageTracker.getInstance().triggerFeatureUsed("scratch"); @@ -83,8 +96,26 @@ public class NewScratchFileAction extends AnAction implements DumbAware { } @NotNull - static ListPopup buildLanguagePopup(@Nullable Language previous, final Consumer onChoosen) { + static ListPopup buildLanguagePopup(@NotNull Project project, @Nullable Language context, final Consumer onChoosen) { List languages = LanguageUtil.getFileLanguages(); + final List ids = new ArrayList(getLastUsedLanguagesIds(project)); + if (context != null) { + ids.add(context.getID()); + } + if (ids.isEmpty()) { + ids.add(StdLanguages.TEXT.getID()); + } + + ContainerUtil.sort(languages, new Comparator() { + @Override + public int compare(Language o1, Language o2) { + int ind1 = ids.indexOf(o1.getID()); + int ind2 = ids.indexOf(o2.getID()); + if (ind1 == -1) ind1 = 666; + if (ind2 == -1) ind2 = 666; + return ind1 - ind2; + } + }); BaseListPopupStep step = new BaseListPopupStep("Choose Language", languages) { @NotNull @@ -110,7 +141,7 @@ public class NewScratchFileAction extends AnAction implements DumbAware { return associatedLanguage != null ? associatedLanguage.getIcon() : null; } }; - step.setDefaultOptionIndex(Math.max(0, languages.indexOf(ObjectUtils.chooseNotNull(previous, StdLanguages.TEXT)))); + step.setDefaultOptionIndex(0); return tweakSizeToPreferred(JBPopupFactory.getInstance().createListPopup(step)); } diff --git a/platform/lang-impl/src/com/intellij/ide/scratch/ScratchWidget.java b/platform/lang-impl/src/com/intellij/ide/scratch/ScratchWidget.java index 9a455cad2e4a..987a806a11b0 100644 --- a/platform/lang-impl/src/com/intellij/ide/scratch/ScratchWidget.java +++ b/platform/lang-impl/src/com/intellij/ide/scratch/ScratchWidget.java @@ -56,7 +56,7 @@ class ScratchWidget extends EditorBasedWidget implements CustomStatusBarWidget.M final LightVirtualFile selectedFile = getScratchFile(); if (project == null || editor == null || selectedFile == null) return false; - ListPopup popup = NewScratchFileAction.buildLanguagePopup(selectedFile.getLanguage(), new Consumer() { + ListPopup popup = NewScratchFileAction.buildLanguagePopup(project, selectedFile.getLanguage(), new Consumer() { @Override public void consume(Language language) { selectedFile.setLanguage(LanguageSubstitutors.INSTANCE.substituteLanguage(language, selectedFile, myProject)); diff --git a/platform/lang-impl/src/com/intellij/ide/scratch/ScratchpadManager.java b/platform/lang-impl/src/com/intellij/ide/scratch/ScratchpadManager.java index 53c988ab198f..e9125e4396c2 100644 --- a/platform/lang-impl/src/com/intellij/ide/scratch/ScratchpadManager.java +++ b/platform/lang-impl/src/com/intellij/ide/scratch/ScratchpadManager.java @@ -20,7 +20,6 @@ import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; public abstract class ScratchpadManager { public static ScratchpadManager getInstance(@NotNull Project project) { @@ -29,7 +28,4 @@ public abstract class ScratchpadManager { @NotNull public abstract VirtualFile createScratchFile(@NotNull Language language); - - @Nullable - public abstract Language getLatestLanguage(); } diff --git a/platform/lang-impl/src/com/intellij/ide/scratch/ScratchpadManagerImpl.java b/platform/lang-impl/src/com/intellij/ide/scratch/ScratchpadManagerImpl.java index 052fdf8d373f..6cc2e81cecc8 100644 --- a/platform/lang-impl/src/com/intellij/ide/scratch/ScratchpadManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/ide/scratch/ScratchpadManagerImpl.java @@ -15,6 +15,7 @@ */ package com.intellij.ide.scratch; +import com.intellij.ide.util.PropertiesComponent; import com.intellij.lang.Language; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; @@ -24,12 +25,14 @@ import com.intellij.openapi.util.Computable; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.StatusBar; import com.intellij.openapi.wm.WindowManager; +import com.intellij.util.ArrayUtil; import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; + public class ScratchpadManagerImpl extends ScratchpadManager implements Disposable { private final Project myProject; private Integer myIndex = 0; - private Language myLatestLanguage; public ScratchpadManagerImpl(@NotNull Project project) { myProject = project; @@ -45,7 +48,8 @@ public class ScratchpadManagerImpl extends ScratchpadManager implements Disposab @NotNull @Override public VirtualFile createScratchFile(@NotNull final Language language) { - myLatestLanguage = language; + updateHistory(myProject, language); + return ApplicationManager.getApplication().runWriteAction(new Computable() { @Override public VirtualFile compute() { @@ -55,16 +59,26 @@ public class ScratchpadManagerImpl extends ScratchpadManager implements Disposab }); } + private static void updateHistory(Project project, Language language) { + String[] values = PropertiesComponent.getInstance(project).getValues(ScratchpadManager.class.getName()); + ArrayList lastUsed = new ArrayList(5); + lastUsed.add(language.getID()); + if (values != null) { + for (String value : values) { + if (!lastUsed.contains(value)) { + lastUsed.add(value); + } + if (lastUsed.size() == 5) break; + } + } + PropertiesComponent.getInstance(project).setValues(ScratchpadManager.class.getName(), ArrayUtil.toStringArray(lastUsed)); + } + @NotNull private static String calculatePrefix(@NotNull Project project) { return project.getLocationHash(); } - @Override - public Language getLatestLanguage() { - return myLatestLanguage; - } - @NotNull private String generateFileName() { int updated = myIndex++;