From 204afe9ca2e2c63fec76b1dc2e555a1614c5ae39 Mon Sep 17 00:00:00 2001 From: Nadya Zabrodina Date: Fri, 29 Apr 2016 12:58:41 +0300 Subject: [PATCH] [patch]: implement analyze and apply patch on the fly --- .../openapi/diff/impl/patch/PatchReader.java | 35 +++++++++++++ .../openapi/vcs/VcsApplicationSettings.java | 1 + .../patch/ApplyPatchFromClipboardAction.java | 52 +++++++++++++++++-- .../changes/patch/PatchClipboardListener.java | 35 +++++++++++++ 4 files changed, 118 insertions(+), 5 deletions(-) create mode 100644 platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/PatchClipboardListener.java diff --git a/platform/vcs-api/src/com/intellij/openapi/diff/impl/patch/PatchReader.java b/platform/vcs-api/src/com/intellij/openapi/diff/impl/patch/PatchReader.java index c0ccbf4e8cc7..d62c74f14ef6 100644 --- a/platform/vcs-api/src/com/intellij/openapi/diff/impl/patch/PatchReader.java +++ b/platform/vcs-api/src/com/intellij/openapi/diff/impl/patch/PatchReader.java @@ -47,6 +47,9 @@ public class PatchReader { @NonNls private static final String CONTEXT_HUNK_PREFIX = "***************"; @NonNls private static final String CONTEXT_FILE_PREFIX = "*** "; + @NonNls private static final String UNIFIED_BEFORE_HUNK_PREFIX = "--- "; + @NonNls private static final String UNIFIED_AFTER_HUNK_PREFIX = "+++ "; + @NonNls private static final Pattern ourUnifiedHunkStartPattern = Pattern.compile("@@ -(\\d+)(,(\\d+))? \\+(\\d+)(,(\\d+))? @@.*"); @NonNls private static final Pattern ourContextBeforeHunkStartPattern = Pattern.compile("\\*\\*\\* (\\d+),(\\d+) \\*\\*\\*\\*"); @NonNls private static final Pattern ourContextAfterHunkStartPattern = Pattern.compile("--- (\\d+),(\\d+) ----"); @@ -629,4 +632,36 @@ public class PatchReader { return myHunkCount == 1 && myDeleted; } } + + public static boolean isPatchContent(@Nullable String content) { + if (content == null) return false; + List lines = LineTokenizer.tokenizeIntoList(content, false); + final ListIterator iterator = lines.listIterator(); + DiffFormat currentFormat = null; + while (iterator.hasNext()) { + String line = iterator.next(); + if (line.startsWith(CONTEXT_HUNK_PREFIX)) { + currentFormat = DiffFormat.CONTEXT; + } + else if (currentFormat == DiffFormat.CONTEXT && ourContextBeforeHunkStartPattern.matcher(line).matches()) { + break; + } + else if (line.startsWith(UNIFIED_BEFORE_HUNK_PREFIX) && currentFormat == null) { + currentFormat = DiffFormat.UNIFIED; + } + else if (currentFormat == DiffFormat.UNIFIED && line.startsWith(UNIFIED_AFTER_HUNK_PREFIX)) break; + } + if (currentFormat == null) return false; // can't detect format + // check that contains at least one chunk + while (iterator.hasNext()) { + String line = iterator.next(); + if (currentFormat == DiffFormat.CONTEXT) { + if (ourContextAfterHunkStartPattern.matcher(line).matches()) return true; + } + else { + if (ourUnifiedHunkStartPattern.matcher(line).matches()) return true; + } + } + return false; + } } diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsApplicationSettings.java b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsApplicationSettings.java index 67fc5fa7bad3..322f0d482e03 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsApplicationSettings.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsApplicationSettings.java @@ -33,6 +33,7 @@ public class VcsApplicationSettings implements PersistentStateComponent