PY-13363 Django: not able to uncomment block comments with argument description
authorIlya.Kazakevich <Ilya.Kazakevich@jetbrains.com>
Mon, 20 Oct 2014 19:05:03 +0000 (23:05 +0400)
committerIlya.Kazakevich <Ilya.Kazakevich@jetbrains.com>
Mon, 20 Oct 2014 19:05:03 +0000 (23:05 +0400)
platform/core-api/src/com/intellij/lang/CustomUncommenter.java [new file with mode: 0644]
platform/lang-impl/src/com/intellij/codeInsight/generation/CommentByBlockCommentHandler.java

diff --git a/platform/core-api/src/com/intellij/lang/CustomUncommenter.java b/platform/core-api/src/com/intellij/lang/CustomUncommenter.java
new file mode 100644 (file)
index 0000000..bd2af1a
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.lang;
+
+import com.intellij.openapi.util.Couple;
+import com.intellij.openapi.util.TextRange;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+
+/**
+ * Commenter that knows how to uncomment commented block
+ *
+ * @author Ilya.Kazakevich
+ */
+public interface CustomUncommenter {
+
+  /**
+   * Finds commented block in selected text
+   *
+   * @param text selected text
+   * @return commented block (including comment prefix and suffix!) or null if text is not commented
+   */
+  @Nullable
+  TextRange findMaximumCommentedRange(@NotNull CharSequence text);
+
+
+  /**
+   * Returns couples each pointing to comment prefix and suffiix:
+   * [commentPrefix-start,commentPrefix-end] -- [commentSuffix-start,commentSuffix-end].
+   * If block has several commented areas you may provide all of them.
+   *
+   * @param text text with comments
+   * @return list of couples: [commentPrefix-start,commentPrefix-end], [commentSuffix-start,commentSuffix-end]
+   */
+  @NotNull
+  Collection<? extends Couple<TextRange>> getCommentRangesToDelete(@NotNull String text);
+}
index 6887ddfc0fbeaac7d10fbafb43eb19daba8cab5b..519d2de9efcab2e7fe95000659b8015dcf424841 100644 (file)
@@ -22,6 +22,7 @@ import com.intellij.codeInsight.actions.MultiCaretCodeInsightActionHandler;
 import com.intellij.featureStatistics.FeatureUsageTracker;
 import com.intellij.ide.highlighter.custom.CustomFileTypeLexer;
 import com.intellij.lang.Commenter;
+import com.intellij.lang.CustomUncommenter;
 import com.intellij.lang.Language;
 import com.intellij.lang.LanguageCommenters;
 import com.intellij.lexer.Lexer;
@@ -259,6 +260,9 @@ public class CommentByBlockCommentHandler extends MultiCaretCodeInsightActionHan
 
     final String prefix;
     final String suffix;
+    if (commenter instanceof CustomUncommenter) {
+      return ((CustomUncommenter)commenter).findMaximumCommentedRange(text);
+    }
 
     if (commenter instanceof SelfManagingCommenter) {
       SelfManagingCommenter selfManagingCommenter = (SelfManagingCommenter)commenter;
@@ -660,19 +664,36 @@ public class CommentByBlockCommentHandler extends MultiCaretCodeInsightActionHan
     //boolean endsProperly = CharArrayUtil.regionMatches(chars, range.getEndOffset() - commentSuffix.length(), commentSuffix);
     List<Couple<TextRange>> ranges = new ArrayList<Couple<TextRange>>();
 
-    int position = 0;
-    while (true) {
-      int start = getNearest(text, commentPrefix, position);
-      if (start == text.length()) {
-        break;
+
+    if (commenter instanceof CustomUncommenter) {
+      /**
+       * In case of custom uncommenter, we need to ask it for list of [commentOpen-start,commentOpen-end], [commentClose-start,commentClose-end]
+       * and shift if according to current offset
+       */
+      CustomUncommenter customUncommenter = (CustomUncommenter)commenter;
+      for (Couple<TextRange> coupleFromCommenter : customUncommenter.getCommentRangesToDelete(text)) {
+        TextRange openComment = coupleFromCommenter.first.shiftRight(startOffset);
+        TextRange closeComment = coupleFromCommenter.second.shiftRight(startOffset);
+        ranges.add(Couple.of(openComment, closeComment));
       }
-      position = start;
-      int end = getNearest(text, commentSuffix, position + commentPrefix.length()) + commentSuffix.length();
-      position = end;
-      Couple<TextRange> pair =
-        findCommentBlock(new TextRange(start + startOffset, end + startOffset), commentPrefix, commentSuffix);
-      ranges.add(pair);
     }
+    else {
+      // If commenter is not custom, we need to get this list by our selves
+      int position = 0;
+      while (true) {
+        int start = getNearest(text, commentPrefix, position);
+        if (start == text.length()) {
+          break;
+        }
+        position = start;
+        int end = getNearest(text, commentSuffix, position + commentPrefix.length()) + commentSuffix.length();
+        position = end;
+        Couple<TextRange> pair =
+          findCommentBlock(new TextRange(start + startOffset, end + startOffset), commentPrefix, commentSuffix);
+        ranges.add(pair);
+      }
+    }
+
 
     for (int i = ranges.size() - 1; i >= 0; i--) {
       Couple<TextRange> toDelete = ranges.get(i);