mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-15 11:53:49 +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
|
@ApiStatus.Internal
|
||||||
interface TextPresentationTransformer {
|
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 {
|
companion object {
|
||||||
val EP: ExtensionPointName<KeyedLazyInstance<TextPresentationTransformer>> = ExtensionPointName("com.intellij.fileEditor.textPresentationTransformer")
|
val EP: ExtensionPointName<KeyedLazyInstance<TextPresentationTransformer>> = ExtensionPointName("com.intellij.fileEditor.textPresentationTransformer")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See [TextPresentationTransformer.fromPersistent]
|
||||||
|
*/
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun fromPersistent(text: CharSequence, virtualFile: VirtualFile): CharSequence {
|
fun fromPersistent(text: CharSequence, virtualFile: VirtualFile): CharSequence {
|
||||||
val transformer = service<TextPresentationTransformers>().forFileType(virtualFile.fileType)
|
val transformer = service<TextPresentationTransformers>().forFileType(virtualFile.fileType)
|
||||||
@@ -44,6 +47,9 @@ class TextPresentationTransformers : FileTypeExtension<TextPresentationTransform
|
|||||||
return transformer.fromPersistent(text, virtualFile)
|
return transformer.fromPersistent(text, virtualFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See [TextPresentationTransformer.toPersistent]
|
||||||
|
*/
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun toPersistent(text: CharSequence, virtualFile: VirtualFile): CharSequence {
|
fun toPersistent(text: CharSequence, virtualFile: VirtualFile): CharSequence {
|
||||||
val transformer = service<TextPresentationTransformers>().forFileType(virtualFile.fileType)
|
val transformer = service<TextPresentationTransformers>().forFileType(virtualFile.fileType)
|
||||||
|
|||||||
@@ -408,16 +408,17 @@ public final class LoadTextUtil {
|
|||||||
write(project, file, requestor, newText, -1);
|
write(project, file, requestor, newText, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@ApiStatus.Internal
|
||||||
* Normally, one should not use this method.
|
|
||||||
*/
|
|
||||||
public static void write(@Nullable Project project,
|
public static void write(@Nullable Project project,
|
||||||
@NotNull VirtualFile virtualFile,
|
@NotNull VirtualFile virtualFile,
|
||||||
@NotNull Object requestor,
|
@NotNull Object requestor,
|
||||||
@NotNull String text,
|
@NotNull String text,
|
||||||
long newModificationStamp) throws IOException {
|
long newModificationStamp,
|
||||||
|
boolean applyTextTransformer) throws IOException {
|
||||||
Charset existing = virtualFile.getCharset();
|
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);
|
Pair.NonNull<Charset, byte[]> chosen = charsetForWriting(project, virtualFile, text, existing);
|
||||||
Charset charset = chosen.first;
|
Charset charset = chosen.first;
|
||||||
byte[] buffer = chosen.second;
|
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,
|
public static @NotNull Pair.NonNull<Charset, byte[]> charsetForWriting(@Nullable Project project,
|
||||||
@NotNull VirtualFile virtualFile,
|
@NotNull VirtualFile virtualFile,
|
||||||
@NotNull String text,
|
@NotNull String text,
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import com.intellij.openapi.vfs.VfsUtil;
|
|||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
import com.intellij.openapi.vfs.encoding.EncodingManager;
|
import com.intellij.openapi.vfs.encoding.EncodingManager;
|
||||||
import com.intellij.openapi.vfs.encoding.EncodingProjectManager;
|
import com.intellij.openapi.vfs.encoding.EncodingProjectManager;
|
||||||
|
import com.intellij.openapi.vfs.transformer.TextPresentationTransformers;
|
||||||
import com.intellij.psi.PsiDocumentManager;
|
import com.intellij.psi.PsiDocumentManager;
|
||||||
import com.intellij.testFramework.BinaryLightVirtualFile;
|
import com.intellij.testFramework.BinaryLightVirtualFile;
|
||||||
import com.intellij.testFramework.LightVirtualFile;
|
import com.intellij.testFramework.LightVirtualFile;
|
||||||
@@ -394,7 +395,10 @@ public final class DiffContentFactoryImpl extends DiffContentFactoryEx {
|
|||||||
if (project == null || project.isDefault()) return null;
|
if (project == null || project.isDefault()) return null;
|
||||||
if (fileType != null && fileType.isBinary()) 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);
|
file.setWritable(!readOnly);
|
||||||
|
|
||||||
return ReadAction.compute(() -> {
|
return ReadAction.compute(() -> {
|
||||||
@@ -402,6 +406,7 @@ public final class DiffContentFactoryImpl extends DiffContentFactoryEx {
|
|||||||
if (document == null) {
|
if (document == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
PsiDocumentManager.getInstance(project).getPsiFile(document);
|
PsiDocumentManager.getInstance(project).getPsiFile(document);
|
||||||
return document;
|
return document;
|
||||||
});
|
});
|
||||||
@@ -884,8 +889,10 @@ public final class DiffContentFactoryImpl extends DiffContentFactoryEx {
|
|||||||
@Override
|
@Override
|
||||||
public @Nullable FileType guessContentType() {
|
public @Nullable FileType guessContentType() {
|
||||||
VirtualFile file = myFilePath.getVirtualFile();
|
VirtualFile file = myFilePath.getVirtualFile();
|
||||||
if (file != null) return file.getFileType();
|
if (file == null) {
|
||||||
return null;
|
return FileTypeManager.getInstance().getFileTypeByFileName(myFilePath.getName());
|
||||||
|
}
|
||||||
|
return file.getFileType();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,12 +2,14 @@
|
|||||||
package com.intellij.openapi.vcs.changes;
|
package com.intellij.openapi.vcs.changes;
|
||||||
|
|
||||||
import com.intellij.openapi.application.ReadAction;
|
import com.intellij.openapi.application.ReadAction;
|
||||||
|
import com.intellij.openapi.application.WriteAction;
|
||||||
import com.intellij.openapi.editor.Document;
|
import com.intellij.openapi.editor.Document;
|
||||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||||
import com.intellij.openapi.vcs.FilePath;
|
import com.intellij.openapi.vcs.FilePath;
|
||||||
import com.intellij.openapi.vcs.VcsException;
|
import com.intellij.openapi.vcs.VcsException;
|
||||||
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
|
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
|
import com.intellij.openapi.vfs.transformer.TextPresentationTransformers;
|
||||||
import org.jetbrains.annotations.NonNls;
|
import org.jetbrains.annotations.NonNls;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@@ -28,7 +30,15 @@ public class CurrentContentRevision implements ByteBackedContentRevision {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Document doc = ReadAction.compute(() -> FileDocumentManager.getInstance().getDocument(vFile));
|
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
|
@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.diff.impl.patch.TextFilePatch;
|
||||||
import com.intellij.openapi.editor.Document;
|
import com.intellij.openapi.editor.Document;
|
||||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||||
|
import com.intellij.openapi.fileEditor.impl.LoadTextUtil;
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
import com.intellij.openapi.vcs.FilePath;
|
import com.intellij.openapi.vcs.FilePath;
|
||||||
import com.intellij.openapi.vcs.changes.CommitContext;
|
import com.intellij.openapi.vcs.changes.CommitContext;
|
||||||
import com.intellij.openapi.vcs.changes.patch.ApplyPatchForBaseRevisionTexts;
|
import com.intellij.openapi.vcs.changes.patch.ApplyPatchForBaseRevisionTexts;
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
|
import com.intellij.openapi.vfs.transformer.TextPresentationTransformers;
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
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());
|
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 != null) {
|
||||||
if (appliedPatch.status == ApplyPatchStatus.ALREADY_APPLIED) {
|
if (appliedPatch.status == ApplyPatchStatus.ALREADY_APPLIED) {
|
||||||
return new Result(appliedPatch.status);
|
return new Result(appliedPatch.status);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (appliedPatch.status == ApplyPatchStatus.SUCCESS) {
|
if (appliedPatch.status == ApplyPatchStatus.SUCCESS) {
|
||||||
VcsFacade.getInstance().runHeavyModificationTask(project, document, () -> document.setText(appliedPatch.patchedText));
|
updateDocumentContent(project, document, fileToPatch, appliedPatch.patchedText);
|
||||||
FileDocumentManager.getInstance().saveDocument(document);
|
|
||||||
return new Result(appliedPatch.status);
|
return new Result(appliedPatch.status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,7 +81,23 @@ public final class ApplyTextFilePatch extends ApplyFilePatchBase<TextFilePatch>
|
|||||||
catch (IllegalArgumentException ignore) {
|
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