mirror of
https://github.com/arduino/Arduino.git
synced 2025-02-26 20:54:22 +01:00
Testing autocomplete with arduino-preprocessor
This commit is contained in:
parent
ff17c8667f
commit
42930e22b0
@ -55,5 +55,6 @@
|
||||
<classpathentry kind="lib" path="lib/jtouchbar-1.0.0.jar"/>
|
||||
<classpathentry kind="lib" path="lib/commons-lang3-3.8.1.jar"/>
|
||||
<classpathentry kind="lib" path="lib/jssc-2.8.0-arduino4.jar"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/AutoComplete"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
|
61
app/src/cc/arduino/autocomplete/ArduinoCompletionsList.java
Normal file
61
app/src/cc/arduino/autocomplete/ArduinoCompletionsList.java
Normal file
@ -0,0 +1,61 @@
|
||||
package cc.arduino.autocomplete;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ArduinoCompletionsList extends ArrayList<ArduinoCompletion> {
|
||||
}
|
||||
|
||||
class ArduinoCompletion {
|
||||
ArduinoCompletionDetail completion;
|
||||
String type;
|
||||
|
||||
public ArduinoCompletionDetail getCompletion() {
|
||||
return completion;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
class ArduinoCompletionDetail {
|
||||
List<CompletionChunk> chunks;
|
||||
String brief;
|
||||
|
||||
public List<CompletionChunk> getChunks() {
|
||||
return chunks;
|
||||
}
|
||||
|
||||
public String getBrief() {
|
||||
return brief;
|
||||
}
|
||||
}
|
||||
|
||||
class CompletionChunk {
|
||||
String typedtext;
|
||||
String t;
|
||||
String placeholder;
|
||||
String res;
|
||||
ArduinoCompletionDetail optional;
|
||||
|
||||
public String getTypedtext() {
|
||||
return typedtext;
|
||||
}
|
||||
|
||||
public String getT() {
|
||||
return t;
|
||||
}
|
||||
|
||||
public String getPlaceholder() {
|
||||
return placeholder;
|
||||
}
|
||||
|
||||
public String getRes() {
|
||||
return res;
|
||||
}
|
||||
|
||||
public ArduinoCompletionDetail getOptional() {
|
||||
return optional;
|
||||
}
|
||||
}
|
@ -7,7 +7,7 @@ import org.fife.ui.autocomplete.DefaultCompletionProvider;
|
||||
* @author Ricardo JL Rufino (ricardo@criativasoft.com.br)
|
||||
* @date 28/04/2017
|
||||
*/
|
||||
public class BaseCCompletionProvider extends DefaultCompletionProvider{
|
||||
public class BaseCCompletionProvider extends DefaultCompletionProvider {
|
||||
|
||||
@Override
|
||||
protected boolean isValidChar(char ch) {
|
||||
|
88
app/src/cc/arduino/autocomplete/ClangCompletionProvider.java
Normal file
88
app/src/cc/arduino/autocomplete/ClangCompletionProvider.java
Normal file
@ -0,0 +1,88 @@
|
||||
package cc.arduino.autocomplete;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.text.BadLocationException;
|
||||
import javax.swing.text.JTextComponent;
|
||||
|
||||
import org.fife.ui.autocomplete.Completion;
|
||||
import org.fife.ui.autocomplete.TemplateCompletion;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import processing.app.Editor;
|
||||
import processing.app.EditorTab;
|
||||
|
||||
public class ClangCompletionProvider extends BaseCCompletionProvider {
|
||||
|
||||
private Editor editor;
|
||||
|
||||
public ClangCompletionProvider(Editor e) {
|
||||
super();
|
||||
editor = e;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Completion> getCompletionByInputText(String inputText) {
|
||||
System.out.println("INPUTTEXT: " + inputText);
|
||||
return super.getCompletionByInputText(inputText);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<Completion> getCompletionsImpl(JTextComponent textarea) {
|
||||
|
||||
// Retrieve current line and column
|
||||
EditorTab tab = editor.getCurrentTab();
|
||||
int line, col;
|
||||
try {
|
||||
int pos = tab.getTextArea().getCaretPosition();
|
||||
line = tab.getTextArea().getLineOfOffset(pos);
|
||||
col = pos - tab.getTextArea().getLineStartOffset(line);
|
||||
line++;
|
||||
col++;
|
||||
} catch (BadLocationException e1) {
|
||||
// Should never happen...
|
||||
e1.printStackTrace();
|
||||
return completions;
|
||||
}
|
||||
|
||||
try {
|
||||
// Run codecompletion engine
|
||||
String out = editor.getSketchController()
|
||||
.codeComplete(tab.getSketchFile(), line, col);
|
||||
|
||||
List<Completion> res = new ArrayList<>();
|
||||
res.add(new TemplateCompletion(this, "for", "interate over array",
|
||||
"for (int ${i} = 0; ${i} < ${array}.length; ${i}++) {\n ${cursor}\n}"));
|
||||
|
||||
// Parse engine output and build code completions
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
ArduinoCompletionsList allCc;
|
||||
allCc = mapper.readValue(out, ArduinoCompletionsList.class);
|
||||
for (ArduinoCompletion cc : allCc) {
|
||||
if (cc.type.equals("macro")) {
|
||||
// for now skip macro
|
||||
continue;
|
||||
}
|
||||
String returnType;
|
||||
String typedText;
|
||||
String template = "";
|
||||
for (CompletionChunk chunk : cc.completion.chunks) {
|
||||
if (chunk.t != null) {
|
||||
template += "t";
|
||||
}
|
||||
if (chunk.res != null) {
|
||||
returnType = chunk.res;
|
||||
}
|
||||
if (chunk.typedtext != null) {
|
||||
typedText = chunk.typedtext;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return completions;
|
||||
}
|
||||
}
|
@ -58,6 +58,7 @@ import java.nio.file.Path;
|
||||
import java.io.File;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.fife.ui.autocomplete.AutoCompletion;
|
||||
import org.fife.ui.rsyntaxtextarea.RSyntaxDocument;
|
||||
import org.fife.ui.rsyntaxtextarea.RSyntaxTextAreaEditorKit;
|
||||
import org.fife.ui.rsyntaxtextarea.RSyntaxUtilities;
|
||||
@ -65,7 +66,7 @@ import org.fife.ui.rtextarea.Gutter;
|
||||
import org.fife.ui.rtextarea.RTextScrollPane;
|
||||
|
||||
import cc.arduino.UpdatableBoardsLibsFakeURLsHandler;
|
||||
import cc.arduino.autocomplete.FakeCompletionProvider;
|
||||
import cc.arduino.autocomplete.ClangCompletionProvider;
|
||||
import processing.app.helpers.DocumentTextChangeListener;
|
||||
import processing.app.syntax.ArduinoTokenMakerFactory;
|
||||
import processing.app.syntax.PdeKeywords;
|
||||
@ -120,7 +121,17 @@ public class EditorTab extends JPanel implements SketchFile.TextStorage {
|
||||
applyPreferences();
|
||||
add(scrollPane, BorderLayout.CENTER);
|
||||
editor.base.addEditorFontResizeMouseWheelListener(textarea);
|
||||
textarea.setupAutoComplete(file.getSketch(), new FakeCompletionProvider());
|
||||
// SketchCompletionProvider completionProvider = new SketchCompletionProvider(
|
||||
// editor.getSketch(), textarea, new ClangCompletionProvider(editor));
|
||||
|
||||
AutoCompletion ac = new AutoCompletion(new ClangCompletionProvider(editor));
|
||||
ac.setAutoActivationEnabled(true);
|
||||
ac.setShowDescWindow(false);
|
||||
ac.setAutoCompleteSingleChoices(true);
|
||||
ac.setParameterAssistanceEnabled(true);
|
||||
// ac.setParamChoicesRenderer(new CompletionsRenderer());
|
||||
// ac.setListCellRenderer(new CompletionsRenderer());
|
||||
ac.install(textarea);
|
||||
}
|
||||
|
||||
private RSyntaxDocument createDocument(String contents) {
|
||||
|
@ -680,6 +680,40 @@ public class SketchController {
|
||||
return Paths.get(tempFolder.getAbsolutePath(), sketch.getPrimaryFile().getFileName()).toFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Preprocess sketch and obtain code-completions.
|
||||
*
|
||||
* @return null if compilation failed, main class name if not
|
||||
*/
|
||||
public String codeComplete(SketchFile file, int line, int col) throws RunnerException, PreferencesMapException, IOException {
|
||||
// run the preprocessor
|
||||
for (CompilerProgressListener progressListener : editor.status.getCompilerProgressListeners()){
|
||||
progressListener.progress(20);
|
||||
}
|
||||
|
||||
ensureExistence();
|
||||
|
||||
boolean deleteTemp = false;
|
||||
File pathToSketch = sketch.getPrimaryFile().getFile();
|
||||
File requestedFile = file.getFile();
|
||||
if (sketch.isModified()) {
|
||||
// If any files are modified, make a copy of the sketch with the changes
|
||||
// saved, so arduino-builder will see the modifications.
|
||||
pathToSketch = saveSketchInTempFolder();
|
||||
// This takes into account when the sketch is copied into a temporary folder
|
||||
requestedFile = new File(pathToSketch.getParent(), requestedFile.getName());
|
||||
deleteTemp = true;
|
||||
}
|
||||
|
||||
try {
|
||||
return new Compiler(pathToSketch, sketch).codeComplete(editor.status.getCompilerProgressListeners(), requestedFile, line, col);
|
||||
} finally {
|
||||
// Make sure we clean up any temporary sketch copy
|
||||
if (deleteTemp)
|
||||
FileUtils.recursiveDelete(pathToSketch.getParentFile());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle export to applet.
|
||||
*/
|
||||
|
@ -135,22 +135,6 @@ public class SketchTextArea extends RSyntaxTextArea {
|
||||
setLinkGenerator(new DocLinkGenerator(pdeKeywords));
|
||||
}
|
||||
|
||||
public void setupAutoComplete(Sketch sketch, CompletionProvider provider) {
|
||||
|
||||
SketchCompletionProvider completionProvider = new SketchCompletionProvider(sketch, this, provider);
|
||||
|
||||
AutoCompletion ac = new AutoCompletion( completionProvider );
|
||||
|
||||
ac.setAutoActivationEnabled(true);
|
||||
ac.setShowDescWindow(false);
|
||||
ac.setAutoCompleteSingleChoices(true);
|
||||
ac.setParameterAssistanceEnabled(true);
|
||||
// ac.setParamChoicesRenderer(new CompletionsRenderer());
|
||||
// ac.setListCellRenderer(new CompletionsRenderer());
|
||||
ac.install(this);
|
||||
|
||||
}
|
||||
|
||||
private void installFeatures() throws IOException {
|
||||
setTheme(PreferencesData.get("editor.syntax_theme", "default"));
|
||||
|
||||
|
@ -125,7 +125,7 @@ public class Compiler implements MessageConsumer {
|
||||
}
|
||||
|
||||
enum BuilderAction {
|
||||
COMPILE("-compile"), DUMP_PREFS("-dump-prefs");
|
||||
COMPILE("-compile"), DUMP_PREFS("-dump-prefs"), CODE_COMPLETE("-code-complete-at");
|
||||
|
||||
final String value;
|
||||
|
||||
@ -143,6 +143,10 @@ public class Compiler implements MessageConsumer {
|
||||
private final boolean verbose;
|
||||
private RunnerException exception;
|
||||
|
||||
private File codeCompleteFile;
|
||||
private int codeCompleteLine;
|
||||
private int codeCompleteCol;
|
||||
|
||||
public Compiler(Sketch data) {
|
||||
this(data.getPrimaryFile().getFile(), data);
|
||||
}
|
||||
@ -193,6 +197,34 @@ public class Compiler implements MessageConsumer {
|
||||
return sketch.getPrimaryFile().getFileName();
|
||||
}
|
||||
|
||||
public String codeComplete(ArrayList<CompilerProgressListener> progListeners, File file, int line, int col) throws RunnerException, PreferencesMapException, IOException {
|
||||
this.buildPath = sketch.getBuildPath().getAbsolutePath();
|
||||
this.buildCache = BaseNoGui.getCachePath();
|
||||
|
||||
TargetBoard board = BaseNoGui.getTargetBoard();
|
||||
if (board == null) {
|
||||
throw new RunnerException("Board is not selected");
|
||||
}
|
||||
|
||||
TargetPlatform platform = board.getContainerPlatform();
|
||||
TargetPackage aPackage = platform.getContainerPackage();
|
||||
String vidpid = VIDPID();
|
||||
|
||||
ByteArrayOutputStream completions = new ByteArrayOutputStream();
|
||||
MessageConsumerOutputStream out = new MessageConsumerOutputStream(new ProgressAwareMessageConsumer(new I18NAwareMessageConsumer(new PrintStream(completions), System.err), progListeners), "\n");
|
||||
MessageConsumerOutputStream err = new MessageConsumerOutputStream(new I18NAwareMessageConsumer(System.err, Compiler.this), "\n");
|
||||
|
||||
codeCompleteFile = file;
|
||||
codeCompleteLine = line;
|
||||
codeCompleteCol = col;
|
||||
callArduinoBuilder(board, platform, aPackage, vidpid, BuilderAction.CODE_COMPLETE, out, err);
|
||||
|
||||
out.flush();
|
||||
err.flush();
|
||||
|
||||
return completions.toString();
|
||||
}
|
||||
|
||||
private String VIDPID() {
|
||||
BoardPort boardPort = BaseNoGui.getDiscoveryManager().find(PreferencesData.get("serial.port"));
|
||||
if (boardPort == null) {
|
||||
@ -234,6 +266,9 @@ public class Compiler implements MessageConsumer {
|
||||
List<String> cmd = new ArrayList<>();
|
||||
cmd.add(BaseNoGui.getContentFile("arduino-builder").getAbsolutePath());
|
||||
cmd.add(action.value);
|
||||
if (action == BuilderAction.CODE_COMPLETE) {
|
||||
cmd.add(codeCompleteFile.getAbsolutePath() + ":" + codeCompleteLine + ":" + codeCompleteCol);
|
||||
}
|
||||
cmd.add("-logger=machine");
|
||||
|
||||
File installedPackagesFolder = new File(BaseNoGui.getSettingsFolder(), "packages");
|
||||
@ -280,9 +315,7 @@ public class Compiler implements MessageConsumer {
|
||||
}
|
||||
}
|
||||
|
||||
//commandLine.addArgument("-debug-level=10", false);
|
||||
|
||||
if (verbose) {
|
||||
if (verbose && action != BuilderAction.CODE_COMPLETE) {
|
||||
cmd.add("-verbose");
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user