-
-
Notifications
You must be signed in to change notification settings - Fork 243
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Converted functionality to wrap paragraph from jython to java.
- Loading branch information
Showing
8 changed files
with
343 additions
and
292 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
77 changes: 77 additions & 0 deletions
77
...s/org.python.pydev.core/src/org/python/pydev/core/wrap_paragraph/AssistWrapParagraph.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
package org.python.pydev.core.wrap_paragraph; | ||
|
||
import java.io.File; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
import org.eclipse.jface.text.BadLocationException; | ||
import org.eclipse.jface.text.IDocument; | ||
import org.eclipse.jface.text.ITypedRegion; | ||
import org.eclipse.text.edits.ReplaceEdit; | ||
import org.python.pydev.core.IAssistProps; | ||
import org.python.pydev.core.IPyEdit; | ||
import org.python.pydev.core.IPythonNature; | ||
import org.python.pydev.core.MisconfigurationException; | ||
import org.python.pydev.core.docutils.ParsingUtils; | ||
import org.python.pydev.core.docutils.PySelection; | ||
import org.python.pydev.core.partition.PyPartitionScanner; | ||
import org.python.pydev.core.proposals.CompletionProposalFactory; | ||
import org.python.pydev.shared_core.code_completion.ICompletionProposalHandle; | ||
import org.python.pydev.shared_core.code_completion.IPyCompletionProposal; | ||
import org.python.pydev.shared_core.image.IImageCache; | ||
import org.python.pydev.shared_core.image.IImageHandle; | ||
import org.python.pydev.shared_core.image.UIConstants; | ||
import org.python.pydev.shared_core.partitioner.FastPartitioner; | ||
|
||
public class AssistWrapParagraph implements IAssistProps { | ||
|
||
private Paragrapher paragrapher; | ||
|
||
@Override | ||
public List<ICompletionProposalHandle> getProps(PySelection ps, IImageCache imageCache, File f, | ||
IPythonNature nature, IPyEdit edit, int offset) throws BadLocationException, MisconfigurationException { | ||
ReplaceEdit replaceEdit = paragrapher.getReplaceEdit(); | ||
|
||
String replacementString = replaceEdit.getText(); | ||
int replacementOffset = replaceEdit.getOffset(); | ||
int replacementLength = replaceEdit.getLength(); | ||
int cursorPosition = replaceEdit.getText().length(); | ||
String displayString = "Wrap text"; | ||
Object contextInformation = null; | ||
String additionalProposalInfo = null; | ||
int priority = IPyCompletionProposal.PRIORITY_DEFAULT; | ||
|
||
IImageHandle image = imageCache != null ? imageCache.get(UIConstants.COMPLETION_TEMPLATE) : null; | ||
|
||
ICompletionProposalHandle proposal = CompletionProposalFactory.get().createPyCompletionProposal( | ||
replacementString, replacementOffset, | ||
replacementLength, cursorPosition, image, displayString, | ||
contextInformation, additionalProposalInfo, priority); | ||
List<ICompletionProposalHandle> ret = new ArrayList<>(); | ||
ret.add(proposal); | ||
|
||
return ret; | ||
} | ||
|
||
@Override | ||
public boolean isValid(PySelection ps, String sel, IPyEdit edit, int offset) { | ||
IDocument doc = ps.getDoc(); | ||
ITypedRegion partition = ((FastPartitioner) PyPartitionScanner.checkPartitionScanner(doc)).getPartition(offset); | ||
|
||
// Only valid for strings or comments. | ||
if (!ParsingUtils.isStringContentType(partition.getType()) | ||
&& !ParsingUtils.isCommentContentType(partition.getType())) { | ||
return false; | ||
} | ||
|
||
int noCols = edit.getPrintMarginColums(); | ||
paragrapher = new Paragrapher(ps, noCols); | ||
String errorMsg = paragrapher.getValidErrorInPos(); | ||
if (errorMsg == null) { | ||
return true; | ||
} | ||
|
||
return false; | ||
} | ||
|
||
} |
211 changes: 211 additions & 0 deletions
211
plugins/org.python.pydev.core/src/org/python/pydev/core/wrap_paragraph/Paragrapher.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,211 @@ | ||
package org.python.pydev.core.wrap_paragraph; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.regex.Matcher; | ||
import java.util.regex.Pattern; | ||
|
||
import org.eclipse.jface.text.BadLocationException; | ||
import org.eclipse.jface.text.IDocument; | ||
import org.eclipse.text.edits.ReplaceEdit; | ||
import org.python.pydev.core.docutils.PySelection; | ||
import org.python.pydev.shared_core.string.TextSelectionUtils; | ||
|
||
public class Paragrapher { | ||
private PySelection selection; | ||
private IDocument document; | ||
|
||
private int offset; | ||
public int currentLineNo; | ||
|
||
private String currentLine; | ||
|
||
public String leadingString; | ||
public String mainText; | ||
|
||
public int offsetOfOriginalParagraph; | ||
public int lengthOfOriginalParagraph; | ||
|
||
private int numberOfLinesInDocument; | ||
public final String docDelimiter; | ||
private int noCols; | ||
private List<String> paragraph; | ||
|
||
private static Pattern pattern = Pattern | ||
.compile("(\\s*#\\s*|\\s*\"\"\"\\s*|\\s*'''\\s*|\\s*\"\\s*|\\s*'\\s*|\\s*)"); | ||
|
||
public Paragrapher(PySelection selection, int noCols) { | ||
this.noCols = noCols; | ||
this.selection = selection; | ||
this.document = selection.getDoc(); | ||
|
||
this.docDelimiter = TextSelectionUtils.getDelimiter(document); | ||
this.offset = selection.getAbsoluteCursorOffset(); | ||
this.currentLineNo = selection.getLineOfOffset(offset); | ||
|
||
this.currentLine = selection.getLine(currentLineNo); | ||
|
||
Matcher matcher = pattern.matcher(currentLine); | ||
if (matcher.find()) { | ||
this.leadingString = currentLine.substring(0, matcher.end()); | ||
this.mainText = currentLine.substring(matcher.end()); | ||
} | ||
|
||
this.offsetOfOriginalParagraph = 0; | ||
this.lengthOfOriginalParagraph = 0; | ||
|
||
this.numberOfLinesInDocument = document.getNumberOfLines(); | ||
} | ||
|
||
private String[] splitLine(String line) { | ||
Matcher matcher = pattern.matcher(line); | ||
if (matcher.find()) { | ||
String leadingString = line.substring(0, matcher.end()); | ||
String mainText = line.substring(matcher.end()); | ||
return new String[] { leadingString, mainText }; | ||
} | ||
return new String[] { "", line }; // Fallback if no match | ||
} | ||
|
||
public String getCurrentLine() { | ||
this.currentLine = selection.getLine(currentLineNo); | ||
this.mainText = splitLine(currentLine)[1]; | ||
return this.mainText; | ||
} | ||
|
||
public boolean previousLineIsInParagraph() { | ||
if (currentLineNo == 0) { | ||
return false; | ||
} | ||
|
||
String previousLine = selection.getLine(currentLineNo - 1); | ||
String[] previousLineParts = splitLine(previousLine); | ||
String leadingStringOfPreviousLine = previousLineParts[0]; | ||
String mainTextOfPreviousLine = previousLineParts[1]; | ||
|
||
if (mainTextOfPreviousLine.trim().isEmpty() || !leadingStringOfPreviousLine.equals(leadingString)) { | ||
String line = selection.getLine(currentLineNo); | ||
int lineEndsAt; | ||
try { | ||
lineEndsAt = selection.getEndLineOffset(currentLineNo); | ||
} catch (BadLocationException e) { | ||
return false; | ||
} | ||
offsetOfOriginalParagraph = lineEndsAt - line.length(); | ||
return false; | ||
} else { | ||
return true; | ||
} | ||
} | ||
|
||
public boolean nextLineIsInParagraph() { | ||
if (currentLineNo + 1 == numberOfLinesInDocument) { | ||
return false; | ||
} | ||
|
||
String nextLine = selection.getLine(currentLineNo + 1); | ||
String[] nextLineParts = splitLine(nextLine); | ||
String leadingStringOfNextLine = nextLineParts[0]; | ||
String mainTextOfNextLine = nextLineParts[1]; | ||
|
||
if (mainTextOfNextLine.trim().isEmpty() || !leadingStringOfNextLine.equals(leadingString)) { | ||
try { | ||
lengthOfOriginalParagraph = selection.getEndLineOffset(currentLineNo) - offsetOfOriginalParagraph; | ||
} catch (BadLocationException e) { | ||
return false; | ||
} | ||
return false; | ||
} else { | ||
return true; | ||
} | ||
} | ||
|
||
public String getValidErrorInPos() { | ||
// Start building a list of lines of text in paragraph | ||
paragraph = new ArrayList<>(); | ||
paragraph.add(this.getCurrentLine()); | ||
|
||
// Check if it's a docstring (""" or ' or ") | ||
boolean isDocstring = this.leadingString.contains("\"\"\"") || | ||
this.leadingString.contains("'") || | ||
this.leadingString.contains("\""); | ||
|
||
if (isDocstring) { | ||
return "Cannot rewrap docstrings"; | ||
} | ||
|
||
if (paragraph.get(0).trim().isEmpty()) { | ||
return "Currect selection is empty"; | ||
} | ||
|
||
// Don't wrap empty lines or docstrings | ||
int startingLineNo = this.currentLineNo; | ||
|
||
// Add the lines before the line containing the selection | ||
while (this.previousLineIsInParagraph()) { | ||
this.currentLineNo--; | ||
paragraph.add(0, this.getCurrentLine()); | ||
} | ||
|
||
// Add the lines after the line containing the selection | ||
this.currentLineNo = startingLineNo; | ||
while (this.nextLineIsInParagraph()) { | ||
this.currentLineNo++; | ||
paragraph.add(this.getCurrentLine()); | ||
} | ||
|
||
if (paragraph.size() == 1 && paragraph.get(0).length() < noCols - this.leadingString.length()) { | ||
return "Current selection cannot be wrapped"; | ||
} | ||
return null; | ||
} | ||
|
||
public ReplaceEdit getReplaceEdit() { | ||
// Rewrap the paragraph | ||
List<String> wrappedParagraph = new ArrayList<>(); | ||
|
||
for (String line : paragraph) { | ||
wrappedParagraph.add(line.trim() + " "); | ||
} | ||
|
||
String fullParagraph = String.join("", wrappedParagraph); | ||
List<String> rewrappedParagraph = wrapText(fullParagraph, noCols - this.leadingString.length()); | ||
|
||
// Add line terminators | ||
List<String> finalParagraph = new ArrayList<>(); | ||
for (String line : rewrappedParagraph) { | ||
finalParagraph.add(this.leadingString + line + this.docDelimiter); | ||
} | ||
|
||
// Adjust the last line to remove the delimiter | ||
if (!finalParagraph.isEmpty()) { | ||
String lastLine = finalParagraph.get(finalParagraph.size() - 1); | ||
lastLine = lastLine.replace(this.docDelimiter, ""); | ||
finalParagraph.set(finalParagraph.size() - 1, lastLine); | ||
} | ||
|
||
// Replace the original paragraph | ||
String newText = String.join("", finalParagraph); | ||
ReplaceEdit replaceEdit = new ReplaceEdit(this.offsetOfOriginalParagraph, this.lengthOfOriginalParagraph, | ||
newText); | ||
return replaceEdit; | ||
} | ||
|
||
public static List<String> wrapText(String text, int width) { | ||
// Mimic Python's textwrap functionality | ||
List<String> lines = new ArrayList<>(); | ||
int start = 0; | ||
while (start < text.length()) { | ||
int end = Math.min(text.length(), start + width); | ||
if (end < text.length() && !Character.isWhitespace(text.charAt(end))) { | ||
while (end > start && !Character.isWhitespace(text.charAt(end))) { | ||
end--; | ||
} | ||
} | ||
lines.add(text.substring(start, end).trim()); | ||
start = end; | ||
} | ||
return lines; | ||
} | ||
|
||
} |
Oops, something went wrong.