Add basic code completion to editor

master
skylarmt 9 years ago
parent f34e03fd0c
commit cc72fcaade

Binary file not shown.

@ -31,6 +31,7 @@ dist.jar=${dist.dir}/SyMAT.jar
dist.javadoc.dir=${dist.dir}/javadoc
endorsed.classpath=
excludes=
file.reference.autocomplete-2.5.4.jar=lib/autocomplete-2.5.4.jar
file.reference.htmlcleaner-2.10.jar=lib/htmlcleaner-2.10.jar
file.reference.iText-4.2.0-com.itextpdf.jar=lib/iText-4.2.0-com.itextpdf.jar
file.reference.JavaPrettify-1.2.1.jar=lib/JavaPrettify-1.2.1.jar
@ -53,7 +54,8 @@ javac.classpath=\
${file.reference.js-engine.jar}:\
${file.reference.js.jar}:\
${file.reference.jython-standalone-2.7-b3.jar}:\
${file.reference.rsyntaxtextarea-2.5.6.jar}
${file.reference.rsyntaxtextarea-2.5.6.jar}:\
${file.reference.autocomplete-2.5.4.jar}
# Space-separated list of extra javac options
javac.compilerargs=
javac.deprecation=false

@ -0,0 +1,97 @@
/*
* Apocalypse Laboratories
* Open Source License
*
* Source code can be used for any purpose, as long as:
* - Compiled binaries are rebranded and trademarks are not
* visible by the end user at any time, except to give
* credit to Apocalypse Laboratories, such as by showing
* "Based on <product> by Apocalypse Laboratories" or a
* similar notice;
* - You do not use the code for evil;
* - Rebranded compiled applications have significant
* differences in functionality;
* - and you provide your modified source code for download,
* under the terms of the GNU LGPL v3 or a comparable
* license.
*
* Compiled binaries cannot be redistributed or mirrored,
* unless:
* - You have written permission from Apocalypse Laboratories;
* - Downloads are not available from Apocalypse Laboratories,
* not even behind a paywall or other blocking mechanism;
* - or you have received a multi-computer license, in which
* case you should take measures to prevent unauthorized
* downloads, such as preventing download access from the
* Internet.
*/
package net.apocalypselabs.symat;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import org.fife.ui.autocomplete.BasicCompletion;
import org.fife.ui.autocomplete.Completion;
import org.fife.ui.autocomplete.CompletionProvider;
import org.fife.ui.autocomplete.DefaultCompletionProvider;
import org.fife.ui.autocomplete.FunctionCompletion;
import org.fife.ui.autocomplete.MarkupTagCompletion;
import org.fife.ui.autocomplete.ShorthandCompletion;
import org.fife.ui.autocomplete.VariableCompletion;
/**
*
* @author Skylar
*/
public class CodeCompleter {
private final CompletionProvider provider;
private final String lang;
/**
*
* @param language Either js or py.
*/
public CodeCompleter(String language) {
lang = language;
provider = makeCompletions();
}
public CompletionProvider getProvider() {
return provider;
}
private CompletionProvider makeCompletions() {
DefaultCompletionProvider provider = new DefaultCompletionProvider();
try {
String[] files = {"functions", "constants"};
for (String fileid : files) {
BufferedReader reader = new BufferedReader(
new InputStreamReader(
CodeEditor.class.getResourceAsStream("resources/" + lang + fileid + ".txt")));
String line;
while ((line = reader.readLine()) != null) {
switch (fileid) {
case "functions":
String[] args = line.split("\\|");
if (args.length == 2) {
provider.addCompletion(new BasicCompletion(provider, args[0], args[1]));
} else if (args.length == 3) {
provider.addCompletion(new BasicCompletion(provider, args[0], args[1], args[2]));
} else {
provider.addCompletion(new BasicCompletion(provider, args[0]));
}
break;
case "constants":
provider.addCompletion(new VariableCompletion(provider, line, "double"));
break;
}
}
}
} catch (IOException ex) {
Debug.printerr(ex.getMessage());
}
return provider;
}
}

@ -108,17 +108,31 @@
<Property name="text" type="java.lang.String" value="Edit"/>
</Properties>
<SubComponents>
<MenuItem class="javax.swing.JMenuItem" name="copyBtn">
<MenuItem class="javax.swing.JMenuItem" name="undoBtn">
<Properties>
<Property name="accelerator" type="javax.swing.KeyStroke" editor="org.netbeans.modules.form.editors.KeyStrokeEditor">
<KeyStroke key="Ctrl+C"/>
<KeyStroke key="Ctrl+Z"/>
</Property>
<Property name="text" type="java.lang.String" value="Copy"/>
<Property name="text" type="java.lang.String" value="Undo"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="copyBtnActionPerformed"/>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="undoBtnActionPerformed"/>
</Events>
</MenuItem>
<MenuItem class="javax.swing.JMenuItem" name="redoBtn">
<Properties>
<Property name="accelerator" type="javax.swing.KeyStroke" editor="org.netbeans.modules.form.editors.KeyStrokeEditor">
<KeyStroke key="Ctrl+Y"/>
</Property>
<Property name="text" type="java.lang.String" value="Redo"/>
<Property name="toolTipText" type="java.lang.String" value=""/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="redoBtnActionPerformed"/>
</Events>
</MenuItem>
<MenuItem class="javax.swing.JPopupMenu$Separator" name="jSeparator1">
</MenuItem>
<MenuItem class="javax.swing.JMenuItem" name="cutBtn">
<Properties>
<Property name="accelerator" type="javax.swing.KeyStroke" editor="org.netbeans.modules.form.editors.KeyStrokeEditor">
@ -130,6 +144,17 @@
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cutBtnActionPerformed"/>
</Events>
</MenuItem>
<MenuItem class="javax.swing.JMenuItem" name="copyBtn">
<Properties>
<Property name="accelerator" type="javax.swing.KeyStroke" editor="org.netbeans.modules.form.editors.KeyStrokeEditor">
<KeyStroke key="Ctrl+C"/>
</Property>
<Property name="text" type="java.lang.String" value="Copy"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="copyBtnActionPerformed"/>
</Events>
</MenuItem>
<MenuItem class="javax.swing.JMenuItem" name="pasteBtn">
<Properties>
<Property name="accelerator" type="javax.swing.KeyStroke" editor="org.netbeans.modules.form.editors.KeyStrokeEditor">

@ -40,12 +40,13 @@ import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;
import org.fife.ui.autocomplete.AutoCompletion;
import org.fife.ui.autocomplete.CompletionProvider;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
import org.fife.ui.rsyntaxtextarea.Theme;
@ -62,6 +63,11 @@ public class CodeEditor extends javax.swing.JInternalFrame {
private RSyntaxTextArea codeBox = new RSyntaxTextArea();
private RTextScrollPane sp;
private String lastSaved = "";
private CompletionProvider jscomp = new CodeCompleter("js").getProvider();
private CompletionProvider pycomp = new CodeCompleter("py").getProvider();
private AutoCompletion jsac = new AutoCompletion(jscomp);
private AutoCompletion pyac = new AutoCompletion(pycomp);
/**
* Creates new form CodeEditor
@ -101,6 +107,8 @@ public class CodeEditor extends javax.swing.JInternalFrame {
formMouseClicked(evt);
}
});
jsac.install(codeBox);
sp.setVisible(true);
codeBox.setVisible(true);
codeBox.requestFocus();
@ -161,8 +169,11 @@ public class CodeEditor extends javax.swing.JInternalFrame {
saveAsMenu = new javax.swing.JMenuItem();
exportMenu = new javax.swing.JMenuItem();
editMenu = new javax.swing.JMenu();
copyBtn = new javax.swing.JMenuItem();
undoBtn = new javax.swing.JMenuItem();
redoBtn = new javax.swing.JMenuItem();
jSeparator1 = new javax.swing.JPopupMenu.Separator();
cutBtn = new javax.swing.JMenuItem();
copyBtn = new javax.swing.JMenuItem();
pasteBtn = new javax.swing.JMenuItem();
runMenu = new javax.swing.JMenu();
runCodeBtn = new javax.swing.JMenuItem();
@ -316,14 +327,25 @@ public class CodeEditor extends javax.swing.JInternalFrame {
editMenu.setText("Edit");
copyBtn.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_C, java.awt.event.InputEvent.CTRL_MASK));
copyBtn.setText("Copy");
copyBtn.addActionListener(new java.awt.event.ActionListener() {
undoBtn.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_Z, java.awt.event.InputEvent.CTRL_MASK));
undoBtn.setText("Undo");
undoBtn.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
copyBtnActionPerformed(evt);
undoBtnActionPerformed(evt);
}
});
editMenu.add(copyBtn);
editMenu.add(undoBtn);
redoBtn.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_Y, java.awt.event.InputEvent.CTRL_MASK));
redoBtn.setText("Redo");
redoBtn.setToolTipText("");
redoBtn.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
redoBtnActionPerformed(evt);
}
});
editMenu.add(redoBtn);
editMenu.add(jSeparator1);
cutBtn.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_X, java.awt.event.InputEvent.CTRL_MASK));
cutBtn.setText("Cut");
@ -334,6 +356,15 @@ public class CodeEditor extends javax.swing.JInternalFrame {
});
editMenu.add(cutBtn);
copyBtn.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_C, java.awt.event.InputEvent.CTRL_MASK));
copyBtn.setText("Copy");
copyBtn.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
copyBtnActionPerformed(evt);
}
});
editMenu.add(copyBtn);
pasteBtn.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_V, java.awt.event.InputEvent.CTRL_MASK));
pasteBtn.setText("Paste");
pasteBtn.addActionListener(new java.awt.event.ActionListener() {
@ -444,10 +475,12 @@ public class CodeEditor extends javax.swing.JInternalFrame {
javascriptOption.setSelected(true);
pythonOption.setSelected(false);
codeBox.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVASCRIPT);
jsac.install(codeBox);
} else if (file.matches(".*\\.(sypy|py)")) {
javascriptOption.setSelected(false);
pythonOption.setSelected(true);
codeBox.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_PYTHON);
pyac.install(codeBox);
}
}
@ -595,6 +628,14 @@ public class CodeEditor extends javax.swing.JInternalFrame {
outputBox.setText("");
}//GEN-LAST:event_clearBtnActionPerformed
private void undoBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_undoBtnActionPerformed
codeBox.undoLastAction();
}//GEN-LAST:event_undoBtnActionPerformed
private void redoBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_redoBtnActionPerformed
codeBox.redoLastAction();
}//GEN-LAST:event_redoBtnActionPerformed
/**
* Open a sample code file with the given name.<p>
* Uses the current language.
@ -678,6 +719,7 @@ public class CodeEditor extends javax.swing.JInternalFrame {
private javax.swing.JMenuItem jMenuItem4;
private javax.swing.JPanel jPanel1;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JPopupMenu.Separator jSeparator1;
private javax.swing.JSplitPane jSplitPane1;
private javax.swing.JRadioButtonMenuItem javascriptOption;
private javax.swing.ButtonGroup langBtnGroup;
@ -687,11 +729,13 @@ public class CodeEditor extends javax.swing.JInternalFrame {
private javax.swing.JPanel outputPanel;
private javax.swing.JMenuItem pasteBtn;
private javax.swing.JRadioButtonMenuItem pythonOption;
private javax.swing.JMenuItem redoBtn;
private javax.swing.JMenuItem runCodeBtn;
private javax.swing.JMenu runMenu;
private javax.swing.JMenuItem sampleGraph;
private javax.swing.JMenuItem sampleHelloWorld;
private javax.swing.JMenuItem saveAsMenu;
private javax.swing.JMenuItem saveMenu;
private javax.swing.JMenuItem undoBtn;
// End of variables declaration//GEN-END:variables
}

@ -94,18 +94,12 @@
<Component id="shellBtn" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="editorBtn" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="graphBtn" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
</Group>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="jLabel1" max="32767" attributes="0"/>
<Group type="102" alignment="1" attributes="0">
<Component id="helpBtn" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
<Group type="103" alignment="0" groupAlignment="1" max="-2" attributes="0">
<Component id="jLabel1" max="32767" attributes="0"/>
<Component id="helpBtn" max="32767" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@ -224,8 +218,8 @@
<Component id="arrangeWindowsBtn" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="closeAllBtn" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="94" max="-2" attributes="0"/>
<Component id="jLabel3" pref="400" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jLabel3" pref="490" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>

@ -272,15 +272,11 @@ public class MainGUI extends javax.swing.JFrame {
.addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(shellBtn)
.addComponent(editorBtn)
.addComponent(graphBtn))
.addComponent(graphBtn)
.addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
.addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(helpBtn, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addGroup(jPanel4Layout.createSequentialGroup()
.addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel4Layout.createSequentialGroup()
.addComponent(helpBtn)
.addGap(0, 0, Short.MAX_VALUE)))
.addContainerGap())
);
tabs.addTab("Apps", jPanel4);
@ -341,8 +337,8 @@ public class MainGUI extends javax.swing.JFrame {
.addComponent(arrangeWindowsBtn)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(closeAllBtn)
.addGap(94, 94, 94)
.addComponent(jLabel3, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel3, javax.swing.GroupLayout.DEFAULT_SIZE, 490, Short.MAX_VALUE))
);
jPanel2Layout.setVerticalGroup(
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

@ -0,0 +1,8 @@
E
PI
LN2
LN10
LOG2E
LOG10E
SQRT1_2
SQRT2

@ -0,0 +1,30 @@
notify|return nothing|Display a message in a box.
ask|return String|Ask a question in a box. Supply question text.
D|return String|Find the derivative of the function passed with respect to the second argument.
rad|return double|Convert a given number in degrees to radians.
deg|return double|Convert a given number in radians to degrees.
subs|return double|Solve an equation for the second argument.
plot|return nothing|Graph the given function.
graph|alias of plot|Graph the given function.
plotname|return nothing or String|Gets or sets the title of the graph window.
plotclr|return nothing|Clear the graph and its history.
clearplot|alias of plotclr|Clear the graph and its history.
plotscale|return nothing|Scale the plot to the given factor.
drawdot|return nothing|Places a red dot at the given coordinates.
abs|return double|
asin|return double|
acos|return double|
atan|return double|
ceil|return double|
exp|return double|
floor|return double|
log|return double|
max|return double|Returns the highest number given.
min|return double|Returns the lowest number given.
pow|return double|
random|return double|Gives a random number between 0.0 and 1.0.
round|return double|
sin|return double|
cos|return double|
tan|return double|
print|return nothing|Prints the supplied text to the output.

@ -0,0 +1,29 @@
_.notify|return nothing|Display a message in a box.
_.ask|return String|Ask a question in a box. Supply question text.
_.D|return String|Find the derivative of the function passed with respect to the second argument.
radians|return double|Convert a given number in degrees to radians.
degrees|return double|Convert a given number in radians to degrees.
_.subs|return double|Solve an equation for the second argument.
_.plot|return nothing|Graph the given function.
_.graph|alias of plot|Graph the given function.
_.plotname|return nothing or String|Gets or sets the title of the graph window.
_.plotclr|return nothing|Clear the graph and its history.
_.clearplot|alias of plotclr|Clear the graph and its history.
_.plotscale|return nothing|Scale the plot to the given factor.
_.drawdot|return nothing|Places a red dot at the given coordinates.
fabs|return double|
asin|return double|
acos|return double|
atan|return double|
ceil|return double|
exp|return double|
floor|return double|
log|return double|
max|return double|Returns the highest number given.
min|return double|Returns the lowest number given.
pow|return double|
round|return double|
sin|return double|
cos|return double|
tan|return double|
print|return nothing|Prints the supplied text to the output.
Loading…
Cancel
Save