1
0
mirror of https://github.com/arduino/Arduino.git synced 2024-11-28 09:24:14 +01:00

Compare commits

...

5 Commits

Author SHA1 Message Date
Ricardo JL Rufino
fd2f214da1
Merge 0918a5b0b4 into 89539b1131 2022-11-06 23:40:42 +09:00
Ricardo JL Rufino
0918a5b0b4 Avoid erros on format multi-line comments, add Tests 2020-05-21 17:19:49 -03:00
Ricardo JL Rufino
cf81fdcbee format selection using AStyle control tags 2020-05-20 19:55:11 -03:00
Ricardo JL Rufino
7efb118156 fix code formatting 2020-05-14 10:59:21 -03:00
Ricardo JL Rufino
2ba0124871 [editor] Allow formatting only the selection 2020-05-14 01:31:22 -03:00
4 changed files with 284 additions and 9 deletions

View File

@ -29,16 +29,21 @@
package cc.arduino.packages.formatter;
import static processing.app.I18n.tr;
import processing.app.Base;
import processing.app.BaseNoGui;
import processing.app.Editor;
import processing.app.helpers.FileUtils;
import processing.app.syntax.SketchTextArea;
import processing.app.tools.Tool;
import java.io.File;
import java.io.IOException;
import static processing.app.I18n.tr;
import java.util.regex.Pattern;
import javax.swing.text.BadLocationException;
import org.fife.ui.rsyntaxtextarea.RSyntaxDocument;
import org.fife.ui.rsyntaxtextarea.Token;
public class AStyle implements Tool {
@ -76,19 +81,99 @@ public class AStyle implements Tool {
@Override
public void run() {
String originalText = editor.getCurrentTab().getText();
String formattedText = aStyleInterface.AStyleMain(originalText, formatterConfiguration);
if (formattedText.equals(originalText)) {
editor.statusNotice(tr("No changes necessary for Auto Format."));
return;
SketchTextArea textArea = editor.getCurrentTab().getTextArea();
String originalText = textArea.getSelectedText();
// If no selection use all file
if (originalText == null || originalText.isEmpty()) {
String formattedText = aStyleInterface.AStyleMain(textArea.getText(), formatterConfiguration);
editor.getCurrentTab().setText(formattedText);
} else {
try {
// apply indentation control keywords.
String FORMAT_ON = "\n// *INDENT-ON* DYN\n";
String FORMAT_OFF = "\n// *INDENT-OFF* DYN\n";
RSyntaxDocument content = (RSyntaxDocument) textArea.getDocument();
textArea.beginAtomicEdit();
int selStart = editor.getCurrentTab().getSelectionStart();
int selEnd = editor.getCurrentTab().getSelectionStop();
int lineStart = textArea.getLineOfOffset(selStart);
int lineEnd = textArea.getLineOfOffset(selEnd);
// Calculate offsets from begin and end of each line.
int fristLineOffset = textArea.getLineStartOffset(lineStart);
int lastLineOffset = textArea.getLineEndOffset(lineEnd);
// Avoid multi-line comments
fristLineOffset = navigateOffComments(textArea, fristLineOffset); // try caech (invalid selection)
lastLineOffset = navigateOffComments(textArea, lastLineOffset); // try caech (invalid selection)
// inserts change the length, use this to calculate new positios.
int offLength = FORMAT_OFF.length();
int onLength = FORMAT_ON.length();
content.insertString(0, FORMAT_OFF, null);
content.insertString(fristLineOffset + offLength, FORMAT_ON, null);
content.insertString(lastLineOffset + offLength + onLength, FORMAT_OFF,null);
originalText = content.getText(0, content.getLength());
String formattedText = aStyleInterface.AStyleMain(originalText, formatterConfiguration);
// Remove format tags
formattedText = formattedText.replaceAll(Pattern.quote(FORMAT_OFF), "");
formattedText = formattedText.replaceAll(Pattern.quote(FORMAT_ON), "");
textArea.setText(formattedText);
textArea.select(selStart, selStart);
} catch (BadLocationException e) {
editor.statusNotice(tr("Auto Format Error") + ": " + e.getLocalizedMessage());
e.printStackTrace();
return;
} finally {
textArea.endAtomicEdit();
}
}
editor.getCurrentTab().setText(formattedText);
// mark as finished
editor.statusNotice(tr("Auto Format finished."));
}
private int navigateOffComments(SketchTextArea textArea, int offset) throws BadLocationException {
Token token = textArea.modelToToken(offset);
// if line is a multiline comment, go back !!
if (token != null && token.getType() == Token.COMMENT_MULTILINE) {
int lineStart = textArea.getLineOfOffset(offset);
token = textArea.getTokenListForLine(lineStart);
while (token.getType() == Token.COMMENT_MULTILINE) {
if (lineStart == 0)
break;
token = token.getNextToken();
if (token == null)
token = textArea.getTokenListForLine(--lineStart);
}
return token.getOffset();
} else {
return offset;
}
}
@Override
public String getMenuTitle() {

View File

@ -0,0 +1,174 @@
/*
* This file is part of Arduino.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package processing.app;
import org.fest.swing.fixture.JMenuItemFixture;
import org.junit.Test;
import processing.app.helpers.SketchTextAreaFixture;
import static org.junit.Assert.assertEquals;
public class AutoformatSelectionTest extends AbstractGUITest {
private static String orig = "/**\n" +
" *Docs..\n" +
" */\n" +
"void loop() {\n" +
" // LED ON\n" +
"digitalWrite(LED_BUILTIN, HIGH);\n" +
"if (true) {\n" +
" delay( 1000)\n" +
"};\n" +
" digitalWrite(LED_BUILTIN, LOW);\n" +
" if (true) {delay( 1000 )}; // <<< UGLY FORMATTING\n" +
"}";
@Test
public void testSuite() {
selectIfMultilineCorrectSel();
selectIfMultilineCorrectPartialSel();
selectIfMultilineDocs();
selectIfSinglelineDocs();
}
/**
* select all if block
*/
public void selectIfMultilineCorrectSel() {
String espected = "/**\n" +
" *Docs..\n" +
" */\n" +
"void loop() {\n" +
" // LED ON\n" +
"digitalWrite(LED_BUILTIN, HIGH);\n" +
" if (true) {\n" +
" delay( 1000)\n" +
" };\n" +
" digitalWrite(LED_BUILTIN, LOW);\n" +
" if (true) {delay( 1000 )}; // <<< UGLY FORMATTING\n" +
"}";
validateFormat(78, 109, orig, espected);
}
/**
* selection starts in if (|true) and goto '}'
* expected: format entry block
*/
public void selectIfMultilineCorrectPartialSel() {
String espected = "/**\n" +
" *Docs..\n" +
" */\n" +
"void loop() {\n" +
" // LED ON\n" +
"digitalWrite(LED_BUILTIN, HIGH);\n" +
" if (true) {\n" +
" delay( 1000)\n" +
" };\n" +
" digitalWrite(LED_BUILTIN, LOW);\n" +
" if (true) {delay( 1000 )}; // <<< UGLY FORMATTING\n" +
"}";
validateFormat(81, 109, orig, espected);
}
/**
* selection starts in multiple docs /** *\/
* expected: format entry block
*/
public void selectIfMultilineDocs() {
String espected = "/**\n" +
" Docs..\n" +
"*/\n" +
"void loop() {\n" +
" // LED ON\n" +
" digitalWrite(LED_BUILTIN, HIGH);\n" +
"if (true) {\n" +
" delay( 1000)\n" +
"};\n" +
" digitalWrite(LED_BUILTIN, LOW);\n" +
" if (true) {delay( 1000 )}; // <<< UGLY FORMATTING\n" +
"}";
validateFormat(9, 51, orig, espected);
}
/**
* selection starts in single line coment // LED |ON
* expected: format comment
*/
public void selectIfSinglelineDocs() {
String espected = "/**\n" +
" *Docs..\n" +
" */\n" +
"void loop() {\n" +
" // LED ON\n" +
" digitalWrite(LED_BUILTIN, HIGH);\n" +
"if (true) {\n" +
" delay( 1000)\n" +
"};\n" +
" digitalWrite(LED_BUILTIN, LOW);\n" +
" if (true) {delay( 1000 )}; // <<< UGLY FORMATTING\n" +
"}";
validateFormat(42, 56, orig, espected);
}
public SketchTextAreaFixture validateFormat(int selStart, int selEnd, String orig, String espected) {
JMenuItemFixture menuToolsAutoFormat = window.menuItem("menuToolsAutoFormat");
menuToolsAutoFormat.requireEnabled();
SketchTextAreaFixture editor = window.textArea("editor");
editor.setText(orig);
editor.select(selStart, selEnd); // select frist if
menuToolsAutoFormat.click();
assertEquals(espected, editor.getText());
return editor;
}
}

View File

@ -81,6 +81,17 @@ public class SketchTextAreaComponentDriver extends JComponentDriver {
});
}
public SketchTextArea select(final SketchTextArea target, int selectionStart, int selectionEnd) {
return GuiActionRunner.execute(new GuiQuery<SketchTextArea>() {
protected SketchTextArea executeInEDT() {
target.select(selectionStart, selectionEnd);
return target;
}
});
}
public Integer getCaretPosition(final SketchTextArea target) {
focusAndWaitForFocusGain(target);

View File

@ -71,6 +71,11 @@ public class SketchTextAreaFixture extends ComponentFixture {
driver.selectAll((SketchTextArea) target);
return this;
}
public SketchTextAreaFixture select(int selectionStart, int selectionEnd) {
driver.select((SketchTextArea) target, selectionStart, selectionEnd);
return this;
}
public int getCaretPosition() {
return driver.getCaretPosition((SketchTextArea) target);