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; }