Editor is now able to find a commented line even if // was not written at its beginning. Fixes #3513

This commit is contained in:
Federico Fissore 2015-09-08 17:41:33 +02:00
parent 4cb72ceb9b
commit 96e0ee2a67
1 changed files with 102 additions and 1 deletions

View File

@ -1,5 +1,6 @@
package processing.app.syntax;
import org.fife.ui.rsyntaxtextarea.RSyntaxDocument;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextAreaEditorKit;
import org.fife.ui.rtextarea.RTextArea;
import org.fife.ui.rtextarea.RecordableTextAction;
@ -16,7 +17,8 @@ public class SketchTextAreaEditorKit extends RSyntaxTextAreaEditorKit {
private static final Action[] defaultActions = {
new DeleteNextWordAction(),
new DeleteLineToCursorAction(),
new SelectWholeLineAction()
new SelectWholeLineAction(),
new ToggleCommentAction()
};
@Override
@ -126,4 +128,103 @@ public class SketchTextAreaEditorKit extends RSyntaxTextAreaEditorKit {
}
public static class ToggleCommentAction extends RecordableTextAction {
public ToggleCommentAction() {
super(rstaToggleCommentAction);
}
@Override
public void actionPerformedImpl(ActionEvent e, RTextArea textArea) {
if (!textArea.isEditable() || !textArea.isEnabled()) {
UIManager.getLookAndFeel().provideErrorFeedback(textArea);
return;
}
RSyntaxDocument doc = (RSyntaxDocument) textArea.getDocument();
Element map = doc.getDefaultRootElement();
Caret c = textArea.getCaret();
int dot = c.getDot();
int mark = c.getMark();
int line1 = map.getElementIndex(dot);
int line2 = map.getElementIndex(mark);
int start = Math.min(line1, line2);
int end = Math.max(line1, line2);
org.fife.ui.rsyntaxtextarea.Token t = doc.getTokenListForLine(start);
int languageIndex = t != null ? t.getLanguageIndex() : 0;
String[] startEnd = doc.getLineCommentStartAndEnd(languageIndex);
if (startEnd == null) {
UIManager.getLookAndFeel().provideErrorFeedback(textArea);
return;
}
// Don't toggle comment on last line if there is no
// text selected on it.
if (start != end) {
Element elem = map.getElement(end);
if (Math.max(dot, mark) == elem.getStartOffset()) {
end--;
}
}
textArea.beginAtomicEdit();
try {
boolean add = getDoAdd(doc, map, start, end, startEnd);
for (line1 = start; line1 <= end; line1++) {
Element elem = map.getElement(line1);
handleToggleComment(elem, doc, startEnd, add);
}
} catch (BadLocationException ble) {
ble.printStackTrace();
UIManager.getLookAndFeel().provideErrorFeedback(textArea);
} finally {
textArea.endAtomicEdit();
}
}
private boolean getDoAdd(Document doc, Element map, int startLine, int endLine, String[] startEnd) throws BadLocationException {
boolean doAdd = false;
for (int i = startLine; i <= endLine; i++) {
Element elem = map.getElement(i);
int start = elem.getStartOffset();
String t = doc.getText(start, elem.getEndOffset() - start - 1).trim();
if (!t.startsWith(startEnd[0]) ||
(startEnd[1] != null && !t.endsWith(startEnd[1]))) {
doAdd = true;
break;
}
}
return doAdd;
}
private void handleToggleComment(Element elem, Document doc, String[] startEnd, boolean add) throws BadLocationException {
int start = elem.getStartOffset();
int end = elem.getEndOffset() - 1;
if (add) {
doc.insertString(start, startEnd[0], null);
if (startEnd[1] != null) {
doc.insertString(end + startEnd[0].length(), startEnd[1], null);
}
} else {
String text = doc.getText(start, elem.getEndOffset() - start - 1);
start += text.indexOf(startEnd[0]);
doc.remove(start, startEnd[0].length());
if (startEnd[1] != null) {
int temp = startEnd[1].length();
doc.remove(end - startEnd[0].length() - temp, temp);
}
}
}
@Override
public final String getMacroID() {
return rstaToggleCommentAction;
}
}
}