Skip to content

Commit 80b0cdb

Browse files
Version 1.0 :)
1 parent 2a3972a commit 80b0cdb

File tree

12 files changed

+372
-119
lines changed

12 files changed

+372
-119
lines changed

META-INF/plugin.xml

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,32 @@
55
<vendor email="support@yourcompany.com" url="http://www.yourcompany.com">YourCompany</vendor>
66

77
<description><![CDATA[
8-
Registers .ino and .pde files as C/C++ sources
8+
<h1>CLion Arduino Plugin</h1>
9+
<br>
10+
11+
<a href="https://github.com/francoiscampbell/CLionArduinoPlugin">GitHub</a> |
12+
<a href="https://github.com/francoiscampbell/CLionArduinoPlugin/issues">Issues</a>
13+
14+
<br>
15+
16+
This is a plugin to enable Arduino-CMake integration into CLion. It uses the amazing <a href="https://github.com/queezythegreat/arduino-cmake">Arduino CMake</a>
17+
project from queezythegreat. The current features are to convert a default CLion project into an Arduino-CMake one, and to create new sketch files.
18+
<br>
19+
When CLion adds the ability to hook into project creation directly, I will be able to make it selectable,
20+
but for now, we're stuck with having to create a new CLion project and then convert it.
21+
<br>
22+
Future features are to add menu option to easily change the board type, port number, etc.
923
]]></description>
1024

1125
<change-notes><![CDATA[
12-
Add change notes here.<br>
13-
<em>most HTML tags may be used</em>
26+
<b>1.0</b>
27+
<ul>
28+
<li>Convert a project to Arduino CMake. This replaces CMakeLists.txt with a default one, deletes the default
29+
main.cpp file, copies in the Arduino CMake toolchain files, and deletes the build direcory to start fresh</li>
30+
<li>Associates .ino and .pde files as C++ source, so you get syntax highlighting and prediction, etc.</li>
31+
<li>Create a new sketch file in any directory. If you omit the extension, it will add .ino automatically</li>
32+
<li>Adds import for Arduino.h to all newly created sketch files to enable code completion</li>
33+
</ul>
1434
]]>
1535
</change-notes>
1636

@@ -28,7 +48,7 @@
2848
<application-components>
2949
<!-- Add your application components here -->
3050
<component>
31-
<implementation-class>io.github.francoiscambell.clionarduinoplugin.filetypes.ArduinoFileTypeRegistration
51+
<implementation-class>io.github.francoiscambell.clionarduinoplugin.components.ArduinoFileTypeRegistration
3252
</implementation-class>
3353
</component>
3454
</application-components>

lib/commons-io-2.4-javadoc.jar

707 KB
Binary file not shown.

lib/commons-io-2.4-sources.jar

241 KB
Binary file not shown.

lib/commons-io-2.4.jar

181 KB
Binary file not shown.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
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).set("SOURCE_FILES", file.getName());
43+
}
44+
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
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+
/**
12+
* Created by francois on 15-08-04.
13+
*/
14+
public class CMakeListsEditor {
15+
private static CMakeListsEditor INSTANCE;
16+
private Project project;
17+
18+
private CMakeListsEditor(Project project) {
19+
this.project = project;
20+
}
21+
22+
public static CMakeListsEditor getInstance(Project project) {
23+
if (INSTANCE == null) {
24+
INSTANCE = new CMakeListsEditor(project);
25+
}
26+
return INSTANCE;
27+
}
28+
29+
public VirtualFile getCMakeListsVirtualFile() {
30+
return project.getBaseDir().findChild(Strings.CMAKE_LISTS_FILENAME);
31+
}
32+
33+
public 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(project, new Runnable() {
43+
@Override
44+
public void run() {
45+
cMakeLists.deleteString(0, getCMakeListsDocument().getTextLength());
46+
}
47+
}, null, null, cMakeLists);
48+
}
49+
});
50+
}
51+
52+
public void addLine(int line, final String text) {
53+
final Document cMakeLists = getCMakeListsDocument();
54+
final int lineEndOffset = cMakeLists.getLineEndOffset(line);
55+
56+
ApplicationManager.getApplication().runWriteAction(new Runnable() {
57+
@Override
58+
public void run() {
59+
CommandProcessor.getInstance().executeCommand(project, new Runnable() {
60+
@Override
61+
public void run() {
62+
cMakeLists.insertString(lineEndOffset, text + "\n");
63+
}
64+
}, null, null, cMakeLists);
65+
}
66+
});
67+
}
68+
69+
public void appendLine(String text) {
70+
int lastLine = getCMakeListsDocument().getLineCount();
71+
if (lastLine != 0) {
72+
lastLine--;
73+
}
74+
addLine(lastLine, text);
75+
}
76+
77+
public void blankLine() {
78+
appendLine("");
79+
}
80+
81+
public void minVersion(String minVersion) {
82+
method("cmake_minimum_required", "VERSION", minVersion);
83+
}
84+
85+
public void set(String var, String value) {
86+
method("set", var, value);
87+
}
88+
89+
public void project(String projectName) {
90+
method("project", projectName);
91+
}
92+
93+
public void method(String methodName, String... args) {
94+
StringBuilder builder = new StringBuilder(methodName);
95+
builder.append('(');
96+
for (String arg : args) {
97+
builder.append(arg);
98+
builder.append(' ');
99+
}
100+
if (args.length > 0) {
101+
builder.deleteCharAt(builder.length() - 1);
102+
}
103+
builder.append(')');
104+
appendLine(builder.toString());
105+
}
106+
}

src/io/github/francoiscambell/clionarduinoplugin/actions/ConvertToSketchProject.java

Lines changed: 53 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -2,112 +2,83 @@
22

33
import com.intellij.openapi.actionSystem.*;
44
import com.intellij.openapi.application.*;
5-
import com.intellij.openapi.command.*;
6-
import com.intellij.openapi.editor.*;
75
import com.intellij.openapi.project.*;
86
import com.intellij.openapi.vfs.*;
9-
import com.intellij.psi.*;
7+
import com.jetbrains.cidr.cpp.cmake.*;
8+
import com.jetbrains.cidr.cpp.cmake.workspace.*;
9+
import io.github.francoiscambell.clionarduinoplugin.*;
1010
import io.github.francoiscambell.clionarduinoplugin.resources.*;
11-
import org.apache.sanselan.util.*;
11+
import org.apache.commons.io.*;
1212

1313
import java.io.*;
1414

1515
/**
1616
* Created by francois on 15-08-03.
1717
*/
1818
public class ConvertToSketchProject extends AnAction {
19+
1920
public void actionPerformed(AnActionEvent e) {
20-
// TODO: insert action logic here
2121
final Project project = e.getRequiredData(CommonDataKeys.PROJECT);
22-
final PsiDirectory projectRootDirectory = PsiManager.getInstance(project).findDirectory(project.getBaseDir());
23-
PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(project);
24-
2522
final String projectName = project.getName();
26-
Application app = ApplicationManager.getApplication();
23+
final CMakeListsEditor cMakeListsEditor = CMakeListsEditor.getInstance(project);
2724

28-
PsiFile cmakeListsPsiFile = projectRootDirectory.findFile("CMakeLists.txt");
29-
final Document cmakeListsDocument = psiDocumentManager.getDocument(cmakeListsPsiFile);
30-
final int endOfFirstLine = cmakeListsDocument.getCharsSequence().toString().indexOf('\n');
31-
app.runWriteAction(new Runnable() {
32-
@Override
33-
public void run() {
34-
CommandProcessor.getInstance().executeCommand(project, new Runnable() {
35-
@Override
36-
public void run() {
37-
cmakeListsDocument
38-
.insertString(endOfFirstLine, "\nset(CMAKE_TOOLCHAIN_FILE ${CMAKE_SOURCE_DIR}/cmake/ArduinoToolchain.cmake)");
39-
cmakeListsDocument.insertString(0, "set(PROJECT_NAME " + projectName + ")\n");
25+
deleteMainCpp(project);
4026

41-
}
42-
}, null, null, cmakeListsDocument);
43-
}
44-
});
27+
cMakeListsEditor.clear();
28+
cMakeListsEditor.minVersion("3.2");
29+
cMakeListsEditor.set("CMAKE_TOOLCHAIN_FILE", "${CMAKE_SOURCE_DIR}/cmake/ArduinoToolchain.cmake");
30+
cMakeListsEditor.set("PROJECT_NAME", projectName);
31+
cMakeListsEditor.project("${PROJECT_NAME}");
32+
cMakeListsEditor.blankLine();
33+
cMakeListsEditor.set("${CMAKE_PROJECT_NAME}_SKETCH", getMainSketchFile(project).getName());
34+
cMakeListsEditor.method("generate_arduino_firmware", "${CMAKE_PROJECT_NAME}");
35+
36+
ArduinoToolchainFiles.copyToProject(project);
37+
deleteBuildOutputDir(project);
38+
39+
CMakeSettings.getInstance(project).setAutoReloadEnabled(true);
4540

46-
PsiFile mainInoFile = projectRootDirectory.findFile(projectName + ".ino");
47-
PsiFile mainPdeFile = projectRootDirectory.findFile(projectName + ".pde");
48-
if (mainInoFile == null && mainPdeFile == null) {
49-
app.runWriteAction(new Runnable() {
41+
}
42+
43+
private void deleteMainCpp(Project project) {
44+
final VirtualFile mainCpp = project.getBaseDir().findChild(Strings.MAIN_CPP_FILENAME);
45+
if (mainCpp != null) {
46+
ApplicationManager.getApplication().runWriteAction(new Runnable() {
5047
@Override
5148
public void run() {
52-
PsiFile mainProjectFile = projectRootDirectory.createFile(projectName + ".ino");
53-
final Document mainProjectDocument = PsiDocumentManager.getInstance(project)
54-
.getDocument(mainProjectFile);
55-
CommandProcessor.getInstance().executeCommand(project, new Runnable() {
56-
@Override
57-
public void run() {
58-
mainProjectDocument
59-
.setText("#include <Arduino.h>\n\nvoid setup() {\n\n}\n\nvoid loop() {\n\n}");
60-
}
61-
}, null, null, mainProjectDocument);
49+
try {
50+
mainCpp.delete(this);
51+
} catch (IOException e) {
52+
e.printStackTrace();
53+
}
6254
}
6355
});
6456
}
57+
}
6558

66-
app.runWriteAction(new Runnable() {
67-
@Override
68-
public void run() {
69-
if (projectRootDirectory.findSubdirectory("build") == null) {
70-
projectRootDirectory.createSubdirectory("build");
71-
}
72-
}
73-
});
74-
75-
app.runWriteAction(new Runnable() {
76-
@Override
77-
public void run() {
78-
CommandProcessor.getInstance().executeCommand(project, new Runnable() {
79-
@Override
80-
public void run() {
81-
cmakeListsDocument.insertString(cmakeListsDocument
82-
.getTextLength(), "\nset(${CMAKE_PROJECT_NAME}_SKETCH ${CMAKE_PROJECT_NAME}.ino)\ngenerate_arduino_firmware(${CMAKE_PROJECT_NAME})\n");
83-
}
84-
}, null, null, cmakeListsDocument);
85-
}
86-
});
87-
88-
app.runWriteAction(new Runnable() {
89-
@Override
90-
public void run() {
91-
PsiDirectory cmakeDirectory = projectRootDirectory.createSubdirectory("cmake");
92-
PsiDirectory platformDirectory = cmakeDirectory.createSubdirectory("Platform");
93-
94-
PsiFile arduinoToolchain = cmakeDirectory.createFile("ArduinoToolchain.cmake");
95-
PsiFile arduino = platformDirectory.createFile("Arduino.cmake");
96-
97-
VirtualFile arduinoToolchainVirtualFile = arduinoToolchain.getVirtualFile();
98-
VirtualFile arduinoVirtualFile = arduino.getVirtualFile();
59+
public void deleteBuildOutputDir(Project project) {
60+
try {
61+
FileUtils.deleteDirectory(CMakeWorkspace.getInstance(project).getProjectGeneratedDir());
62+
} catch (IOException e1) {
63+
e1.printStackTrace();
64+
}
65+
}
9966

100-
try {
101-
OutputStream arduinoToolchainOutputStream = arduinoToolchainVirtualFile.getOutputStream(null);
102-
OutputStream arduinoOutputStream = arduinoVirtualFile.getOutputStream(null);
67+
public VirtualFile getMainSketchFile(Project project) {
68+
VirtualFile projectBaseDir = project.getBaseDir();
69+
String projectName = project.getName();
10370

104-
IOUtils.copyStreamToStream(ArduinoToolchainFiles.ARDUINO_TOOLCHAIN_CMAKE, arduinoToolchainOutputStream);
105-
IOUtils.copyStreamToStream(ArduinoToolchainFiles.ARDUINO_CMAKE, arduinoOutputStream);
106-
} catch (IOException e1) {
107-
e1.printStackTrace();
108-
}
71+
VirtualFile mainInoFile = projectBaseDir.findChild(projectName + Strings.DOT_INO_EXT);
72+
if (mainInoFile == null) {
73+
VirtualFile mainPdeFile = projectBaseDir.findChild(projectName + Strings.DOT_PDE_EXT);
74+
if (mainPdeFile == null) {
75+
return ArduinoSketchFileCreator
76+
.createSketchFileWithName(project, projectBaseDir, projectName + Strings.DOT_INO_EXT);
77+
} else {
78+
return mainPdeFile;
10979
}
110-
});
111-
80+
} else {
81+
return mainInoFile;
82+
}
11283
}
11384
}

0 commit comments

Comments
 (0)