diff --git a/.gitignore b/.gitignore index 1ff22582a..c3aae4577 100644 --- a/.gitignore +++ b/.gitignore @@ -14,13 +14,17 @@ hardware/arduino/bootloaders/caterina_LUFA/Caterina.elf hardware/arduino/bootloaders/caterina_LUFA/Caterina.eep hardware/arduino/bootloaders/caterina_LUFA/.dep/ build/windows/work/ +build/windows/jre.zip +build/windows/libastylej* build/windows/arduino-*.zip build/windows/dist/gcc-*.tar.gz build/macosx/arduino-*.zip build/macosx/dist/gcc-*.tar.gz +build/macosx/libastylej* build/linux/work/ build/linux/dist/*.tar.gz build/linux/*.tgz +build/linux/libastylej* test-bin *.iml .idea diff --git a/app/src/cc/arduino/packages/formatter/AStyle.java b/app/src/cc/arduino/packages/formatter/AStyle.java new file mode 100644 index 000000000..54d51dfde --- /dev/null +++ b/app/src/cc/arduino/packages/formatter/AStyle.java @@ -0,0 +1,68 @@ +package cc.arduino.packages.formatter; + +import processing.app.Base; +import processing.app.Editor; +import processing.app.helpers.FileUtils; +import processing.app.tools.Tool; + +import java.io.File; +import java.io.IOException; + +import static processing.app.I18n._; + +public class AStyle implements Tool { + + private static String FORMATTER_CONF = "formatter.conf"; + + private final AStyleInterface aStyleInterface; + private final String formatterConfiguration; + private Editor editor; + + public AStyle() { + this.aStyleInterface = new AStyleInterface(); + File customFormatterConf = Base.getSettingsFile(FORMATTER_CONF); + File defaultFormatterConf = new File(Base.getContentFile("lib"), FORMATTER_CONF); + + File formatterConf; + if (customFormatterConf.exists()) { + formatterConf = customFormatterConf; + } else { + formatterConf = defaultFormatterConf; + } + String formatterConfiguration = ""; + + try { + formatterConfiguration = FileUtils.readFileToString(formatterConf); + } catch (IOException e) { + // noop + } + this.formatterConfiguration = formatterConfiguration; + } + + @Override + public void init(Editor editor) { + this.editor = editor; + } + + @Override + public void run() { + String originalText = editor.getText(); + String formattedText = aStyleInterface.AStyleMain(originalText, formatterConfiguration); + + if (formattedText.equals(originalText)) { + editor.statusNotice(_("No changes necessary for Auto Format.")); + return; + } + + editor.setText(formattedText); + editor.getSketch().setModified(true); + // mark as finished + editor.statusNotice(_("Auto Format finished.")); + } + + @Override + public String getMenuTitle() { + return _("Auto Format"); + } + +} diff --git a/app/src/cc/arduino/packages/formatter/AStyleInterface.java b/app/src/cc/arduino/packages/formatter/AStyleInterface.java new file mode 100644 index 000000000..8c08c6446 --- /dev/null +++ b/app/src/cc/arduino/packages/formatter/AStyleInterface.java @@ -0,0 +1,54 @@ +package cc.arduino.packages.formatter; + +import processing.app.Base; + +import java.io.File; + +public class AStyleInterface { + + static { + File astyleLib = new File(Base.getContentFile("lib"), System.mapLibraryName("astylej")); + String astylePath = astyleLib.getAbsolutePath(); + try { + System.load(astylePath); + } catch (UnsatisfiedLinkError e) { + e.printStackTrace(); + System.out.println(e.getMessage()); + System.out.println("Cannot load native library " + astylePath); + System.out.println("The program has terminated!"); + System.exit(1); + } + } + + /** + * Calls the AStyleMain function in Artistic Style. + * + * @param textIn A string containing the source code to be formatted. + * @param options A string of options to Artistic Style. + * @return A String containing the formatted source from Artistic Style. + */ + public native String AStyleMain(String textIn, String options); + + /** + * Calls the AStyleGetVersion function in Artistic Style. + * + * @return A String containing the version number of Artistic Style. + */ + public native String AStyleGetVersion(); + + /** + * Error handler for messages from Artistic Style. + * This method is called only if there are errors when AStyleMain is called. + * This is for debugging and there should be no errors when the calling + * parameters are correct. + * Changing the method name requires changing Artistic Style. + * Signature: (ILjava/lang/String;)V. + * + * @param errorNumber The error number from Artistic Style. + * @param errorMessage The error message from Artistic Style. + */ + private void ErrorHandler(int errorNumber, String errorMessage) { + System.out.println("AStyle error " + String.valueOf(errorNumber) + " - " + errorMessage); + } + +} diff --git a/app/src/processing/app/Editor.java b/app/src/processing/app/Editor.java index 284a39148..0929092f7 100644 --- a/app/src/processing/app/Editor.java +++ b/app/src/processing/app/Editor.java @@ -907,7 +907,7 @@ public class Editor extends JFrame implements RunnerListener { protected JMenu addInternalTools(JMenu menu) { JMenuItem item; - item = createToolMenuItem("processing.app.tools.AutoFormat"); + item = createToolMenuItem("cc.arduino.packages.formatter.AStyle"); int modifiers = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); item.setAccelerator(KeyStroke.getKeyStroke('T', modifiers)); menu.add(item); diff --git a/app/src/processing/app/helpers/FileUtils.java b/app/src/processing/app/helpers/FileUtils.java index f35a14918..bf562a80b 100644 --- a/app/src/processing/app/helpers/FileUtils.java +++ b/app/src/processing/app/helpers/FileUtils.java @@ -1,9 +1,6 @@ package processing.app.helpers; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; +import java.io.*; import java.util.Arrays; import java.util.List; import java.util.Random; @@ -170,4 +167,25 @@ public class FileUtils { public static boolean isSCCSOrHiddenFile(File file) { return file.isHidden() || file.getName().charAt(0) == '.' || (file.isDirectory() && SOURCE_CONTROL_FOLDERS.contains(file.getName())); } + + public static String readFileToString(File file) throws IOException { + BufferedReader reader = null; + try { + reader = new BufferedReader(new InputStreamReader(new FileInputStream(file))); + StringBuilder sb = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + sb.append(line).append("\n"); + } + return sb.toString(); + } finally { + if (reader != null) { + try { + reader.close(); + } catch (IOException e) { + // noop + } + } + } + } } diff --git a/build/build.xml b/build/build.xml index 6eddc3de9..e9e023b2d 100644 --- a/build/build.xml +++ b/build/build.xml @@ -259,6 +259,11 @@ + + + + + @@ -470,6 +475,11 @@ + + + + + @@ -485,6 +495,7 @@ + @@ -659,6 +670,10 @@ + + + + diff --git a/build/shared/lib/formatter.conf b/build/shared/lib/formatter.conf new file mode 100644 index 000000000..255716d1d --- /dev/null +++ b/build/shared/lib/formatter.conf @@ -0,0 +1,28 @@ +# This configuration file contains a selection of the available options provided by the formatting tool "Artistic Style" +# http://astyle.sourceforge.net/astyle.html +# +# If you wish to change them, don't edit this file. +# Instead, copy it in the same folder of file "preferences.txt" and modify the copy. This way, you won't lose your custom formatter settings when upgrading the IDE +# If you don't know where file preferences.txt is stored, open the IDE, File -> Preferences and you'll find a link + +# 2 spaces indentation +indent=spaces=2 + +# also indent macros +indent-preprocessor + +# indent classes, switches (and cases), comments starting at column 1 +indent-classes +indent-switches +indent-cases +indent-col1-comments + +# put a space around operators +pad-oper + +# put a space after if/for/while +pad-header + +# if you like one-liners, keep them +keep-one-line-statements +