├── .gitignore
├── .gitmodules
├── CLionArduinoPlugin.zip
├── META-INF
└── plugin.xml
├── README.md
├── lib
├── commons-io-2.4-javadoc.jar
├── commons-io-2.4-sources.jar
└── commons-io-2.4.jar
└── src
└── io
└── github
└── francoiscambell
└── clionarduinoplugin
├── ArduinoSketchFileCreator.java
├── CMakeListsEditor.java
├── actions
├── NewArduinoProject.java
└── NewSketchFile.java
├── components
└── ArduinoFileTypeRegistration.java
├── resources
├── ArduinoToolchainFiles.java
├── Strings.java
└── icons
│ ├── ArduinoIcon.java
│ ├── Arduino_Logo.png
│ ├── Arduino_Logo@2x.png
│ ├── Arduino_Logo@2x_dark.png
│ └── Arduino_Logo_dark.png
└── wizards
├── NewArduinoProjectForm.java
└── NewArduinoProjectWizard.java
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | ### JetBrains template
3 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion
4 |
5 | *.iml
6 |
7 | ## Directory-based project format:
8 | .idea/
9 | # if you remove the above rule, at least ignore the following:
10 |
11 | # User-specific stuff:
12 | # .idea/workspace.xml
13 | # .idea/tasks.xml
14 | # .idea/dictionaries
15 |
16 | # Sensitive or high-churn files:
17 | # .idea/dataSources.ids
18 | # .idea/dataSources.xml
19 | # .idea/sqlDataSources.xml
20 | # .idea/dynamic.xml
21 | # .idea/uiDesigner.xml
22 |
23 | # Gradle:
24 | # .idea/gradle.xml
25 | # .idea/libraries
26 |
27 | # Mongo Explorer plugin:
28 | # .idea/mongoSettings.xml
29 |
30 | ## File-based project format:
31 | *.ipr
32 | *.iws
33 |
34 | ## Plugin-specific files:
35 |
36 | # IntelliJ
37 | /out/
38 |
39 | # mpeltonen/sbt-idea plugin
40 | .idea_modules/
41 |
42 | # JIRA plugin
43 | atlassian-ide-plugin.xml
44 |
45 | # Crashlytics plugin (for Android Studio and IntelliJ)
46 | com_crashlytics_export_strings.xml
47 | crashlytics.properties
48 | crashlytics-build.properties
49 |
50 | /*.zip
51 |
52 | *.DS_Store
53 |
54 |
55 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "src/io/github/francoiscambell/clionarduinoplugin/resources/arduino-cmake"]
2 | path = src/io/github/francoiscambell/clionarduinoplugin/resources/arduino-cmake
3 | url = git://github.com/francoiscampbell/arduino-cmake.git
4 | ignore = dirty
5 |
--------------------------------------------------------------------------------
/CLionArduinoPlugin.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rjuang/CLionArduinoPlugin/0932733d5ffd952776e2a39922f88dcb174c3420/CLionArduinoPlugin.zip
--------------------------------------------------------------------------------
/META-INF/plugin.xml:
--------------------------------------------------------------------------------
1 |
3 |
5 |
6 |
7 |
8 |
9 |
12 |
13 |
14 |
15 |
17 |
18 |
19 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
33 |
34 |
37 | ]>
38 |
39 | io.github.francoiscambell.clionarduinoplugin2017
40 | Arduino
41 | 1.2.3
42 | Francois Campbell
43 |
44 | CLion Arduino Plugin v2
46 |
47 | This is a branch of the original CLionArduinoPlugin written by Francois Cambell to resolve crash issues.
48 |
49 | Branched Repo |
50 | Original Repo |
51 | Issues
52 |
53 |
54 | This is a plugin that integrates Arduino CMake into the IDE.
55 |
56 |
57 | The current features are to create an Arduino CMake project in one click, and to create new sketch files.
58 |
59 |
60 | Future features are to add menu option to easily change the board type, port number, import existing Arduino projects, etc.
61 | ]]>
62 |
63 | 1.2.3
65 |
66 | - Fixed to run on CLion 2016.3.2 and 2017.2.1
67 | - Updating plugin xml to create a branch that can be uploaded to Jetbrains plugin repo.
68 |
69 | 1.2.2
70 |
71 | - Fixed .ino and .pde files not refactorable. Increased compatibility for Servo library
72 |
73 | 1.2.1
74 |
75 | - Re-compiled for Java 6
76 |
77 | 1.2.0
78 |
79 | - Added new project creation to Welcome Screen and File menu
80 |
81 | 1.1.0
82 |
83 | - Compatiblity with Arduino SDK 1.6 on Mac OS X
84 |
85 | 1.0.2
86 |
87 | - Removed Groovy runtime, no longer necessary
88 |
89 | 1.0.1
90 |
91 | - Fixed organization
92 |
93 | 1.0
94 |
95 | - Convert a project to Arduino CMake. This replaces CMakeLists.txt with a default one, deletes the default
96 | main.cpp file, copies in the Arduino CMake toolchain files, and deletes the build direcory to start
97 | fresh
98 |
99 | - Associates .ino and .pde files as C++ source, so you get syntax highlighting and prediction, etc.
100 | - Create a new sketch file in any directory. If you omit the extension, it will add .ino automatically
101 |
102 | - Adds import for Arduino.h to all newly created sketch files to enable code completion
103 | - Compiled with Java 6 for compatibility with OS X out of the box
104 |
105 | ]]>
106 |
107 |
108 |
109 |
110 |
111 |
113 | com.intellij.modules.clion
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 | io.github.francoiscambell.clionarduinoplugin.components.ArduinoFileTypeRegistration
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
140 |
141 |
142 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | #CLion Arduino Plugin
2 |
3 | This is a JetBrains CLion plugin that integrates [Arduino CMake](https://github.com/francoiscampbell/arduino-cmake) into the IDE.
4 |
5 | The current features are to create an Arduino CMake project in one click, and to create new sketch files.
6 |
7 | For those asking how to upload, you need to specify the serial port in the CMakeLists.txt file. For example:
8 |
9 | set(${CMAKE_PROJECT_NAME}_BOARD uno)
10 | set(${CMAKE_PROJECT_NAME}_PORT /dev/ttys0)
11 |
12 | This will create the 'upload' configuration in your Run Configurations and you can click the Run button or use the keyboard shortcut to upload.
13 |
14 | Future features are to add menu option to easily change the board type, port number, import existing Arduino projects, etc.
15 |
16 | ## Update on status:
17 | It seems that arduino-cmake (the backing plugin) development has pretty much stalled, which is the root cause of most of the issues here, so I've got my own fork and I've tried to implement most of the fixes from previous forks of the project, which are also mostly dead. This project was just an exercise in making a JetBrains plugin that turned out well, but I don't have a lot of free time on my hands to do this though, what with full-time university and what not, so I can't give a definite date on what will be fixed when, but I will make an effort to get it done.
18 |
19 | ## Release Notes
20 |
21 | **1.2.2**
22 |
23 | * Fixed .ino and .pde files not refactorable. Increased compatibility for Servo library
24 |
25 | **1.2.1**
26 |
27 | * Re-compiled for Java 6
28 |
29 | **1.2.0**
30 |
31 | * Added new project creation to Welcome Screen and File menu
32 |
33 | **1.1.0**
34 |
35 | * Compatiblity with Arduino SDK 1.6 on Mac OS X
36 |
37 | **1.0.2**
38 |
39 | * Removed Groovy runtime, no longer necessary
40 |
41 | **1.0.1**
42 |
43 | * Fixed organization
44 |
45 | **1.0**
46 |
47 | * Convert a project to Arduino CMake. This replaces CMakeLists.txt with a default one, deletes the default main.cpp file, copies in the Arduino CMake toolchain files, and deletes the build direcory to start fresh
48 | * Associates .ino and .pde files as C++ source, so you get syntax highlighting and prediction, etc.
49 | * Create a new sketch file in any directory. If you omit the extension, it will add .ino automatically
50 | * Adds import for Arduino.h to all newly created sketch files to enable code completion
51 | * Compiled with Java 6 for compatibility with OS X out of the box
52 |
--------------------------------------------------------------------------------
/lib/commons-io-2.4-javadoc.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rjuang/CLionArduinoPlugin/0932733d5ffd952776e2a39922f88dcb174c3420/lib/commons-io-2.4-javadoc.jar
--------------------------------------------------------------------------------
/lib/commons-io-2.4-sources.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rjuang/CLionArduinoPlugin/0932733d5ffd952776e2a39922f88dcb174c3420/lib/commons-io-2.4-sources.jar
--------------------------------------------------------------------------------
/lib/commons-io-2.4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rjuang/CLionArduinoPlugin/0932733d5ffd952776e2a39922f88dcb174c3420/lib/commons-io-2.4.jar
--------------------------------------------------------------------------------
/src/io/github/francoiscambell/clionarduinoplugin/ArduinoSketchFileCreator.java:
--------------------------------------------------------------------------------
1 | package io.github.francoiscambell.clionarduinoplugin;
2 |
3 | import com.intellij.openapi.application.*;
4 | import com.intellij.openapi.command.*;
5 | import com.intellij.openapi.editor.*;
6 | import com.intellij.openapi.fileEditor.*;
7 | import com.intellij.openapi.project.*;
8 | import com.intellij.openapi.vfs.*;
9 | import io.github.francoiscambell.clionarduinoplugin.resources.*;
10 |
11 | import java.io.*;
12 |
13 | /**
14 | * Created by francois on 15-08-04.
15 | */
16 | public class ArduinoSketchFileCreator {
17 |
18 | public static VirtualFile createSketchFileWithName(final Project project, final VirtualFile directory, final String name) {
19 | ApplicationManager.getApplication().runWriteAction(new Runnable() {
20 | @Override
21 | public void run() {
22 | try {
23 | VirtualFile sketch = directory.createChildData(this, name);
24 | final Document sketchDocument = FileDocumentManager.getInstance().getDocument(sketch);
25 | if (sketchDocument != null) {
26 | CommandProcessor.getInstance().executeCommand(project, new Runnable() {
27 | @Override
28 | public void run() {
29 | sketchDocument.setText(Strings.DEFAULT_ARDUINO_SKETCH_CONTENTS);
30 | }
31 | }, null, null, sketchDocument);
32 | }
33 | } catch (IOException e) {
34 | e.printStackTrace();
35 | }
36 | }
37 | });
38 | return directory.findChild(name);
39 | }
40 |
41 | public static void addFileToCMakeLists(final Project project, final VirtualFile file) {
42 | CMakeListsEditor.getInstance(project.getBaseDir()).set("SOURCE_FILES", file.getName());
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/io/github/francoiscambell/clionarduinoplugin/CMakeListsEditor.java:
--------------------------------------------------------------------------------
1 | package io.github.francoiscambell.clionarduinoplugin;
2 |
3 | import com.intellij.openapi.application.*;
4 | import com.intellij.openapi.command.*;
5 | import com.intellij.openapi.editor.*;
6 | import com.intellij.openapi.fileEditor.*;
7 | import com.intellij.openapi.vfs.*;
8 |
9 | import java.util.*;
10 |
11 | /**
12 | * Created by francois on 15-08-04.
13 | */
14 | public class CMakeListsEditor {
15 | private static Map INSTANCES = new WeakHashMap();
16 | private VirtualFile cMakeListsVirtualFile;
17 |
18 | private CMakeListsEditor(VirtualFile cMakeLists) {
19 | this.cMakeListsVirtualFile = cMakeLists;
20 | }
21 |
22 | public static CMakeListsEditor getInstance(VirtualFile cMakeLists) {
23 | if (!INSTANCES.containsKey(cMakeLists)) {
24 | INSTANCES.put(cMakeLists, new CMakeListsEditor(cMakeLists));
25 | }
26 | return INSTANCES.get(cMakeLists);
27 | }
28 |
29 | private VirtualFile getCMakeListsVirtualFile() {
30 | return cMakeListsVirtualFile;
31 | }
32 |
33 | private Document getCMakeListsDocument() {
34 | return FileDocumentManager.getInstance().getDocument(getCMakeListsVirtualFile());
35 | }
36 |
37 | public void clear() {
38 | final Document cMakeLists = getCMakeListsDocument();
39 | ApplicationManager.getApplication().runWriteAction(new Runnable() {
40 | @Override
41 | public void run() {
42 | CommandProcessor.getInstance().executeCommand(null, new Runnable() {
43 | @Override
44 | public void run() {
45 | cMakeLists.deleteString(0, cMakeLists.getTextLength());
46 | FileDocumentManager.getInstance().saveDocument(cMakeLists);
47 | }
48 | }, null, null, cMakeLists);
49 | }
50 | });
51 | }
52 |
53 | public void addLine(int line, final String text) {
54 | final Document cMakeLists = getCMakeListsDocument();
55 | final int lineEndOffset = cMakeLists.getLineEndOffset(line);
56 |
57 | ApplicationManager.getApplication().runWriteAction(new Runnable() {
58 | @Override
59 | public void run() {
60 | CommandProcessor.getInstance().executeCommand(null, new Runnable() {
61 | @Override
62 | public void run() {
63 | cMakeLists.insertString(lineEndOffset, text + "\n");
64 | FileDocumentManager.getInstance().saveDocument(cMakeLists);
65 | }
66 | }, null, null, cMakeLists);
67 | }
68 | });
69 | }
70 |
71 | public void appendLine(String text) {
72 | int lastLine = getCMakeListsDocument().getLineCount();
73 | if (lastLine != 0) {
74 | lastLine--;
75 | }
76 | addLine(lastLine, text);
77 | }
78 |
79 | public void blankLine() {
80 | appendLine("");
81 | }
82 |
83 | public void minVersion(String minVersion) {
84 | method("cmake_minimum_required", "VERSION", minVersion);
85 | }
86 |
87 | public void set(String var, String value) {
88 | method("set", var, value);
89 | }
90 |
91 | public void project(String projectName) {
92 | method("project", projectName);
93 | }
94 |
95 | public void method(String methodName, String... args) {
96 | StringBuilder builder = new StringBuilder(methodName);
97 | builder.append('(');
98 | for (String arg : args) {
99 | builder.append(arg);
100 | builder.append(' ');
101 | }
102 | if (args.length > 0) {
103 | builder.deleteCharAt(builder.length() - 1);
104 | }
105 | builder.append(')');
106 | appendLine(builder.toString());
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/src/io/github/francoiscambell/clionarduinoplugin/actions/NewArduinoProject.java:
--------------------------------------------------------------------------------
1 | package io.github.francoiscambell.clionarduinoplugin.actions;
2 |
3 | import com.intellij.icons.*;
4 | import com.intellij.openapi.actionSystem.*;
5 | import com.intellij.openapi.wm.impl.welcomeScreen.*;
6 | import io.github.francoiscambell.clionarduinoplugin.wizards.NewArduinoProjectWizard;
7 |
8 | /**
9 | * Created by francois on 15-08-14.
10 | */
11 | public class NewArduinoProject extends AnAction {
12 | public void update(AnActionEvent event) {
13 | Presentation presentation = event.getPresentation();
14 | if (ActionPlaces.isMainMenuOrActionSearch(event.getPlace())) {
15 | presentation.setIcon(null);
16 | }
17 |
18 | if (NewWelcomeScreen.isNewWelcomeScreen(event)) {
19 | event.getPresentation().setIcon(AllIcons.Welcome.CreateNewProject);
20 | }
21 |
22 | }
23 |
24 | @Override
25 | public void actionPerformed(AnActionEvent e) {
26 | (new NewArduinoProjectWizard()).runWizard();
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/io/github/francoiscambell/clionarduinoplugin/actions/NewSketchFile.java:
--------------------------------------------------------------------------------
1 | package io.github.francoiscambell.clionarduinoplugin.actions;
2 |
3 | import com.intellij.ide.*;
4 | import com.intellij.openapi.actionSystem.*;
5 | import com.intellij.openapi.application.*;
6 | import com.intellij.openapi.fileEditor.*;
7 | import com.intellij.openapi.project.*;
8 | import com.intellij.openapi.ui.*;
9 | import com.intellij.openapi.vfs.*;
10 | import com.intellij.psi.*;
11 | import io.github.francoiscambell.clionarduinoplugin.*;
12 | import io.github.francoiscambell.clionarduinoplugin.resources.*;
13 | import io.github.francoiscambell.clionarduinoplugin.resources.icons.*;
14 | import org.jetbrains.annotations.*;
15 |
16 | import java.io.*;
17 |
18 | /**
19 | * Created by francois on 15-08-02.
20 | */
21 | public class NewSketchFile extends AnAction {
22 |
23 | public void actionPerformed(AnActionEvent e) {
24 | final Project project = e.getRequiredData(CommonDataKeys.PROJECT);
25 | final IdeView view = e.getRequiredData(LangDataKeys.IDE_VIEW);
26 |
27 | PsiDirectory directory = view.getOrChooseDirectory();
28 | if (directory == null) {
29 | return;
30 | }
31 | final VirtualFile directoryVirtualFile = directory.getVirtualFile();
32 |
33 | boolean loop = false;
34 | do {
35 | String filename = getDesiredFilename(project);
36 | if (filename == null) { //cancel
37 | return;
38 | }
39 | if (filename.isEmpty()) { //no name entered
40 | showEmptyFilenameError(project);
41 | loop = true;
42 | continue;
43 | }
44 | filename = correctExtension(filename); //add .ino if the current filename doesn't end with .ino or .pde
45 |
46 | VirtualFile existingFile = directoryVirtualFile.findChild(filename);
47 | if (existingFile != null) {
48 | int overwriteChoice = getOverwriteChoice(project); //ask to overwrite file
49 | switch (overwriteChoice) {
50 | case Messages.YES:
51 | deleteVirtualFile(existingFile);
52 | loop = false;
53 | break;
54 | case Messages.NO:
55 | loop = true;
56 | continue;
57 | case Messages.CANCEL:
58 | return;
59 | }
60 | }
61 | VirtualFile sketch = ArduinoSketchFileCreator
62 | .createSketchFileWithName(project, directoryVirtualFile, filename);
63 | // ArduinoSketchFileCreator.addFileToCMakeLists(project, sketch); //not sure if i need to do this or not
64 | FileEditorManager.getInstance(project).openFile(sketch, true, true); //open in editor
65 | } while (loop);
66 | }
67 |
68 | private void showEmptyFilenameError(Project project) {
69 | Messages.showErrorDialog(project, Strings.ENTER_FILENAME, Strings.ERROR);
70 | }
71 |
72 | private int getOverwriteChoice(Project project) {
73 | return Messages
74 | .showYesNoCancelDialog(project, Strings.QUESTION_OVERWRITE, Strings.FILE_ALREADY_EXISTS, ArduinoIcon.ARDUINO_ICON);
75 | }
76 |
77 | private String getDesiredFilename(Project project) {
78 | return Messages
79 | .showInputDialog(project, Strings.ENTER_FILENAME, Strings.SKETCH_NAME, ArduinoIcon.ARDUINO_ICON);
80 | }
81 |
82 | @NotNull
83 | private String correctExtension(String filename) {
84 | if (!(filename.endsWith(Strings.DOT_INO_EXT) || filename.endsWith(Strings.DOT_PDE_EXT))) {
85 | filename = filename + Strings.DOT_INO_EXT;
86 | }
87 | return filename;
88 | }
89 |
90 |
91 | private void deleteVirtualFile(final VirtualFile virtualFile) {
92 | if (virtualFile == null) {
93 | return;
94 | }
95 | ApplicationManager.getApplication().runWriteAction(new Runnable() {
96 | @Override
97 | public void run() {
98 | try {
99 | virtualFile.delete(this);
100 | } catch (IOException e) {
101 | e.printStackTrace();
102 | }
103 | }
104 | });
105 |
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/src/io/github/francoiscambell/clionarduinoplugin/components/ArduinoFileTypeRegistration.java:
--------------------------------------------------------------------------------
1 | package io.github.francoiscambell.clionarduinoplugin.components;
2 |
3 | import com.intellij.openapi.application.*;
4 | import com.intellij.openapi.components.*;
5 | import com.intellij.openapi.fileTypes.*;
6 | import io.github.francoiscambell.clionarduinoplugin.resources.*;
7 | import org.jetbrains.annotations.*;
8 |
9 | /**
10 | * Created by francois on 15-08-03.
11 | */
12 | public class ArduinoFileTypeRegistration implements ApplicationComponent {
13 |
14 | public void initComponent() {
15 | ApplicationManager.getApplication().invokeLater(new Runnable() {
16 | @Override
17 | public void run() {
18 | ApplicationManager.getApplication().runWriteAction(new Runnable() {
19 | @Override
20 | public void run() {
21 | FileType cpp = FileTypeManager.getInstance().getFileTypeByExtension(Strings.CPP_EXT);
22 | FileTypeManager.getInstance().associateExtension(cpp, Strings.INO_EXT);
23 | FileTypeManager.getInstance().associateExtension(cpp, Strings.PDE_EXT);
24 | }
25 | });
26 | }
27 | });
28 | }
29 |
30 | public void disposeComponent() {
31 | ApplicationManager.getApplication().invokeLater(new Runnable() {
32 | @Override
33 | public void run() {
34 | ApplicationManager.getApplication().runWriteAction(new Runnable() {
35 | @Override
36 | public void run() {
37 | FileType cpp = FileTypeManager.getInstance().getFileTypeByExtension(Strings.CPP_EXT);
38 | FileTypeManager.getInstance().removeAssociatedExtension(cpp, Strings.INO_EXT);
39 | FileTypeManager.getInstance().removeAssociatedExtension(cpp, Strings.PDE_EXT);
40 | }
41 | });
42 | }
43 | });
44 | }
45 |
46 | @NotNull
47 | public String getComponentName() {
48 | return "ArduinoFileTypeRegistration";
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/io/github/francoiscambell/clionarduinoplugin/resources/ArduinoToolchainFiles.java:
--------------------------------------------------------------------------------
1 | package io.github.francoiscambell.clionarduinoplugin.resources;
2 |
3 | import com.intellij.openapi.application.ApplicationManager;
4 | import com.intellij.openapi.vfs.VirtualFile;
5 | import org.apache.commons.io.IOUtils;
6 |
7 | import java.io.Closeable;
8 | import java.io.IOException;
9 | import java.io.InputStream;
10 | import java.io.OutputStream;
11 |
12 | /**
13 | * Created by francois on 15-08-03.
14 | */
15 | public class ArduinoToolchainFiles {
16 | public static InputStream getArduinoToolchainCmake() {
17 | return ArduinoToolchainFiles.class.getResourceAsStream("arduino-cmake/cmake/ArduinoToolchain.cmake");
18 | }
19 |
20 | public static InputStream getArduinoCmake() {
21 | return ArduinoToolchainFiles.class.getResourceAsStream("arduino-cmake/cmake/Platform/Arduino.cmake");
22 | }
23 |
24 | public static void copyToDirectory(final VirtualFile projectRoot) {
25 | ApplicationManager.getApplication().runWriteAction(new Runnable() {
26 | @Override
27 | public void run() {
28 | try {
29 | VirtualFile cmakeDirectory = projectRoot.createChildDirectory(this, "cmake");
30 | VirtualFile platformDirectory = cmakeDirectory.createChildDirectory(this, "Platform");
31 |
32 | VirtualFile arduinoToolchain = cmakeDirectory.createChildData(this, "ArduinoToolchain.cmake");
33 | VirtualFile arduino = platformDirectory.createChildData(this, "Arduino.cmake");
34 |
35 | OutputStream arduinoToolchainOutputStream = arduinoToolchain.getOutputStream(this);
36 | OutputStream arduinoOutputStream = arduino.getOutputStream(this);
37 |
38 | InputStream arduinoToolchainInputStream = getArduinoToolchainCmake();
39 | InputStream arduinoInputStream = getArduinoCmake();
40 |
41 | try {
42 | IOUtils.copy(arduinoToolchainInputStream, arduinoToolchainOutputStream);
43 | IOUtils.copy(arduinoInputStream, arduinoOutputStream);
44 | } finally {
45 | closeStreams(arduinoToolchainOutputStream,
46 | arduinoOutputStream,
47 | arduinoToolchainInputStream,
48 | arduinoInputStream);
49 | }
50 | } catch (IOException e) {
51 | e.printStackTrace();
52 | }
53 | }
54 | });
55 | }
56 |
57 | private static void closeStreams(Closeable... streams) {
58 | for (Closeable c : streams) {
59 | IOUtils.closeQuietly(c);
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/io/github/francoiscambell/clionarduinoplugin/resources/Strings.java:
--------------------------------------------------------------------------------
1 | package io.github.francoiscambell.clionarduinoplugin.resources;
2 |
3 | /**
4 | * Created by francois on 15-08-04.
5 | */
6 | public class Strings {
7 | public static final String CMAKE_LISTS_FILENAME = "CMakeLists.txt";
8 | public static final String CPP_EXT = "cpp";
9 | public static final String DEFAULT_ARDUINO_SKETCH_CONTENTS = "#include \n\nvoid setup() {\n\n}\n\nvoid loop() {\n\n}";
10 | public static final String ENTER_FILENAME = "Enter filename";
11 | public static final String ERROR = "Error";
12 | public static final String FILE_ALREADY_EXISTS = "File Already Exists";
13 | public static final String INO_EXT = "ino";
14 | public static final String DOT_INO_EXT = "." + INO_EXT;
15 | public static final String MAIN_CPP_FILENAME = "main.cpp";
16 | public static final String PDE_EXT = "PDE";
17 | public static final String DOT_PDE_EXT = "." + PDE_EXT;
18 | public static final String QUESTION_OVERWRITE = "Do you wish to overwrite the existing file?";
19 | public static final String SKETCH_NAME = "Sketch Name";
20 | }
21 |
--------------------------------------------------------------------------------
/src/io/github/francoiscambell/clionarduinoplugin/resources/icons/ArduinoIcon.java:
--------------------------------------------------------------------------------
1 | package io.github.francoiscambell.clionarduinoplugin.resources.icons;
2 |
3 | import com.intellij.openapi.util.*;
4 |
5 | import javax.swing.*;
6 |
7 | /**
8 | * Created by francois on 15-08-04.
9 | */
10 | public class ArduinoIcon {
11 | public static final Icon ARDUINO_ICON = IconLoader.getIcon("Arduino_Logo.png");
12 | }
13 |
--------------------------------------------------------------------------------
/src/io/github/francoiscambell/clionarduinoplugin/resources/icons/Arduino_Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rjuang/CLionArduinoPlugin/0932733d5ffd952776e2a39922f88dcb174c3420/src/io/github/francoiscambell/clionarduinoplugin/resources/icons/Arduino_Logo.png
--------------------------------------------------------------------------------
/src/io/github/francoiscambell/clionarduinoplugin/resources/icons/Arduino_Logo@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rjuang/CLionArduinoPlugin/0932733d5ffd952776e2a39922f88dcb174c3420/src/io/github/francoiscambell/clionarduinoplugin/resources/icons/Arduino_Logo@2x.png
--------------------------------------------------------------------------------
/src/io/github/francoiscambell/clionarduinoplugin/resources/icons/Arduino_Logo@2x_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rjuang/CLionArduinoPlugin/0932733d5ffd952776e2a39922f88dcb174c3420/src/io/github/francoiscambell/clionarduinoplugin/resources/icons/Arduino_Logo@2x_dark.png
--------------------------------------------------------------------------------
/src/io/github/francoiscambell/clionarduinoplugin/resources/icons/Arduino_Logo_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rjuang/CLionArduinoPlugin/0932733d5ffd952776e2a39922f88dcb174c3420/src/io/github/francoiscambell/clionarduinoplugin/resources/icons/Arduino_Logo_dark.png
--------------------------------------------------------------------------------
/src/io/github/francoiscambell/clionarduinoplugin/wizards/NewArduinoProjectForm.java:
--------------------------------------------------------------------------------
1 | package io.github.francoiscambell.clionarduinoplugin.wizards;
2 |
3 | import com.intellij.openapi.fileChooser.FileChooserDescriptor;
4 | import com.intellij.openapi.project.Project;
5 | import com.intellij.openapi.project.ProjectManager;
6 | import com.intellij.openapi.ui.TextBrowseFolderListener;
7 | import com.intellij.openapi.ui.TextFieldWithBrowseButton;
8 | import com.jetbrains.cidr.cpp.cmake.projectWizard.CMakeProjectStepAdapter;
9 | import com.jetbrains.cidr.cpp.cmake.workspace.CMakeWorkspace;
10 |
11 | import javax.swing.*;
12 | import javax.swing.event.DocumentEvent;
13 | import javax.swing.event.DocumentListener;
14 | import java.awt.*;
15 | import java.awt.event.*;
16 | import java.beans.PropertyChangeEvent;
17 | import java.beans.PropertyChangeListener;
18 |
19 | import static java.awt.GridBagConstraints.HORIZONTAL;
20 | import static java.awt.GridBagConstraints.LINE_END;
21 | import static java.awt.GridBagConstraints.LINE_START;
22 |
23 | /**
24 | * Created by radford on 1/9/17.
25 | */
26 | public class NewArduinoProjectForm extends CMakeProjectStepAdapter {
27 | private JTextField projectNameTextField;
28 | private TextFieldWithBrowseButton projectPathField;
29 |
30 | private JPanel mainPanel;
31 | private String lastSelectedPath;
32 |
33 | public NewArduinoProjectForm(String defaultProjectName, String defaultProjectPath) {
34 | lastSelectedPath = defaultProjectPath;
35 |
36 | mainPanel = new JPanel(new GridBagLayout());
37 |
38 | projectNameTextField = new JTextField(defaultProjectName, 20);
39 |
40 | GridBagConstraints constraints = new GridBagConstraints();
41 | constraints.ipadx = 5;
42 | constraints.fill = HORIZONTAL;
43 |
44 | constraints.gridx = 0;
45 | constraints.gridy = 0;
46 | constraints.weightx = 0.2;
47 | constraints.anchor = LINE_END;
48 |
49 | mainPanel.add(new JLabel("Project Name"), constraints);
50 |
51 | constraints.gridx = 1;
52 | constraints.gridy = 0;
53 | constraints.weightx = 0.8;
54 | constraints.anchor = LINE_START;
55 |
56 | mainPanel.add(projectNameTextField, constraints);
57 |
58 | projectPathField = new TextFieldWithBrowseButton(
59 | new JTextField(
60 | defaultProjectPath,
61 | 20),
62 | new ActionListener() {
63 | @Override
64 | public void actionPerformed(ActionEvent e) {
65 | lastSelectedPath = projectPathField.getText();
66 | }
67 | }
68 | );
69 |
70 | projectPathField.addBrowseFolderListener(
71 | "Select Target Project Directory",
72 | null,
73 | null,
74 | new FileChooserDescriptor(false,
75 | true,
76 | false,
77 | false,
78 | false,
79 | false));
80 |
81 |
82 | projectNameTextField.getDocument().addDocumentListener(
83 | new DocumentListener() {
84 | @Override
85 | public void insertUpdate(DocumentEvent e) {
86 | syncFields();
87 | }
88 |
89 | @Override
90 | public void removeUpdate(DocumentEvent e) {
91 | syncFields();
92 | }
93 |
94 | @Override
95 | public void changedUpdate(DocumentEvent e) {
96 | syncFields();
97 | }
98 |
99 | private void syncFields() {
100 | String projectName = "/" + projectNameTextField.getText();
101 | if (!lastSelectedPath.endsWith(projectName)) {
102 | projectPathField.setText(lastSelectedPath.concat(projectName));
103 | projectPathField.setAutoscrolls(true);
104 | }
105 | }
106 | }
107 | );
108 |
109 | constraints.gridx = 0;
110 | constraints.gridy = 1;
111 | constraints.weightx = 0.2;
112 | constraints.anchor = LINE_END;
113 | mainPanel.add(new JLabel("Project Path"), constraints);
114 |
115 | constraints.gridx = 1;
116 | constraints.gridy = 1;
117 | constraints.weightx = 0.8;
118 | constraints.anchor = LINE_START;
119 | mainPanel.add(projectPathField, constraints);
120 | }
121 |
122 | @Override
123 | protected void init() {
124 | mainPanel.setVisible(true);
125 | }
126 |
127 | @Override
128 | public JComponent getPreferredFocusedComponent() {
129 | return mainPanel;
130 | }
131 |
132 | @Override
133 | public void dispose() {
134 | mainPanel.setVisible(false);
135 | }
136 |
137 | public String getName() {
138 | return projectNameTextField.getText().replaceAll("-", "_");
139 | }
140 |
141 | public String getLocation() {
142 | return projectPathField.getText();
143 | }
144 |
145 | @Override
146 | public JComponent getComponent() {
147 | return mainPanel;
148 | }
149 | }
150 |
--------------------------------------------------------------------------------
/src/io/github/francoiscambell/clionarduinoplugin/wizards/NewArduinoProjectWizard.java:
--------------------------------------------------------------------------------
1 | package io.github.francoiscambell.clionarduinoplugin.wizards;
2 |
3 | import com.intellij.ide.RecentDirectoryProjectsManager;
4 | import com.intellij.ide.RecentProjectsManager;
5 | import com.intellij.ide.util.DirectoryUtil;
6 | import com.intellij.ide.util.PropertiesComponent;
7 | import com.intellij.openapi.application.ApplicationManager;
8 | import com.intellij.openapi.components.impl.stores.DirectoryStorageUtil;
9 | import com.intellij.openapi.fileEditor.OpenFileDescriptor;
10 | import com.intellij.openapi.project.Project;
11 | import com.intellij.openapi.project.ProjectManager;
12 | import com.intellij.openapi.ui.Messages;
13 | import com.intellij.openapi.util.io.FileUtil;
14 | import com.intellij.openapi.vfs.LocalFileSystem;
15 | import com.intellij.openapi.vfs.VfsUtil;
16 | import com.intellij.openapi.vfs.VirtualFile;
17 | import com.jetbrains.cidr.cpp.CPPLog;
18 | import com.jetbrains.cidr.cpp.cmake.CMakeProjectOpenProcessor;
19 | import com.jetbrains.cidr.cpp.cmake.projectWizard.*;
20 | import io.github.francoiscambell.clionarduinoplugin.CMakeListsEditor;
21 | import io.github.francoiscambell.clionarduinoplugin.resources.ArduinoToolchainFiles;
22 | import io.github.francoiscambell.clionarduinoplugin.resources.Strings;
23 | import org.jdom.JDOMException;
24 |
25 | import java.io.File;
26 | import java.io.FilenameFilter;
27 | import java.io.IOException;
28 | import java.util.Optional;
29 |
30 | import static com.jetbrains.cidr.cpp.cmake.projectWizard.CLionProjectWizardUtils.refreshProjectDir;
31 |
32 |
33 | /**
34 | * Created by francois on 15-08-14.
35 | */
36 | public class NewArduinoProjectWizard extends CMakeProjectWizard {
37 |
38 | private String lastDir = Optional.ofNullable(RecentProjectsManager.getInstance().getLastProjectCreationLocation())
39 | .orElse("");
40 |
41 | private NewArduinoProjectForm adapter = new NewArduinoProjectForm(
42 | "untitled-0",
43 | new File(lastDir).getPath());
44 |
45 | public NewArduinoProjectWizard() {
46 | super("New Arduino Sketch Project", "NewArduinoSketchProject");
47 | initWithStep(adapter);
48 | }
49 |
50 | @Override
51 | protected boolean tryFinish() {
52 | String projectRootPath = adapter.getLocation();
53 |
54 | File projectRootDir = new File(projectRootPath);
55 | if (projectRootDir.exists()) {
56 | String[] fileList = projectRootDir.list(new FilenameFilter() {
57 | public boolean accept(File dir, String name) {
58 | return !".DS_Store".equalsIgnoreCase(name) && !"Thumbs.db".equalsIgnoreCase(name);
59 | }
60 | });
61 | if (fileList != null && fileList.length > 0) {
62 | int dialogAnswer = Messages.showYesNoDialog(String
63 | .format("Directory \'%s\' already exists and not empty.\nWould you like to continue?", projectRootPath), "Project Directory Already Exists", Messages
64 | .getQuestionIcon());
65 | if (dialogAnswer != 0) {
66 | return false;
67 | }
68 | }
69 | } else {
70 | try {
71 | VfsUtil.createDirectories(projectRootPath);
72 | } catch (IOException | RuntimeException e) {
73 | CPPLog.LOG.warn(e);
74 | return false;
75 | }
76 | }
77 |
78 | String projectRootDirParentPath = projectRootDir.getParent();
79 | if (projectRootDirParentPath != null) {
80 | RecentProjectsManager.getInstance().setLastProjectCreationLocation(projectRootDirParentPath);
81 | }
82 |
83 | try {
84 | createProject(this.adapter.getName(), projectRootPath);
85 | return true;
86 | } catch (IOException e) {
87 | CPPLog.LOG.warn(e);
88 | return false;
89 | }
90 | }
91 |
92 | public static String createProject(String projectName, String projectRootPath) throws IOException {
93 | File projectRoot = new File(projectRootPath);
94 | File cMakeLists = new File(projectRoot, "CMakeLists.txt");
95 | if (!cMakeLists.exists() && !cMakeLists.createNewFile()) {
96 | throw new IOException("Cannot create file " + cMakeLists);
97 | } else {
98 | projectName = FileUtil.sanitizeFileName(projectName);
99 | File mainSketchFile = new File(projectRoot, projectName + ".ino");
100 | if (!mainSketchFile.exists() && !mainSketchFile.createNewFile()) {
101 | throw new IOException("Cannot create file " + mainSketchFile);
102 | } else {
103 | FileUtil.writeToFile(mainSketchFile, Strings.DEFAULT_ARDUINO_SKETCH_CONTENTS);
104 |
105 | VirtualFile cMakeListsVirtualFile = VfsUtil.findFileByIoFile(cMakeLists, true);
106 | CMakeListsEditor cMakeListsEditor = CMakeListsEditor.getInstance(cMakeListsVirtualFile);
107 | cMakeListsEditor.clear();
108 | cMakeListsEditor.minVersion("2.8.4");
109 | cMakeListsEditor.set("CMAKE_TOOLCHAIN_FILE", "${CMAKE_SOURCE_DIR}/cmake/ArduinoToolchain.cmake");
110 | cMakeListsEditor.set("PROJECT_NAME", projectName);
111 | cMakeListsEditor.project("${PROJECT_NAME}");
112 | cMakeListsEditor.blankLine();
113 | cMakeListsEditor.set("${CMAKE_PROJECT_NAME}_SKETCH", projectName + ".ino");
114 | cMakeListsEditor.blankLine();
115 | cMakeListsEditor.appendLine("#### Uncomment below additional settings as needed.");
116 | cMakeListsEditor.appendLine("# set(${CMAKE_PROJECT_NAME}_BOARD mega)");
117 | cMakeListsEditor.appendLine("# set(${CMAKE_PROJECT_NAME}_PORT /dev/ttyACM0)");
118 | cMakeListsEditor.appendLine("# set(mega.build.mcu atmega2560)");
119 | cMakeListsEditor.appendLine("# set(mega.upload.protocol wiring)");
120 | cMakeListsEditor.appendLine("# set(mega.upload.speed 115200)");
121 | cMakeListsEditor.blankLine();
122 | cMakeListsEditor.method("generate_arduino_firmware", "${CMAKE_PROJECT_NAME}");
123 |
124 | ArduinoToolchainFiles.copyToDirectory(VfsUtil.findFileByIoFile(projectRoot, true));
125 |
126 | return projectName;
127 | }
128 | }
129 | }
130 |
131 | @Override
132 | protected void doRunWizard() {
133 | VirtualFile projectRoot = LocalFileSystem.getInstance().refreshAndFindFileByPath(this.adapter.getLocation());
134 | if (projectRoot == null) {
135 | return;
136 | }
137 | refreshProjectDir(projectRoot);
138 | final VirtualFile cMakeLists = projectRoot.findChild("CMakeLists.txt");
139 | if (cMakeLists == null) {
140 | return;
141 | }
142 | final VirtualFile mainSketchFile = projectRoot.findChild(this.adapter.getName() + ".ino");
143 | if (mainSketchFile == null) {
144 | return;
145 | }
146 |
147 | final Project project;
148 | try {
149 | project = ProjectManager.getInstance().loadAndOpenProject(cMakeLists.getPath());
150 | } catch (IOException | JDOMException e) {
151 | CPPLog.LOG.warn(e);
152 | return;
153 | }
154 |
155 | if (project == null) {
156 | return;
157 | }
158 |
159 | CMakeProjectOpenProcessor.OpenProjectSpec projectSpec = CMakeProjectOpenProcessor.getHelper()
160 | .getAndClearFileToOpenData(project);
161 |
162 | deleteBuildOutputDir(projectSpec);
163 | (new OpenFileDescriptor(project, cMakeLists)).navigate(false);
164 | (new OpenFileDescriptor(project, mainSketchFile)).navigate(true);
165 | }
166 |
167 | private void deleteBuildOutputDir(CMakeProjectOpenProcessor.OpenProjectSpec projectSpec) {
168 | if (projectSpec != null && projectSpec.generationDir != null) {
169 | FileUtil.delete(projectSpec.generationDir);
170 | }
171 | }
172 | }
173 |
--------------------------------------------------------------------------------