Skip to content

Commit

Permalink
Implement more intelligent command completion
Browse files Browse the repository at this point in the history
detects if input cell contains a class and then prompts modelica keywords instead of OpenModelica Scripting commands
  • Loading branch information
hkiel committed May 19, 2017
1 parent eb3bda4 commit 774fd7d
Show file tree
Hide file tree
Showing 10 changed files with 191 additions and 46 deletions.
1 change: 0 additions & 1 deletion OMNotebook/OMNotebookGUI/ModelicaTextHighlighter.cpp
Expand Up @@ -38,7 +38,6 @@
#include <QtGui/QTextLayout>
#include <QtXml/QDomDocument>
#include <QMessageBox>
#include <QDebug>

// IAEX Headers
#include "ModelicaTextHighlighter.h"
Expand Down
2 changes: 1 addition & 1 deletion OMNotebook/OMNotebookGUI/cellfactory.cpp
Expand Up @@ -110,7 +110,7 @@ namespace IAEX
if( cstyle.name() != "null" )
text->setStyle( cstyle );
else
throw runtime_error("No Input style defened, the inputcell may not work correctly, please define a Input style in stylesheet.xml");
throw runtime_error("No Input style defined, the inputcell may not work correctly, please define an Input style in stylesheet.xml");
}
catch( exception e )
{
Expand Down
42 changes: 33 additions & 9 deletions OMNotebook/OMNotebookGUI/commandcompletion.cpp
Expand Up @@ -47,6 +47,7 @@

//QT Headers
#include <QtCore/QFile>
#include <QtGui/QTextDocument>

//IAEX Headers
#include "commandcompletion.h"
Expand Down Expand Up @@ -161,12 +162,24 @@ namespace IAEX

if( !command.isNull() && !command.isEmpty() )
{
// check if any comman match the current word in the text
QStringList commandList = commandList_;
cmds_ = &commands_;
QString content = cursor.document()->toPlainText();
QRegExp key;
// check if alternative list is to be used (depending on keywords in the code)
foreach (key, keywords_) {
if (content.contains(key)) {
commandList = elementList_;
cmds_ = &elements_;
break;
}
}
// check if any command matches the current word in the text
currentList_ = new QStringList();
for( int i = 0; i < commandList_.size(); ++i )
for( int i = 0; i < commandList.size(); ++i )
{
if( 0 == commandList_.at(i).indexOf( command, 0, Qt::CaseInsensitive ))
currentList_->append( commandList_.at(i) );
if( 0 == commandList.at(i).indexOf( command, 0, Qt::CaseInsensitive ))
currentList_->append( commandList.at(i) );
}

//cout << "Found commands (" << command.toStdString() << "):" << endl;
Expand Down Expand Up @@ -256,8 +269,8 @@ namespace IAEX
if( currentList_->size() > currentCommand_ )
{
QString command = currentList_->at( currentCommand_ );
if( commands_.contains( command ))
return commands_[command]->helptext();
if( cmds_->contains( command ))
return (*cmds_)[command]->helptext();
}
}

Expand All @@ -284,16 +297,16 @@ namespace IAEX
{
QString command = currentList_->at( currentCommand_ );

if( commands_.contains( command ))
if( cmds_->contains( command ))
{
if( currentField_ < (commands_[command]->numbersField() - 1) )
if( currentField_ < ((*cmds_)[command]->numbersField() - 1) )
{
//next field
currentField_++;
QString fieldID;
fieldID.setNum( currentField_ );
fieldID = "$" + fieldID;
QString field = commands_[command]->datafield( fieldID );
QString field = (*cmds_)[command]->datafield( fieldID );

if( !field.isNull() )
{
Expand Down Expand Up @@ -358,6 +371,17 @@ namespace IAEX

commands_.insert( unit->fullName(), unit );
commandList_.append( unit->fullName() );
} else if( element.tagName() == "element" )
{
CommandUnit *unit = new CommandUnit( element.attribute( "name" ));
QDomNode n = element.firstChild();
parseCommand( n, unit );

elements_.insert( unit->fullName(), unit );
elementList_.append( unit->fullName() );
} else if( element.tagName() == "keyword" )
{
keywords_.append( QRegExp(element.attribute( "name" )) );
}
}
node = node.nextSibling();
Expand Down
7 changes: 6 additions & 1 deletion OMNotebook/OMNotebookGUI/commandcompletion.h
Expand Up @@ -79,9 +79,14 @@ namespace IAEX
int commandStartPos_;
int commandEndPos_;

QList<QRegExp> keywords_;

QStringList *currentList_;
QStringList commandList_;
QHash<QString,CommandUnit*> commands_;
QStringList elementList_;
QHash<QString,CommandUnit*> *cmds_;
QHash<QString,CommandUnit*> commands_;
QHash<QString,CommandUnit*> elements_;
};
}
#endif
156 changes: 142 additions & 14 deletions OMNotebook/OMNotebookGUI/commands.xml
Expand Up @@ -13,10 +13,11 @@
<!-- names, starting with 0. -->

<commands>
<!-- Shell commands -->
<command name="cd()">
<helptext>Return the current directory.</helptext>
</command>
<command name="cd($0)">
<command name='cd("$0")'>
<field name="$0">dir</field>
<helptext>Change directory to the directory given as a string. Ex: cd("myModels/myLibrary").</helptext>
</command>
Expand All @@ -27,7 +28,23 @@
<helptext>Clear the variables.</helptext>
</command>
<command name="help()">
<helptext>Print this helptext (returned as a string).</helptext>
<helptext>Print helptext (returned as a string).</helptext>
</command>
<command name='help("omc")'>
<helptext>The command-line options available for omc.</helptext>
</command>
<command name='help("debug")'>
<helptext>Flags that enable debugging, diagnostics, and research prototypes.</helptext>
</command>
<command name='help("optmodules")'>
<helptext>Flags that enable debugging, diagnostics, and research prototypes.</helptext>
</command>
<command name='help("simulation")'>
<helptext>Flags that enable debugging, diagnostics, and research prototypes.</helptext>
</command>
<command name='help("$0")'>
<helptext>Flags that enable debugging, diagnostics, and research prototypes.</helptext>
<field name="$0">flagname</field>
</command>
<command name="instantiateModel($0)">
<field name="$0">modelname</field>
Expand All @@ -43,11 +60,11 @@
<command name="listVariables()">
<helptext>Return a vector of the currently defined variable names.</helptext>
</command>
<command name="loadFile($0)">
<command name='loadFile("$0")'>
<field name="$0">strFile</field>
<helptext>Load modelica file given as string argument. Ex: loadFile("../myLibrary/myModels.mo").</helptext>
</command>
<command name="loadFiles({$0})">
<command name='loadFiles({"$0"})'>
<field name="$0">strFiles</field>
<helptext>Load modelica files given as string arrray. Ex: loadFile({"modelA.mo", "modelB.mo").</helptext>
</command>
Expand All @@ -68,33 +85,38 @@
<field name="$1">var2</field>
<helptext>Plot var2 relative to var1 from the most recently simulated model. Ex: plotParametric(x,y).</helptext>
</command>
<command name="plotAll($0)">
<command name='plotAll("$0")'>
<field name="$0">"className_res.mat"</field>
<helptext>Plot all variables from the specified file. Ex: plotAll("Class_res.mat").</helptext>
</command>
<command name="readFile($0)">
<command name='readFile("$0")'>
<field name="$0">str</field>
<helptext>Load file given as string and return a string of the file content. Ex: readFile("myModel/myModelr.mo").</helptext>
</command>
<command name="readSimulationResultSize($0)">
<command name='readSimulationResultSize("$0")'>
<field name="$0">strFile</field>
<helptext>Return the size of the record resulting from a simulation. The size is read from the result file, given as a string. Ex: readSimulationResultSize("dcmotor_res.plt").</helptext>
</command>
<command name="readSimulationResult($0, $1, $2)">
<command name='readSimulationResult("$0", $1, $2)'>
<field name="$0">strFile</field>
<field name="$1">variables</field>
<field name="$2">size</field>
<helptext>Read the results of a simulation from a file named by the string argument strFile. Here size is the size of the resulting record and variables is a vector of the variables to investigate. Ex: readSimulationResult("dcmotor_res.plt", {R1.i,L1.v}, 10).</helptext>
</command>
<command name="runScript($0)">
<command name='runScript("$0")'>
<field name="$0">strFile</field>
<helptext>Exectute script file (.mos) given as string argument. Ex: runScript("simulation.mos").</helptext>
</command>
<command name="saveModel($0, $1)">
<command name='saveModel("$0", $1)'>
<field name="$0">strFile</field>
<field name="$1">modelname</field>
<helptext>Save the model/class with name modelname in the file given by the strFile string argument.</helptext>
</command>
<command name="simulate($0, stopTime=$1)">
<field name="$0">modelname</field>
<field name="$1">1</field>
<helptext>Translates a model and simulates it. Ex: simulate(dcmotor). Ex: simulate(dcmotor, stopTime=10).</helptext>
</command>
<command name="simulate($0, startTime=$1, stopTime=$2, numberOfIntervals=$3, tolerance=$4, method=$5, outputFormat=$6)">
<field name="$0">modelname</field>
<field name="$1">0</field>
Expand All @@ -103,7 +125,7 @@
<field name="$4">1e-6</field>
<field name="$5">"dassl"</field>
<field name="$6">"mat"</field>
<helptext>Translates a model and simulates it. Ex: simulate(dcmotor). Ex: simulate(dcmotor,startTime=0, stopTime=10, numberOfIntervals=1000).</helptext>
<helptext>Translates a model and simulates it. Ex: simulate(dcmotor). Ex: simulate(dcmotor, startTime=0, stopTime=10, numberOfIntervals=1000).</helptext>
</command>
<command name="buildModel($0, startTime=$1, stopTime=$2, numberOfIntervals=$3, tolerance=$4, storeInTemp=$5, method=$6, outputFormat=$7)">
<field name="$0">modelname</field>
Expand All @@ -114,9 +136,9 @@
<field name="$5">false</field>
<field name="$6">"dassl"</field>
<field name="$7">"mat"</field>
<helptext>Translates a model and build it. It does not run the code! Ex: buildModel(dcmotor). Ex: buildMotor(dcmotor,startTime=0, stopTime=10, numberOfIntervals=1000).</helptext>
<helptext>Translates a model and build it. It does not run the code! Ex: buildModel(dcmotor). Ex: buildMotor(dcmotor, startTime=0, stopTime=10, numberOfIntervals=1000).</helptext>
</command>
<command name="system($0)">
<command name='system("$0")'>
<field name="$0">str</field>
<helptext>Execute str as a system(shell) command, return integer success value. Ex: system("touch myFile").</helptext>
</command>
Expand All @@ -138,9 +160,115 @@
</command>
<command name="class $0">
<field name="$0">name</field>
<helptext>New generic class.</helptext>
</command>
<command name="model $0">
<field name="$0">name</field>
<helptext>New model.</helptext>
</command>
<command name="block $0">
<field name="$0">name</field>
<helptext>New block.</helptext>
</command>
<command name="equation"></command>
<command name="package $0">
<field name="$0">name</field>
<helptext>New package.</helptext>
</command>
<command name="record $0">
<field name="$0">name</field>
<helptext>New record.</helptext>
</command>
<command name="connector $0">
<field name="$0">name</field>
<helptext>New connector.</helptext>
</command>
<command name="type $0">
<field name="$0">name</field>
<helptext>New type.</helptext>
</command>
<command name="function $0">
<field name="$0">name</field>
<helptext>New function.</helptext>
</command>

<!-- keywords -->
<keyword name="\bclass\b"></keyword>
<keyword name="\bmodel\b"></keyword>
<keyword name="\bblock\b"></keyword>
<keyword name="\bpackage\b"></keyword>
<keyword name="\brecord\b"></keyword>
<keyword name="\bconnector\b"></keyword>
<keyword name="\btype\b"></keyword>
<keyword name="\bfunction\b"></keyword>

<!-- Modelica language elements -->
<element name="Real $0">
<field name="$0">name</field>
</element>
<element name="Integer $0">
<field name="$0">name</field>
</element>
<element name="Boolean $0">
<field name="$0">name</field>
</element>
<element name="String $0">
<field name="$0">name</field>
</element>
<element name="enumeration ($0,$1)">
<field name="$0">e1</field>
<field name="$1">e2</field>
</element>
<element name="class $0">
<field name="$0">name</field>
<helptext>New class.</helptext>
</element>
<element name="model $0">
<field name="$0">name</field>
<helptext>New model.</helptext>
</element>
<element name="block $0">
<field name="$0">name</field>
<helptext>New block.</helptext>
</element>
<element name="package $0">
<field name="$0">name</field>
<helptext>New package.</helptext>
</element>
<element name="record $0">
<field name="$0">name</field>
<helptext>New record.</helptext>
</element>
<element name="connector $0">
<field name="$0">name</field>
<helptext>New connector.</helptext>
</element>
<element name="type $0">
<field name="$0">name</field>
<helptext>New type.</helptext>
</element>
<element name="function $0">
<field name="$0">name</field>
<helptext>New function.</helptext>
</element>
<element name="equation"></element>
<element name="extends $0">
<field name="$0">BaseClass</field>
<helptext>Extends existing class (inheritance).</helptext>
</element>
<element name="input"></element>
<element name="ouput"></element>
<element name="flow"></element>
<element name="constant">
<helptext>Value of variable will be the same for all possible simulations.</helptext>
</element>
<element name="parameter">
<helptext>Variable may change from one simulation to another, but will not change during given simulation.</helptext>
</element>
<element name="discrete"></element>
<element name="connect"></element>
<element name="noEvent($0)">
<field name="$0">cond</field>
<helptext>Suppresses generation of events.</helptext>
</element>

</commands>
13 changes: 2 additions & 11 deletions OMNotebook/OMNotebookGUI/graphcell.cpp
Expand Up @@ -262,21 +262,13 @@ namespace IAEX {
event->ignore();
emit forwardAction( 3 );
}
else if(event->modifiers() == Qt::ControlModifier && event->key() == Qt::Key_W)
{
inCommand = false;
indentText();
event->ignore();
// QTextBrowser::keyPressEvent( event );
// update();

}

// CTRL+E: autoindent cell
else if(event->modifiers() == Qt::ControlModifier && event->key() == Qt::Key_E)
{
inCommand = false;
indentText();
}
// CTRL+K: kill text until EOL
else if(event->modifiers() == Qt::ControlModifier && event->key() == Qt::Key_K)
{
inCommand = false;
Expand Down Expand Up @@ -355,7 +347,6 @@ namespace IAEX {
}

updatePosition();

}

void MyTextEdit2::setAutoIndent(bool b)
Expand Down
2 changes: 1 addition & 1 deletion OMNotebook/OMNotebookGUI/indent.cpp
Expand Up @@ -94,7 +94,7 @@ void Indent::ISM::newToken(QString s, QString s2)
lMod = true;
break;
}
else if(s == "class" || s == "package" || s == "function" || s == "model" || s == "record" || s == "connector")
else if(s == "class" || s == "package" || s == "function" || s == "model" || s == "block" || s == "record" || s == "connector")
{
++level;
skipNext = true;
Expand Down

0 comments on commit 774fd7d

Please sign in to comment.