mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-14 09:12:22 +07:00
PY-75877 Fix problem with jupyter notebook shelve
(cherry picked from commit 9172e753ec6e1dffca73aa9bf4608400f1ea3c9a) GitOrigin-RevId: 6331ca59f530bb4b7ed177639ef2f1cafab3ff32
This commit is contained in:
committed by
intellij-monorepo-bot
parent
fd6c1512cd
commit
57971b4179
@@ -6,7 +6,27 @@ import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
@ApiStatus.Internal
|
||||
interface TextPresentationTransformer {
|
||||
fun fromPersistent(text: CharSequence, virtualFile: VirtualFile):CharSequence
|
||||
/**
|
||||
* Transforms the given text from its persistent representation to its in-memory representation
|
||||
* based on the specified virtual file's context.
|
||||
*
|
||||
* Used in Jupyter Notebooks to switch from JSON representation to source code text with #%% separators between cells.
|
||||
*
|
||||
* @param text The text in its persistent representation to be transformed
|
||||
* @param virtualFile The virtual file providing context for the transformation
|
||||
* @return The text in its in-memory representation
|
||||
*/
|
||||
fun fromPersistent(text: CharSequence, virtualFile: VirtualFile): CharSequence
|
||||
|
||||
fun toPersistent(text: CharSequence, virtualFile: VirtualFile):CharSequence
|
||||
/**
|
||||
* Transforms the given text from its in-memory representation to its persistent representation
|
||||
* based on the context provided by the specified virtual file.
|
||||
*
|
||||
* Used in Jupyter Notebooks to switch from source code text with #%% separators between cells to JSON representation.
|
||||
*
|
||||
* @param text The text in its in-memory representation to be transformed
|
||||
* @param virtualFile The virtual file providing context for the transformation
|
||||
* @return The text in its persistent representation
|
||||
*/
|
||||
fun toPersistent(text: CharSequence, virtualFile: VirtualFile): CharSequence
|
||||
}
|
||||
@@ -34,6 +34,9 @@ class TextPresentationTransformers : FileTypeExtension<TextPresentationTransform
|
||||
companion object {
|
||||
val EP: ExtensionPointName<KeyedLazyInstance<TextPresentationTransformer>> = ExtensionPointName("com.intellij.fileEditor.textPresentationTransformer")
|
||||
|
||||
/**
|
||||
* See [TextPresentationTransformer.fromPersistent]
|
||||
*/
|
||||
@JvmStatic
|
||||
fun fromPersistent(text: CharSequence, virtualFile: VirtualFile): CharSequence {
|
||||
val transformer = service<TextPresentationTransformers>().forFileType(virtualFile.fileType)
|
||||
@@ -44,6 +47,9 @@ class TextPresentationTransformers : FileTypeExtension<TextPresentationTransform
|
||||
return transformer.fromPersistent(text, virtualFile)
|
||||
}
|
||||
|
||||
/**
|
||||
* See [TextPresentationTransformer.toPersistent]
|
||||
*/
|
||||
@JvmStatic
|
||||
fun toPersistent(text: CharSequence, virtualFile: VirtualFile): CharSequence {
|
||||
val transformer = service<TextPresentationTransformers>().forFileType(virtualFile.fileType)
|
||||
|
||||
@@ -408,16 +408,17 @@ public final class LoadTextUtil {
|
||||
write(project, file, requestor, newText, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normally, one should not use this method.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public static void write(@Nullable Project project,
|
||||
@NotNull VirtualFile virtualFile,
|
||||
@NotNull Object requestor,
|
||||
@NotNull String text,
|
||||
long newModificationStamp) throws IOException {
|
||||
long newModificationStamp,
|
||||
boolean applyTextTransformer) throws IOException {
|
||||
Charset existing = virtualFile.getCharset();
|
||||
text = TextPresentationTransformers.toPersistent(text, virtualFile).toString();
|
||||
if (applyTextTransformer) {
|
||||
text = TextPresentationTransformers.toPersistent(text, virtualFile).toString();
|
||||
}
|
||||
Pair.NonNull<Charset, byte[]> chosen = charsetForWriting(project, virtualFile, text, existing);
|
||||
Charset charset = chosen.first;
|
||||
byte[] buffer = chosen.second;
|
||||
@@ -433,6 +434,17 @@ public final class LoadTextUtil {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normally, one should not use this method.
|
||||
*/
|
||||
public static void write(@Nullable Project project,
|
||||
@NotNull VirtualFile virtualFile,
|
||||
@NotNull Object requestor,
|
||||
@NotNull String text,
|
||||
long newModificationStamp) throws IOException {
|
||||
write(project, virtualFile, requestor, text, newModificationStamp, true);
|
||||
}
|
||||
|
||||
public static @NotNull Pair.NonNull<Charset, byte[]> charsetForWriting(@Nullable Project project,
|
||||
@NotNull VirtualFile virtualFile,
|
||||
@NotNull String text,
|
||||
|
||||
@@ -32,6 +32,7 @@ import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.encoding.EncodingManager;
|
||||
import com.intellij.openapi.vfs.encoding.EncodingProjectManager;
|
||||
import com.intellij.openapi.vfs.transformer.TextPresentationTransformers;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.testFramework.BinaryLightVirtualFile;
|
||||
import com.intellij.testFramework.LightVirtualFile;
|
||||
@@ -394,7 +395,10 @@ public final class DiffContentFactoryImpl extends DiffContentFactoryEx {
|
||||
if (project == null || project.isDefault()) return null;
|
||||
if (fileType != null && fileType.isBinary()) return null;
|
||||
|
||||
LightVirtualFile file = new MyLightVirtualFile(lightFilePath, fileType, content);
|
||||
// Here we need a dummy originalFile to pass it to [TextPresentationTransformers.fromPersistent]
|
||||
LightVirtualFile originalFile = new MyLightVirtualFile(lightFilePath, fileType, content);
|
||||
String convertedText = TextPresentationTransformers.fromPersistent(content, originalFile).toString();
|
||||
LightVirtualFile file = new MyLightVirtualFile(lightFilePath, fileType, convertedText);
|
||||
file.setWritable(!readOnly);
|
||||
|
||||
return ReadAction.compute(() -> {
|
||||
@@ -402,6 +406,7 @@ public final class DiffContentFactoryImpl extends DiffContentFactoryEx {
|
||||
if (document == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
PsiDocumentManager.getInstance(project).getPsiFile(document);
|
||||
return document;
|
||||
});
|
||||
@@ -884,8 +889,10 @@ public final class DiffContentFactoryImpl extends DiffContentFactoryEx {
|
||||
@Override
|
||||
public @Nullable FileType guessContentType() {
|
||||
VirtualFile file = myFilePath.getVirtualFile();
|
||||
if (file != null) return file.getFileType();
|
||||
return null;
|
||||
if (file == null) {
|
||||
return FileTypeManager.getInstance().getFileTypeByFileName(myFilePath.getName());
|
||||
}
|
||||
return file.getFileType();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,12 +2,14 @@
|
||||
package com.intellij.openapi.vcs.changes;
|
||||
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.openapi.application.WriteAction;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.transformer.TextPresentationTransformers;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -28,7 +30,15 @@ public class CurrentContentRevision implements ByteBackedContentRevision {
|
||||
return null;
|
||||
}
|
||||
Document doc = ReadAction.compute(() -> FileDocumentManager.getInstance().getDocument(vFile));
|
||||
return doc == null ? null : doc.getText();
|
||||
if (doc == null) {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
// In some cases like Jupyter Notebooks we need to make TextPresentationTransformers.toPersistent to have a correct text representation
|
||||
// In the case of Jupyter Notebooks it is a JSON representation of the notebook instead of representation with #%% cells separators
|
||||
String docText = doc.getText();
|
||||
return ReadAction.compute(() -> TextPresentationTransformers.toPersistent(docText, vFile).toString());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -7,11 +7,13 @@ import com.intellij.openapi.diff.impl.patch.CharsetEP;
|
||||
import com.intellij.openapi.diff.impl.patch.TextFilePatch;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.fileEditor.impl.LoadTextUtil;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vcs.changes.CommitContext;
|
||||
import com.intellij.openapi.vcs.changes.patch.ApplyPatchForBaseRevisionTexts;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.transformer.TextPresentationTransformers;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -36,15 +38,17 @@ public final class ApplyTextFilePatch extends ApplyFilePatchBase<TextFilePatch>
|
||||
throw new IOException("Failed to set contents for updated file " + fileToPatch.getPath());
|
||||
}
|
||||
|
||||
GenericPatchApplier.AppliedPatch appliedPatch = GenericPatchApplier.apply(document.getText(), myPatch.getHunks());
|
||||
String documentText = document.getText();
|
||||
String fileTextPersistent = TextPresentationTransformers.toPersistent(documentText, fileToPatch).toString();
|
||||
GenericPatchApplier.AppliedPatch appliedPatch = GenericPatchApplier.apply(fileTextPersistent, myPatch.getHunks());
|
||||
|
||||
if (appliedPatch != null) {
|
||||
if (appliedPatch.status == ApplyPatchStatus.ALREADY_APPLIED) {
|
||||
return new Result(appliedPatch.status);
|
||||
}
|
||||
|
||||
if (appliedPatch.status == ApplyPatchStatus.SUCCESS) {
|
||||
VcsFacade.getInstance().runHeavyModificationTask(project, document, () -> document.setText(appliedPatch.patchedText));
|
||||
FileDocumentManager.getInstance().saveDocument(document);
|
||||
updateDocumentContent(project, document, fileToPatch, appliedPatch.patchedText);
|
||||
return new Result(appliedPatch.status);
|
||||
}
|
||||
}
|
||||
@@ -77,7 +81,23 @@ public final class ApplyTextFilePatch extends ApplyFilePatchBase<TextFilePatch>
|
||||
catch (IllegalArgumentException ignore) {
|
||||
}
|
||||
}
|
||||
document.setText(myPatch.getSingleHunkPatchText());
|
||||
FileDocumentManager.getInstance().saveDocument(document);
|
||||
|
||||
String patchText = myPatch.getSingleHunkPatchText();
|
||||
updateDocumentContent(project, document, newFile, patchText);
|
||||
}
|
||||
|
||||
private void updateDocumentContent(@NotNull Project project,
|
||||
@NotNull Document document,
|
||||
@NotNull VirtualFile file,
|
||||
@NotNull String patchedText) {
|
||||
VcsFacade.getInstance().runHeavyModificationTask(project, document, () -> {
|
||||
try {
|
||||
LoadTextUtil.write(project, file, this, patchedText, -1, false);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
FileDocumentManager.getInstance().reloadFromDisk(document);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user