Skip to content

Commit aa02646

Browse files
cmagliefacchinm
authored andcommitted
Testing autocomplete with arduino-preprocessor
1 parent e255865 commit aa02646

File tree

8 files changed

+235
-24
lines changed

8 files changed

+235
-24
lines changed

app/.classpath

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343
<classpathentry kind="lib" path="lib/jsch-0.1.50.jar"/>
4444
<classpathentry kind="lib" path="lib/jssc-2.8.0-arduino1.jar"/>
4545
<classpathentry kind="lib" path="lib/rsyntaxtextarea-2.6.1.jar"/>
46-
<classpathentry kind="lib" path="lib/autocomplete-2.6.1.jar" sourcepath="/media/ricardo/Dados/Workspace/Arduino/arduino-dep/AutoComplete-2.6.1"/>
4746
<classpathentry kind="lib" path="lib/xml-apis-1.3.04.jar"/>
4847
<classpathentry kind="lib" path="lib/xml-apis-ext-1.3.04.jar"/>
4948
<classpathentry kind="lib" path="lib/xmlgraphics-commons-2.0.jar"/>
@@ -53,5 +52,6 @@
5352
<classpathentry kind="lib" path="test-lib/fest-swing-1.2.jar"/>
5453
<classpathentry kind="lib" path="test-lib/fest-util-1.1.2.jar"/>
5554
<classpathentry kind="lib" path="test-lib/jcip-annotations-1.0.jar"/>
55+
<classpathentry combineaccessrules="false" kind="src" path="/AutoComplete"/>
5656
<classpathentry kind="output" path="bin"/>
5757
</classpath>
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package cc.arduino.autocomplete;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
public class ArduinoCompletionsList extends ArrayList<ArduinoCompletion> {
7+
}
8+
9+
class ArduinoCompletion {
10+
ArduinoCompletionDetail completion;
11+
String type;
12+
13+
public ArduinoCompletionDetail getCompletion() {
14+
return completion;
15+
}
16+
17+
public String getType() {
18+
return type;
19+
}
20+
}
21+
22+
class ArduinoCompletionDetail {
23+
List<CompletionChunk> chunks;
24+
String brief;
25+
26+
public List<CompletionChunk> getChunks() {
27+
return chunks;
28+
}
29+
30+
public String getBrief() {
31+
return brief;
32+
}
33+
}
34+
35+
class CompletionChunk {
36+
String typedtext;
37+
String t;
38+
String placeholder;
39+
String res;
40+
ArduinoCompletionDetail optional;
41+
42+
public String getTypedtext() {
43+
return typedtext;
44+
}
45+
46+
public String getT() {
47+
return t;
48+
}
49+
50+
public String getPlaceholder() {
51+
return placeholder;
52+
}
53+
54+
public String getRes() {
55+
return res;
56+
}
57+
58+
public ArduinoCompletionDetail getOptional() {
59+
return optional;
60+
}
61+
}

app/src/cc/arduino/autocomplete/BaseCCompletionProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @author Ricardo JL Rufino (ricardo@criativasoft.com.br)
88
* @date 28/04/2017
99
*/
10-
public class BaseCCompletionProvider extends DefaultCompletionProvider{
10+
public class BaseCCompletionProvider extends DefaultCompletionProvider {
1111

1212
@Override
1313
protected boolean isValidChar(char ch) {
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package cc.arduino.autocomplete;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
import javax.swing.text.BadLocationException;
7+
import javax.swing.text.JTextComponent;
8+
9+
import org.fife.ui.autocomplete.Completion;
10+
import org.fife.ui.autocomplete.TemplateCompletion;
11+
12+
import com.fasterxml.jackson.databind.ObjectMapper;
13+
14+
import processing.app.Editor;
15+
import processing.app.EditorTab;
16+
17+
public class ClangCompletionProvider extends BaseCCompletionProvider {
18+
19+
private Editor editor;
20+
21+
public ClangCompletionProvider(Editor e) {
22+
super();
23+
editor = e;
24+
}
25+
26+
@Override
27+
public List<Completion> getCompletionByInputText(String inputText) {
28+
System.out.println("INPUTTEXT: " + inputText);
29+
return super.getCompletionByInputText(inputText);
30+
}
31+
32+
@Override
33+
protected List<Completion> getCompletionsImpl(JTextComponent textarea) {
34+
35+
// Retrieve current line and column
36+
EditorTab tab = editor.getCurrentTab();
37+
int line, col;
38+
try {
39+
int pos = tab.getTextArea().getCaretPosition();
40+
line = tab.getTextArea().getLineOfOffset(pos);
41+
col = pos - tab.getTextArea().getLineStartOffset(line);
42+
line++;
43+
col++;
44+
} catch (BadLocationException e1) {
45+
// Should never happen...
46+
e1.printStackTrace();
47+
return completions;
48+
}
49+
50+
try {
51+
// Run codecompletion engine
52+
String out = editor.getSketchController()
53+
.codeComplete(tab.getSketchFile(), line, col);
54+
55+
List<Completion> res = new ArrayList<>();
56+
res.add(new TemplateCompletion(this, "for", "interate over array",
57+
"for (int ${i} = 0; ${i} < ${array}.length; ${i}++) {\n ${cursor}\n}"));
58+
59+
// Parse engine output and build code completions
60+
ObjectMapper mapper = new ObjectMapper();
61+
ArduinoCompletionsList allCc;
62+
allCc = mapper.readValue(out, ArduinoCompletionsList.class);
63+
for (ArduinoCompletion cc : allCc) {
64+
if (cc.type.equals("macro")) {
65+
// for now skip macro
66+
continue;
67+
}
68+
String returnType;
69+
String typedText;
70+
String template = "";
71+
for (CompletionChunk chunk : cc.completion.chunks) {
72+
if (chunk.t != null) {
73+
template += "t";
74+
}
75+
if (chunk.res != null) {
76+
returnType = chunk.res;
77+
}
78+
if (chunk.typedtext != null) {
79+
typedText = chunk.typedtext;
80+
}
81+
}
82+
}
83+
} catch (Exception e) {
84+
e.printStackTrace();
85+
}
86+
return completions;
87+
}
88+
}

app/src/processing/app/EditorTab.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,15 @@
5050
import javax.swing.text.DefaultCaret;
5151
import javax.swing.text.Document;
5252

53+
import org.fife.ui.autocomplete.AutoCompletion;
5354
import org.fife.ui.rsyntaxtextarea.RSyntaxDocument;
5455
import org.fife.ui.rsyntaxtextarea.RSyntaxTextAreaEditorKit;
5556
import org.fife.ui.rsyntaxtextarea.RSyntaxUtilities;
5657
import org.fife.ui.rtextarea.Gutter;
5758
import org.fife.ui.rtextarea.RTextScrollPane;
5859

5960
import cc.arduino.UpdatableBoardsLibsFakeURLsHandler;
60-
import cc.arduino.autocomplete.FakeCompletionProvider;
61+
import cc.arduino.autocomplete.ClangCompletionProvider;
6162
import processing.app.helpers.DocumentTextChangeListener;
6263
import processing.app.syntax.ArduinoTokenMakerFactory;
6364
import processing.app.syntax.PdeKeywords;
@@ -111,7 +112,17 @@ public EditorTab(Editor editor, SketchFile file, String contents)
111112
applyPreferences();
112113
add(scrollPane, BorderLayout.CENTER);
113114
textarea.addMouseWheelListener(this);
114-
textarea.setupAutoComplete(file.getSketch(), new FakeCompletionProvider());
115+
// SketchCompletionProvider completionProvider = new SketchCompletionProvider(
116+
// editor.getSketch(), textarea, new ClangCompletionProvider(editor));
117+
118+
AutoCompletion ac = new AutoCompletion(new ClangCompletionProvider(editor));
119+
ac.setAutoActivationEnabled(true);
120+
ac.setShowDescWindow(false);
121+
ac.setAutoCompleteSingleChoices(true);
122+
ac.setParameterAssistanceEnabled(true);
123+
// ac.setParamChoicesRenderer(new CompletionsRenderer());
124+
// ac.setListCellRenderer(new CompletionsRenderer());
125+
ac.install(textarea);
115126
}
116127

117128
private RSyntaxDocument createDocument(String contents) {

app/src/processing/app/SketchController.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,40 @@ private File saveSketchInTempFolder() throws IOException {
663663
return Paths.get(tempFolder.getAbsolutePath(), sketch.getPrimaryFile().getFileName()).toFile();
664664
}
665665

666+
/**
667+
* Preprocess sketch and obtain code-completions.
668+
*
669+
* @return null if compilation failed, main class name if not
670+
*/
671+
public String codeComplete(SketchFile file, int line, int col) throws RunnerException, PreferencesMapException, IOException {
672+
// run the preprocessor
673+
for (CompilerProgressListener progressListener : editor.status.getCompilerProgressListeners()){
674+
progressListener.progress(20);
675+
}
676+
677+
ensureExistence();
678+
679+
boolean deleteTemp = false;
680+
File pathToSketch = sketch.getPrimaryFile().getFile();
681+
File requestedFile = file.getFile();
682+
if (sketch.isModified()) {
683+
// If any files are modified, make a copy of the sketch with the changes
684+
// saved, so arduino-builder will see the modifications.
685+
pathToSketch = saveSketchInTempFolder();
686+
// This takes into account when the sketch is copied into a temporary folder
687+
requestedFile = new File(pathToSketch.getParent(), requestedFile.getName());
688+
deleteTemp = true;
689+
}
690+
691+
try {
692+
return new Compiler(pathToSketch, sketch).codeComplete(editor.status.getCompilerProgressListeners(), requestedFile, line, col);
693+
} finally {
694+
// Make sure we clean up any temporary sketch copy
695+
if (deleteTemp)
696+
FileUtils.recursiveDelete(pathToSketch.getParentFile());
697+
}
698+
}
699+
666700
/**
667701
* Handle export to applet.
668702
*/

app/src/processing/app/syntax/SketchTextArea.java

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -98,22 +98,6 @@ public void setKeywords(PdeKeywords keywords) {
9898
setLinkGenerator(new DocLinkGenerator(pdeKeywords));
9999
}
100100

101-
public void setupAutoComplete(Sketch sketch, CompletionProvider provider) {
102-
103-
SketchCompletionProvider completionProvider = new SketchCompletionProvider(sketch, this, provider);
104-
105-
AutoCompletion ac = new AutoCompletion( completionProvider );
106-
107-
ac.setAutoActivationEnabled(true);
108-
ac.setShowDescWindow(false);
109-
ac.setAutoCompleteSingleChoices(true);
110-
ac.setParameterAssistanceEnabled(true);
111-
// ac.setParamChoicesRenderer(new CompletionsRenderer());
112-
// ac.setListCellRenderer(new CompletionsRenderer());
113-
ac.install(this);
114-
115-
}
116-
117101
private void installFeatures() throws IOException {
118102
setTheme(PreferencesData.get("editor.syntax_theme", "default"));
119103

arduino-core/src/cc/arduino/Compiler.java

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ public class Compiler implements MessageConsumer {
125125
}
126126

127127
enum BuilderAction {
128-
COMPILE("-compile"), DUMP_PREFS("-dump-prefs");
128+
COMPILE("-compile"), DUMP_PREFS("-dump-prefs"), CODE_COMPLETE("-code-complete-at");
129129

130130
final String value;
131131

@@ -143,6 +143,10 @@ enum BuilderAction {
143143
private final boolean verbose;
144144
private RunnerException exception;
145145

146+
private File codeCompleteFile;
147+
private int codeCompleteLine;
148+
private int codeCompleteCol;
149+
146150
public Compiler(Sketch data) {
147151
this(data.getPrimaryFile().getFile(), data);
148152
}
@@ -193,6 +197,34 @@ public String build(ArrayList<CompilerProgressListener> progListeners, boolean e
193197
return sketch.getPrimaryFile().getFileName();
194198
}
195199

200+
public String codeComplete(ArrayList<CompilerProgressListener> progListeners, File file, int line, int col) throws RunnerException, PreferencesMapException, IOException {
201+
this.buildPath = sketch.getBuildPath().getAbsolutePath();
202+
this.buildCache = BaseNoGui.getCachePath();
203+
204+
TargetBoard board = BaseNoGui.getTargetBoard();
205+
if (board == null) {
206+
throw new RunnerException("Board is not selected");
207+
}
208+
209+
TargetPlatform platform = board.getContainerPlatform();
210+
TargetPackage aPackage = platform.getContainerPackage();
211+
String vidpid = VIDPID();
212+
213+
ByteArrayOutputStream completions = new ByteArrayOutputStream();
214+
MessageConsumerOutputStream out = new MessageConsumerOutputStream(new ProgressAwareMessageConsumer(new I18NAwareMessageConsumer(new PrintStream(completions), System.err), progListeners), "\n");
215+
MessageConsumerOutputStream err = new MessageConsumerOutputStream(new I18NAwareMessageConsumer(System.err, Compiler.this), "\n");
216+
217+
codeCompleteFile = file;
218+
codeCompleteLine = line;
219+
codeCompleteCol = col;
220+
callArduinoBuilder(board, platform, aPackage, vidpid, BuilderAction.CODE_COMPLETE, out, err);
221+
222+
out.flush();
223+
err.flush();
224+
225+
return completions.toString();
226+
}
227+
196228
private String VIDPID() {
197229
BoardPort boardPort = BaseNoGui.getDiscoveryManager().find(PreferencesData.get("serial.port"));
198230
if (boardPort == null) {
@@ -234,6 +266,9 @@ private void callArduinoBuilder(TargetBoard board, TargetPlatform platform, Targ
234266
List<String> cmd = new ArrayList<>();
235267
cmd.add(BaseNoGui.getContentFile("arduino-builder").getAbsolutePath());
236268
cmd.add(action.value);
269+
if (action == BuilderAction.CODE_COMPLETE) {
270+
cmd.add(codeCompleteFile.getAbsolutePath() + ":" + codeCompleteLine + ":" + codeCompleteCol);
271+
}
237272
cmd.add("-logger=machine");
238273

239274
File installedPackagesFolder = new File(BaseNoGui.getSettingsFolder(), "packages");
@@ -280,9 +315,7 @@ private void callArduinoBuilder(TargetBoard board, TargetPlatform platform, Targ
280315
}
281316
}
282317

283-
//commandLine.addArgument("-debug-level=10", false);
284-
285-
if (verbose) {
318+
if (verbose && action != BuilderAction.CODE_COMPLETE) {
286319
cmd.add("-verbose");
287320
}
288321

0 commit comments

Comments
 (0)