diff --git a/app/.classpath b/app/.classpath index 51172fa7c40..ebf253e4e58 100644 --- a/app/.classpath +++ b/app/.classpath @@ -4,7 +4,6 @@ - @@ -44,6 +43,7 @@ + @@ -53,4 +53,5 @@ + diff --git a/app/lib/autocomplete-2.6.1.jar b/app/lib/autocomplete-2.6.1.jar new file mode 100755 index 00000000000..46964593fea Binary files /dev/null and b/app/lib/autocomplete-2.6.1.jar differ diff --git a/app/src/cc/arduino/autocomplete/CompletionContext.java b/app/src/cc/arduino/autocomplete/CompletionContext.java new file mode 100755 index 00000000000..18f985243d1 --- /dev/null +++ b/app/src/cc/arduino/autocomplete/CompletionContext.java @@ -0,0 +1,44 @@ +package cc.arduino.autocomplete; + +import org.fife.ui.autocomplete.CompletionProvider; + +import processing.app.Sketch; +import processing.app.syntax.SketchTextArea; + +public class CompletionContext { + + private Sketch sketch; + + private SketchTextArea textArea; + + private CompletionProvider delegate; // of: AutoComplete/RSyntaxTextArea + + public CompletionContext(Sketch sketch, SketchTextArea textArea,CompletionProvider delegate) { + this.sketch = sketch; + this.textArea = textArea; + this.delegate = delegate; + } + + + public String getAlreadyEnteredText() { + return delegate.getAlreadyEnteredText(textArea); + } + + public int getLineNumber() { + return textArea.getCaretLineNumber(); + } + + + public Sketch getSketch() { + return sketch; + } + + public SketchTextArea getTextArea() { + return textArea; + } + + public CompletionProvider getDelegate() { + return delegate; + } + +} diff --git a/app/src/cc/arduino/autocomplete/CompletionProvider.java b/app/src/cc/arduino/autocomplete/CompletionProvider.java new file mode 100755 index 00000000000..8f7ac8b797e --- /dev/null +++ b/app/src/cc/arduino/autocomplete/CompletionProvider.java @@ -0,0 +1,11 @@ +package cc.arduino.autocomplete; + +import java.util.List; + +import org.fife.ui.autocomplete.Completion; + +public interface CompletionProvider { + + List getSuggestions(CompletionContext context); + +} \ No newline at end of file diff --git a/app/src/cc/arduino/autocomplete/FakeCompletionProvider.java b/app/src/cc/arduino/autocomplete/FakeCompletionProvider.java new file mode 100755 index 00000000000..783aefd2339 --- /dev/null +++ b/app/src/cc/arduino/autocomplete/FakeCompletionProvider.java @@ -0,0 +1,22 @@ +package cc.arduino.autocomplete; + +import java.util.LinkedList; +import java.util.List; + +import org.fife.ui.autocomplete.BasicCompletion; +import org.fife.ui.autocomplete.Completion; + +public class FakeCompletionProvider implements CompletionProvider { + + + @Override + public List getSuggestions(CompletionContext context) { + List list = new LinkedList<>(); + list.add(new BasicCompletion(context.getDelegate(), "Text: " + context.getAlreadyEnteredText())); + list.add(new BasicCompletion(context.getDelegate(), "Line: " + context.getLineNumber())); + + return list; + } + + +} diff --git a/app/src/cc/arduino/autocomplete/rsyntax/CompletionProviderBridge.java b/app/src/cc/arduino/autocomplete/rsyntax/CompletionProviderBridge.java new file mode 100755 index 00000000000..547668fcd74 --- /dev/null +++ b/app/src/cc/arduino/autocomplete/rsyntax/CompletionProviderBridge.java @@ -0,0 +1,36 @@ +package cc.arduino.autocomplete.rsyntax; + +import java.util.List; + +import javax.swing.text.JTextComponent; + +import org.fife.ui.autocomplete.Completion; +import org.fife.ui.autocomplete.DefaultCompletionProvider; + +import cc.arduino.autocomplete.CompletionContext; +import cc.arduino.autocomplete.CompletionProvider; + +public class CompletionProviderBridge extends DefaultCompletionProvider{ + + private CompletionProvider provider; + + private CompletionContext context; + + public CompletionProviderBridge(CompletionContext context, CompletionProvider provider) { + this.provider = provider; + this.context = context; + } + + + @Override + public List getCompletionsImpl(JTextComponent comp) { + return provider.getSuggestions(context); + + } + + @Override + protected boolean isValidChar(char ch) { + return super.isValidChar(ch) || '.' == ch || '>' == ch || '-' == ch || '<' == ch || '#' == ch || ':' == ch /**|| getParameterListStart() == ch */; + } + +} diff --git a/app/src/cc/arduino/autocomplete/rsyntax/SketchCompletionProvider.java b/app/src/cc/arduino/autocomplete/rsyntax/SketchCompletionProvider.java new file mode 100755 index 00000000000..39a609d62dc --- /dev/null +++ b/app/src/cc/arduino/autocomplete/rsyntax/SketchCompletionProvider.java @@ -0,0 +1,33 @@ +package cc.arduino.autocomplete.rsyntax; + +import org.fife.ui.autocomplete.LanguageAwareCompletionProvider; + +import cc.arduino.autocomplete.CompletionContext; +import cc.arduino.autocomplete.CompletionProvider; +import processing.app.Sketch; +import processing.app.syntax.SketchTextArea; + + +/** + * CompletionProvider for Arduino/CPP Language.
+ * Setup basic logic for completions using {@link LanguageAwareCompletionProvider} + * Filtering and decision will appear in the autocomplete dialog by implementations of: {@link CompletionProvider}.
+ * + * @author Ricardo JL Rufino (ricardo@criativasoft.com.br) + * @date 28/04/2017 + */ +public class SketchCompletionProvider extends LanguageAwareCompletionProvider{ + + public SketchCompletionProvider(Sketch sketch, SketchTextArea textArea, CompletionProvider provider) { + + CompletionContext context = new CompletionContext(sketch, textArea, this); + + setDefaultCompletionProvider(new CompletionProviderBridge(context, provider)); +// provider.setParameterChoicesProvider(new ParameterChoicesProvider(this)); +// provider.setParameterizedCompletionParams('(', ", ", ')'); + + } + + + +} \ No newline at end of file diff --git a/app/src/processing/app/EditorTab.java b/app/src/processing/app/EditorTab.java index 618bcf3c199..c57336c9a85 100644 --- a/app/src/processing/app/EditorTab.java +++ b/app/src/processing/app/EditorTab.java @@ -66,6 +66,7 @@ import org.fife.ui.rtextarea.RTextScrollPane; import cc.arduino.UpdatableBoardsLibsFakeURLsHandler; +import cc.arduino.autocomplete.FakeCompletionProvider; import processing.app.helpers.DocumentTextChangeListener; import processing.app.syntax.ArduinoTokenMakerFactory; import processing.app.syntax.PdeKeywords; @@ -120,6 +121,7 @@ public EditorTab(Editor editor, SketchFile file, String contents) applyPreferences(); add(scrollPane, BorderLayout.CENTER); textarea.addMouseWheelListener(this); + textarea.setupAutoComplete(file.getSketch(), new FakeCompletionProvider()); } private RSyntaxDocument createDocument(String contents) { diff --git a/app/src/processing/app/syntax/SketchTextArea.java b/app/src/processing/app/syntax/SketchTextArea.java index ce74a3f1f8f..d83c5e014a4 100644 --- a/app/src/processing/app/syntax/SketchTextArea.java +++ b/app/src/processing/app/syntax/SketchTextArea.java @@ -66,6 +66,49 @@ import processing.app.Base; import processing.app.PreferencesData; + +import javax.swing.event.EventListenerList; +import javax.swing.event.HyperlinkEvent; +import javax.swing.event.HyperlinkListener; +import javax.swing.text.BadLocationException; +import javax.swing.text.Segment; +import java.awt.*; +import java.awt.event.MouseEvent; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Map; +import java.util.logging.Logger; + +import javax.swing.KeyStroke; +import javax.swing.event.EventListenerList; +import javax.swing.event.HyperlinkEvent; +import javax.swing.event.HyperlinkListener; +import javax.swing.text.BadLocationException; +import javax.swing.text.Segment; + +import org.apache.commons.compress.utils.IOUtils; +import org.fife.ui.autocomplete.AutoCompletion; +import org.fife.ui.rsyntaxtextarea.LinkGenerator; +import org.fife.ui.rsyntaxtextarea.LinkGeneratorResult; +import org.fife.ui.rsyntaxtextarea.RSyntaxDocument; +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; +import org.fife.ui.rsyntaxtextarea.Style; +import org.fife.ui.rsyntaxtextarea.Theme; +import org.fife.ui.rsyntaxtextarea.Token; +import org.fife.ui.rsyntaxtextarea.TokenImpl; +import org.fife.ui.rsyntaxtextarea.TokenTypes; +import org.fife.ui.rtextarea.RTextArea; +import org.fife.ui.rtextarea.RTextAreaUI; + +import cc.arduino.autocomplete.CompletionProvider; +import cc.arduino.autocomplete.rsyntax.SketchCompletionProvider; +import processing.app.Base; +import processing.app.BaseNoGui; +import processing.app.PreferencesData; +import processing.app.Sketch; import processing.app.helpers.OSUtils; /** @@ -79,6 +122,8 @@ public class SketchTextArea extends RSyntaxTextArea { private final static Logger LOG = Logger.getLogger(SketchTextArea.class.getName()); private PdeKeywords pdeKeywords; + + private SketchCompletionProvider completionProvider; public SketchTextArea(RSyntaxDocument document, PdeKeywords pdeKeywords) throws IOException { super(document); @@ -91,6 +136,22 @@ public void setKeywords(PdeKeywords keywords) { pdeKeywords = keywords; setLinkGenerator(new DocLinkGenerator(pdeKeywords)); } + + public void setupAutoComplete(Sketch sketch, CompletionProvider provider) { + + this.completionProvider = new SketchCompletionProvider(sketch, this, provider); + + AutoCompletion ac = new AutoCompletion( this.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")); diff --git a/arduino-core/src/processing/app/SketchFile.java b/arduino-core/src/processing/app/SketchFile.java index f1341653b57..9e0f1873293 100644 --- a/arduino-core/src/processing/app/SketchFile.java +++ b/arduino-core/src/processing/app/SketchFile.java @@ -246,6 +246,10 @@ public boolean isModified() { public boolean equals(Object o) { return (o instanceof SketchFile) && file.equals(((SketchFile) o).file); } + + public Sketch getSketch() { + return sketch; + } /** * Load this piece of code from a file and return the contents. This