mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-126952 Scratches should have an extension
This commit is contained in:
@@ -19,12 +19,19 @@ import com.intellij.ide.util.PropertiesComponent;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.LanguageUtil;
|
||||
import com.intellij.lang.PerFileMappings;
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.command.undo.BasicUndoableAction;
|
||||
import com.intellij.openapi.command.undo.UndoManager;
|
||||
import com.intellij.openapi.command.undo.UnexpectedUndoException;
|
||||
import com.intellij.openapi.fileTypes.LanguageFileType;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.popup.*;
|
||||
import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.ReadonlyStatusHandler;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Consumer;
|
||||
@@ -38,10 +45,9 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author gregsh
|
||||
@@ -62,13 +68,23 @@ public abstract class LRUPopupBuilder<T> {
|
||||
private JBIterable<T> myExtraItems = JBIterable.empty();
|
||||
|
||||
@NotNull
|
||||
public static ListPopup forFileLanguages(@NotNull Project project, @NotNull final Iterable<VirtualFile> files, @NotNull final PerFileMappings<Language> mappings) {
|
||||
public static ListPopup forFileLanguages(@NotNull Project project, @NotNull Iterable<VirtualFile> files, @NotNull final PerFileMappings<Language> mappings) {
|
||||
final VirtualFile[] filesCopy = VfsUtilCore.toVirtualFileArray(JBIterable.from(files).toList());
|
||||
Arrays.sort(filesCopy, new Comparator<VirtualFile>() {
|
||||
@Override
|
||||
public int compare(VirtualFile o1, VirtualFile o2) {
|
||||
return StringUtil.compare(o1.getName(), o2.getName(), !o1.getFileSystem().isCaseSensitive());
|
||||
}
|
||||
});
|
||||
return forFileLanguages(project, null, new Consumer<Language>() {
|
||||
@Override
|
||||
public void consume(Language t) {
|
||||
for (VirtualFile file : files) {
|
||||
mappings.setMapping(file, t);
|
||||
}
|
||||
public void consume(final Language t) {
|
||||
new WriteCommandAction(project, "Change Language") {
|
||||
@Override
|
||||
protected void run(@NotNull Result result) throws Throwable {
|
||||
changeLanguageWithUndo(project, t, filesCopy, mappings);
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -260,4 +276,47 @@ public abstract class LRUPopupBuilder<T> {
|
||||
return getClass().getName() + "/" + myTitle;
|
||||
}
|
||||
|
||||
|
||||
private static void changeLanguageWithUndo(@NotNull Project project,
|
||||
@NotNull final Language t,
|
||||
@NotNull final VirtualFile[] sortedFiles,
|
||||
@NotNull final PerFileMappings<Language> mappings) throws UnexpectedUndoException {
|
||||
ReadonlyStatusHandler.OperationStatus status = ReadonlyStatusHandler.getInstance(project).ensureFilesWritable(sortedFiles);
|
||||
if (status.hasReadonlyFiles()) return;
|
||||
|
||||
final Set<VirtualFile> matchedExtensions = ContainerUtil.newLinkedHashSet();
|
||||
final Map<VirtualFile, Language> oldMapping = ContainerUtil.newHashMap();
|
||||
for (VirtualFile file : sortedFiles) {
|
||||
oldMapping.put(file, mappings.getMapping(file));
|
||||
if (ScratchUtil.hasMatchingExtension(project, file)) {
|
||||
matchedExtensions.add(file);
|
||||
}
|
||||
}
|
||||
|
||||
BasicUndoableAction action = new BasicUndoableAction(sortedFiles) {
|
||||
@Override
|
||||
public void undo() throws UnexpectedUndoException {
|
||||
for (VirtualFile file : sortedFiles) {
|
||||
mappings.setMapping(file, oldMapping.get(file));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void redo() throws UnexpectedUndoException {
|
||||
for (VirtualFile file : sortedFiles) {
|
||||
mappings.setMapping(file, t);
|
||||
}
|
||||
}
|
||||
};
|
||||
action.redo();
|
||||
UndoManager.getInstance(project).undoableActionPerformed(action);
|
||||
|
||||
for (VirtualFile file : matchedExtensions) {
|
||||
try {
|
||||
ScratchUtil.updateFileExtension(project, file);
|
||||
}
|
||||
catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.editor.Caret;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.fileEditor.FileEditorManager;
|
||||
import com.intellij.openapi.fileTypes.LanguageFileType;
|
||||
import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
@@ -37,6 +38,7 @@ import com.intellij.psi.PsiFile;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.PathUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.JBIterable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -111,9 +113,11 @@ public class ScratchFileActions {
|
||||
static void doCreateNewScratch(@NotNull Project project, boolean buffer, @NotNull Language language, @NotNull String text) {
|
||||
FeatureUsageTracker.getInstance().triggerFeatureUsed("scratch");
|
||||
|
||||
LanguageFileType fileType = language.getAssociatedFileType();
|
||||
String ext = buffer || fileType == null? "" : fileType.getDefaultExtension();
|
||||
String fileName = buffer ? "buffer" + nextBufferIndex() : "scratch";
|
||||
ScratchFileService.Option option = buffer ? ScratchFileService.Option.create_if_missing : ScratchFileService.Option.create_new_always;
|
||||
VirtualFile f = ScratchRootType.getInstance().createScratchFile(project, fileName, language, text, option);
|
||||
VirtualFile f = ScratchRootType.getInstance().createScratchFile(project, PathUtil.makeFileName(fileName, ext), language, text, option);
|
||||
if (f != null) {
|
||||
FileEditorManager.getInstance(project).openFile(f, true);
|
||||
}
|
||||
|
||||
@@ -15,9 +15,21 @@
|
||||
*/
|
||||
package com.intellij.ide.scratch;
|
||||
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.LanguageUtil;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.PathUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author gregsh
|
||||
*/
|
||||
@@ -33,4 +45,33 @@ public class ScratchUtil {
|
||||
public static boolean isScratch(@Nullable VirtualFile file) {
|
||||
return file != null && file.getFileType() == ScratchFileType.INSTANCE;
|
||||
}
|
||||
|
||||
public static void updateFileExtension(@NotNull Project project, @Nullable VirtualFile file) throws IOException {
|
||||
ApplicationManager.getApplication().assertWriteAccessAllowed();
|
||||
if (CommandProcessor.getInstance().getCurrentCommand() == null) {
|
||||
throw new AssertionError("command required");
|
||||
}
|
||||
|
||||
if (file == null) return;
|
||||
Language language = LanguageUtil.getLanguageForPsi(project, file);
|
||||
String extension = file.getExtension();
|
||||
FileType expected = extension == null ? null : FileTypeManager.getInstance().getFileTypeByExtension(extension);
|
||||
FileType actual = language == null ? null : language.getAssociatedFileType();
|
||||
if (expected == actual || actual == null) return;
|
||||
String ext = actual.getDefaultExtension();
|
||||
if (StringUtil.isEmpty(ext)) return;
|
||||
|
||||
String newName = PathUtil.makeFileName(file.getNameWithoutExtension(), ext);
|
||||
VirtualFile parent = file.getParent();
|
||||
newName = parent != null && parent.findChild(newName) != null ? PathUtil.makeFileName(file.getName(), ext) : newName;
|
||||
file.rename(ScratchUtil.class, newName);
|
||||
}
|
||||
|
||||
public static boolean hasMatchingExtension(@NotNull Project project, @NotNull VirtualFile file) {
|
||||
String extension = file.getExtension();
|
||||
Language language = LanguageUtil.getLanguageForPsi(project, file);
|
||||
FileType expected = extension == null ? null : FileTypeManager.getInstance().getFileTypeByExtension(extension);
|
||||
FileType actual = language == null ? null : language.getAssociatedFileType();
|
||||
return expected == actual && actual != null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user