IDEA-171414 diff: warn that compared files are too big to be fully loaded

This commit is contained in:
Aleksey Pivovarov
2017-08-17 18:47:04 +03:00
committed by Aleksey Pivovarov
parent d9a8eb9234
commit 812c1c5413
5 changed files with 40 additions and 4 deletions
@@ -20,6 +20,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.vfs.SavingRequestor;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
@@ -123,6 +124,13 @@ public abstract class FileDocumentManager implements SavingRequestor {
*/
public abstract boolean isFileModified(@NotNull VirtualFile file);
/**
* Check if only beginning of the file was loaded for Document.
*
* @see FileUtilRt#isTooLarge
*/
public abstract boolean isPartialPreviewOfALargeFile(@NotNull Document document);
/**
* Discards unsaved changes for the specified document and reloads it from disk.
*
@@ -99,6 +99,11 @@ public class MockFileDocumentManagerImpl extends FileDocumentManager {
return false;
}
@Override
public boolean isPartialPreviewOfALargeFile(@NotNull Document document) {
return false;
}
@Override
public void reloadFromDisk(@NotNull Document document) {
}
@@ -40,6 +40,7 @@ import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -123,6 +124,11 @@ public class TwosideBinaryDiffViewer extends TwosideDiffViewer<BinaryEditorHolde
return DiffNotifications.createError();
}
if (FileUtilRt.isTooLarge(file1.getLength()) ||
FileUtilRt.isTooLarge(file2.getLength())) {
return DiffNotifications.createNotification("Files are too large to compare");
}
try {
// we can't use getInputStream() here because we can't restore BOM marker
// (getBom() can return null for binary files, while getInputStream() strips BOM for all files).
@@ -31,6 +31,7 @@ import com.intellij.diff.fragments.MergeLineFragment;
import com.intellij.diff.fragments.MergeWordFragment;
import com.intellij.diff.impl.DiffSettingsHolder.DiffSettings;
import com.intellij.diff.requests.ContentDiffRequest;
import com.intellij.diff.tools.util.DiffNotifications;
import com.intellij.diff.tools.util.base.TextDiffSettingsHolder.TextDiffSettings;
import com.intellij.diff.tools.util.base.TextDiffViewerUtil;
import com.intellij.diff.tools.util.text.*;
@@ -476,7 +477,16 @@ public class DiffUtil {
@Nullable
private static JComponent createTitleWithNotifications(@Nullable JComponent title,
@NotNull DiffContent content) {
List<JComponent> notifications = getCustomNotifications(content);
List<JComponent> notifications = new ArrayList<>();
notifications.addAll(getCustomNotifications(content));
if (content instanceof DocumentContent) {
Document document = ((DocumentContent)content).getDocument();
if (FileDocumentManager.getInstance().isPartialPreviewOfALargeFile(document)) {
notifications.add(DiffNotifications.createNotification("File is too large. Only preview is loaded."));
}
}
if (notifications.isEmpty()) return title;
JPanel panel = new JPanel(new BorderLayout(0, TITLE_GAP));
@@ -84,6 +84,7 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Virt
private static final Key<String> LINE_SEPARATOR_KEY = Key.create("LINE_SEPARATOR_KEY");
private static final Key<VirtualFile> FILE_KEY = Key.create("FILE_KEY");
private static final Key<Boolean> MUST_RECOMPUTE_FILE_TYPE = Key.create("Must recompute file type");
private static final Key<Boolean> BIG_FILE_PREVIEW = Key.create("BIG_FILE_PREVIEW");
private final Set<Document> myUnsavedDocuments = ContainerUtil.newConcurrentSet();
@@ -196,6 +197,7 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Virt
document = (DocumentEx)createDocument(text, file);
document.setModificationStamp(file.getModificationStamp());
document.putUserData(BIG_FILE_PREVIEW, tooLarge ? Boolean.TRUE : null);
final FileType fileType = file.getFileType();
document.setReadOnly(tooLarge || !file.isWritable() || fileType.isBinary());
@@ -546,6 +548,11 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Virt
return doc != null && isDocumentUnsaved(doc) && doc.getModificationStamp() != file.getModificationStamp();
}
@Override
public boolean isPartialPreviewOfALargeFile(@NotNull Document document) {
return document.getUserData(BIG_FILE_PREVIEW) == Boolean.TRUE;
}
@Override
public void propertyChanged(@NotNull VirtualFilePropertyEvent event) {
final VirtualFile file = event.getFile();
@@ -626,11 +633,11 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Virt
boolean wasWritable = document.isWritable();
document.setReadOnly(false);
boolean tooLarge = FileUtilRt.isTooLarge(file.getLength());
CharSequence reloaded = tooLarge ? LoadTextUtil.loadText(file, getPreviewCharCount(file)) : LoadTextUtil.loadText(file);
isReloadable[0] = isReloadable(file, document, project);
if (isReloadable[0]) {
DocumentEx documentEx = (DocumentEx)document;
documentEx.replaceText(reloaded, file.getModificationStamp());
CharSequence reloaded = tooLarge ? LoadTextUtil.loadText(file, getPreviewCharCount(file)) : LoadTextUtil.loadText(file);
((DocumentEx)document).replaceText(reloaded, file.getModificationStamp());
document.putUserData(BIG_FILE_PREVIEW, tooLarge ? Boolean.TRUE : null);
}
document.setReadOnly(!wasWritable);
}