Beispiel #1
0
  /** Constructor to be used only in tests! */
  public RefactoringInfo(
      IDocument document, ITextSelection selection, IGrammarVersionProvider versionProvider) {
    this.sourceFile = null;
    this.nature = null;
    this.versionProvider = versionProvider;
    this.doc = document;

    this.indentPrefs =
        PydevPlugin.getDefault() == null
            ? new TestIndentPrefs(document.get().indexOf('\t') < 0, 4)
            : DefaultIndentPrefs.get();

    initInfo(selection);
  }
  /**
   * Recalculates indent prefixes based upon preferences
   *
   * <p>we hold onto the same array SourceViewer has, and write directly into it. This is because
   * there is no way to tell SourceViewer that indent prefixes have changed. And we need this
   * functionality when user resets the tabs vs. spaces preference
   */
  public void resetIndentPrefixes() {
    IPreferenceStore prefs = PydevPlugin.getDefault().getPreferenceStore();
    int tabWidth = DefaultIndentPrefs.getStaticTabWidth();
    FastStringBuffer spaces = new FastStringBuffer(8);

    for (int i = 0; i < tabWidth; i++) {
      spaces.append(" ");
    }

    boolean spacesFirst =
        prefs.getBoolean(PydevEditorPrefs.SUBSTITUTE_TABS)
            && !(getPyAutoIndentStrategy()).getIndentPrefs().getForceTabs();

    if (spacesFirst) {
      indentPrefixes[0] = spaces.toString();
      indentPrefixes[1] = "\t";
    } else {
      indentPrefixes[0] = "\t";
      indentPrefixes[1] = spaces.toString();
    }
  }
 /**
  * TabWidth is defined inside pydev preferences.
  *
  * <p>Python uses its own tab width, since I think that its standard is 8
  */
 public int getTabWidth(ISourceViewer sourceViewer) {
   return DefaultIndentPrefs.getStaticTabWidth();
 }
  /**
   * Performs the action with a given PySelection
   *
   * @param ps Given PySelection
   * @return boolean The success or failure of the action
   */
  public int perform(PySelection ps) {
    // What we'll be replacing the selected text with
    FastStringBuffer strbuf = new FastStringBuffer();

    try {
      // discover 1st line that starts the block comment
      int i;
      int startLineIndex = getStartIndex(ps);
      int endLineIndex = getEndIndex(ps);
      if (startLineIndex == -1 || endLineIndex == -1) {
        if (startLineIndex == -1 && endLineIndex == -1) {
          return -1;
        } else if (startLineIndex == -1) {
          startLineIndex = endLineIndex;
        } else {
          endLineIndex = startLineIndex;
        }
      }

      // For each line, uncomment it
      for (i = startLineIndex; i <= endLineIndex; i++) {
        boolean addDelim = true;
        String spacesBefore = "";
        String line = ps.getLine(i);
        int lineLen = line.length();
        for (int j = 0; j < lineLen; j++) {
          char c = line.charAt(j);
          if (c == '#') {
            // ok, it starts with # (so, remove the whitespaces before it)
            if (j > 0) {
              spacesBefore = line.substring(0, j);
            }
            line = line.substring(j);
            break;
          } else {
            if (!Character.isWhitespace(c)) {
              break;
            }
          }
        }
        if (line.startsWith("#")) {
          line = line.substring(1);
        }

        // get the chars used in block-comments
        AbstractBlockCommentAction[] acts =
            new AbstractBlockCommentAction[] {
              new PyAddSingleBlockComment(), new PyAddBlockComment()
            };
        HashSet<Character> chars = new HashSet<Character>();
        for (int j = 0; j < acts.length; j++) {
          AbstractBlockCommentAction action = acts[j];
          chars.add(action.getColsAndChar().o2);
        }

        if (line.length() > 0) {
          boolean removedChar = false;
          char lastChar = '\0';
          for (int j = 0; j < line.length(); j++) {
            lastChar = line.charAt(j);
            if (!chars.contains(lastChar)) {
              break;
            } else {
              removedChar = true;
              line = line.substring(1);
              j--;
            }
          }
          if (line.length() == 0 && removedChar) {
            addDelim = false;
          }
          if (removedChar && lastChar == ' ') {
            line = line.substring(1);
          }
        }

        if (addDelim) {
          strbuf.append(spacesBefore);
          strbuf.append(line);
          String lineDelimiter = ps.getDoc().getLineDelimiter(i);
          if (lineDelimiter != null) {
            strbuf.append(lineDelimiter);
          }
        }
      }

      // Ok, at this point things should be correct, but make sure than on uncomment,
      // the code goes to a proper indent position (remove spaces we may have added when creating a
      // block).
      String string = strbuf.toString();
      List<String> lines = StringUtils.splitInLines(string);
      Tuple<Integer, String> posAndLine = new Tuple<Integer, String>(-1, "");
      for (String line : lines) {
        int firstCharPosition = PySelection.getFirstCharPosition(line);
        if (firstCharPosition < posAndLine.o1 || posAndLine.o1 < 0) {
          posAndLine.o1 = firstCharPosition;
          posAndLine.o2 = line;
        }
      }
      if (posAndLine.o1 > 0) {
        final String sub = posAndLine.o2.substring(0, posAndLine.o1);
        if (sub.endsWith(
            " ")) { // If it ends with a tab, we won't change anything (only spaces are removed --
                    // which we may have introduced)
          boolean allEqual = true;
          for (String line : lines) {
            if (!line.startsWith(sub)) {
              allEqual = false;
              break;
            }
          }
          if (allEqual) {
            if (sub.startsWith("\t")) {
              // Tabs based indent: remove any ending spaces (and at this point we know a string
              // ends with a space)
              int j;
              for (j = sub.length() - 1; j >= 0; j--) {
                char c = sub.charAt(j);
                if (c != ' ') {
                  j++;
                  break;
                }
              }
              String newSub = sub.substring(0, j);
              strbuf.clear();
              for (String line : lines) {
                strbuf.append(newSub);
                strbuf.append(line.substring(sub.length()));
              }

            } else {
              IIndentPrefs indentPrefs;
              if (targetEditor instanceof PyEdit) {
                PyEdit pyEdit = (PyEdit) targetEditor;
                indentPrefs = pyEdit.getIndentPrefs();
              } else {
                indentPrefs = DefaultIndentPrefs.get();
              }

              String indentationString = indentPrefs.getIndentationString();

              int subLen = sub.length();
              int indentLen = indentationString.length();
              int mod = subLen % indentLen;
              if (mod != 0) {
                String substring = sub.substring(subLen - mod, subLen);
                boolean onlyWhitespaces = true;
                for (int k = 0; k < substring.length(); k++) {
                  if (substring.charAt(k) != ' ') {
                    onlyWhitespaces = false;
                    break;
                  }
                }
                if (onlyWhitespaces) {
                  String newSub = sub.substring(0, subLen - mod);
                  strbuf.clear();
                  for (String line : lines) {
                    strbuf.append(newSub);
                    strbuf.append(line.substring(sub.length()));
                  }
                }
              }
            }
          }
        }
      }

      // Replace the text with the modified information
      int startLineOffset = ps.getLineOffset(startLineIndex);
      int endLineOffset = ps.getEndLineOffset(endLineIndex);
      String endLineDelimiter = ps.getDoc().getLineDelimiter(endLineIndex);
      if (endLineDelimiter != null) {
        endLineOffset += endLineDelimiter.length();
      }
      String str = strbuf.toString();
      ps.getDoc().replace(startLineOffset, endLineOffset - startLineOffset, str);
      return startLineOffset + str.length();
    } catch (Exception e) {
      beep(e);
    }

    // In event of problems, return false
    return -1;
  }