Esempio n. 1
0
  public RefactoringInfo(PyEdit edit, ITextSelection selection) throws MisconfigurationException {
    IEditorInput input = edit.getEditorInput();
    this.indentPrefs = edit.getIndentPrefs();
    IPythonNature localNature = edit.getPythonNature();

    if (input instanceof IFileEditorInput) {
      IFileEditorInput editorInput = (IFileEditorInput) input;
      this.sourceFile = editorInput.getFile();
      this.realFile = sourceFile != null ? sourceFile.getLocation().toFile() : null;
    } else {
      this.realFile = edit.getEditorFile();
    }

    if (localNature == null) {
      Tuple<IPythonNature, String> infoForFile = PydevPlugin.getInfoForFile(this.realFile);
      if (infoForFile != null && infoForFile.o1 != null) {
        localNature = infoForFile.o1;
      }
    }
    this.nature = localNature;

    this.doc = edit.getDocument();

    this.project = edit.getProject();
    versionProvider = this.nature;
    initInfo(selection);
  }
 /** This is the apply that should actually be called! */
 public void apply(ITextViewer viewer, char trigger, int stateMask, int offset) {
   IDocument document = viewer.getDocument();
   if (viewer instanceof PySourceViewer) {
     PySourceViewer pySourceViewer = (PySourceViewer) viewer;
     PyEdit pyEdit = pySourceViewer.getEdit();
     this.indentString = pyEdit.getIndentPrefs().getIndentationString();
   } else {
     // happens on compare editor
     this.indentString = new DefaultIndentPrefs().getIndentationString();
   }
   // If the completion is applied with shift pressed, do a local import. Note that the user is
   // only actually
   // able to do that if the popup menu is focused (i.e.: request completion and do a tab to focus
   // it, instead
   // of having the focus on the editor and just pressing up/down).
   if ((stateMask & SWT.SHIFT) != 0) {
     this.setAddLocalImport(true);
   }
   apply(document, trigger, stateMask, offset);
 }
  /**
   * 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;
  }