Meditor

Aus Physik
Zur Navigation springen Zur Suche springen

In grün geschriebene Klassen sind die selbst entwickelten.

Ziel

Ein professioneller Editor für Matlab

Features:

  • Syntax-Highlighting Funktioniert
  • Automatische Einrückung Funktioniert
  • Matching Brackets Funktioniert
  • Hilfefunktionen
    • Für Matlab - Funktionen wird die passende Matlab-Hilfeseite aufgerufen (Browser) Funktioniert
  • Export von Matlab-Files in verschiedene Formate Funktioniert
    • Direkter Export in XML
    • Umwandlung in verschiedene Zielformate
      • HTML
      • LaTeX, PDF
  • Code editing actions
    • Comment / Uncomment Funktioniert
    • Passend einrücken Funktioniert
    •  ???
  • Interaktion mit weiteren Plugins (Konsole und Workspace-Viewer) wodurch eine umfassende Matlab-IDE gebildet wird.
  • Code Folding (vielleicht später)
  • Templates?

Veröffentlichung

Es ist geplant den Editor zusammen mit der Matlab-Console und dem Workspace View zu veröffentlichen. Die Lizenz wird die EPL sein.

ToDos bis zur Veröffentlichung

  • Quellen für alle Files herausfinden, feststellen welche geändert wurden. Erledigt
  • Lizenzen abklären Erledigt
  • Gemeinsamen Header Erledigt
    • entwickeln
    • überall einfügen
  • XML Export
    • Metainfo-Tags festlegen und implementieren Erledigt
    • Markup Language erweitern (Listen, Aufzählungen) Erledigt
    • Zeilennummern Erledigt
  • System für gemeinsam verwendete Klassen ausdenken
  • Exception Handling Erledigt
  • Preferences durchgehen Erledigt
  • Plugin machen und eine Zeit lang verwenden
  • Doku: klären was zu schreiben ist und dieses verfassen Erledigt

License

Die für Eclipse Plugins wohl üblichste Licence ist die EPL. Deshalb, und weil wir einige EPL-lizenzierte und von uns veränderte Files verwenden, wird auch die EPL für die Veröffentlichung verwendet werden. Wir verwenden auch ein paar Module, welche unter der CPL stehen, was jedoch kein Problem darstellt, solange sie nicht verändert wurden. Für jene CPL Module, die wir veränderten, haben wir die Erlaubnis der jeweiligen Entwickler den Code unter der EPL zu veröffentlichen.

Links:

Versionen

(Milestones wär wohl übertrieben ;-)

Version 1.0.1

Was geht

  • Partitionierung als Basis für Syntax-Highlighting und Operationen im Dokument
    Partitionstypen:
           IDocument.DEFAULT_CONTENT_TYPE,
           MATLAB_COMMENT,
           MATLAB_SINGLELINE_STRING,
           MATLAB_MULTILINE_COMMENT,
           MATLAB_KEYWORD, 
           MATLAB_FUNCTION, 
           MATLAB_CODE, 
           MATLAB_NUMBER, 
           MATLAB_WHITESPACE, 
           MATLAB_NEWLINE
  • Syntax-Highlighting verfeinert
    • Arbeitet nur mehr mit Partitionen (generiert von MatlabPartitionScanner)
    • Hervorgehoben werden:
      • Kommentare
      • Strings
      • Keywords
      • Matlab-Funktionen
      • Zahlen
  • Automatische Einrückung
    • Wenn man eine neue Zeile anfängt
      • die beendete Zeile wird passend eingerückt
      • in der neuen Zeile beginnt man mit passender Einrücktiefe
    • Wenn man ein Keyword fertiggetippt hat (und danach ein Whitespace einfügt)
      • die aktuelle Zeile wird passend eingerückt
    • Bei Eingabe eines Tabs am Zeilenanfang oder im Whitespacebereich am Beginn einer Zeile
      • die aktuelle Zeile wird passend eingerückt
      • Cursor springt an das Ende der Einrückung
    • Vom User einstellbare Sachen:
      • ob die Einrückung mit Tabs oder mit Leerzeichen erfolgen soll
      • Einrücktiefe

Archiv

Diese Seite bei Fertigstellung der Version 1.0.1

Version 1.0.2

Was geht (zusätzlich zur Version 1.0.1)

  • Partitionierung
    • neue Partition MATLAB_CONTINUATION
    • unsinige Partition MATLAB_MULTILINE_COMMENT entfernt
    • Unterscheidung zwischen Strings und dem ' Zeichen als Operator funktioniert
  • Automatische Einrückung
    • Fortsetzungszeilen werden behandelt
    • Einrücken von ausgewählten Bereichen (über Menüpunkt)
  • Preferences
    • Änderungen zeigen sofort Wirkung
  • einige Refactorings im Code
  • Syntax-Highlighting
    • Fortsetzungsoperator (...) wird mit allem was nach ihm in einer Zeile steht als Kommentar hervorgehoben
  • Textoperationen
    • Beim Löschen/Einfügen von Passagen (auch von mehreren Zeilen) werden Partitionierung, Einrückung und Darstellung aktualisiert

Archiv

Diese Seite bei Fertigstellung der Version 1.0.2

Version 1.0.3 (läuft derzeit im MLTutor)

Was geht (zusätzlich zur Version 1.0.2)

  • Keybindings
  • Hilfe für Funktionen, Keywords und Operatoren
  • Operatoren werden gehighlightet
  • Konfiguration, Funktionenlisten und "die Ausnahmen" für die Hilfe werden in Files gespeichert

Was fehlt - Schritte bis zur nächsten Version

  • HTML Help base als Preference Funktioniert
  • Partitionierung
    • Toolbox-Funktionen von Matlab-Funktionen unterscheiden Funktioniert
    • FEHLER: ' Operator wird nicht als Operator erkannt, wenn er hinter einer MATLAB_NUMBER Partition steht. Funktioniert
    • Zahlen über Regex erkennen Funktioniert
      • Überarbeitung der greedy-Funktionalität der RegExRule nötig Funktioniert
      • RegExRule um Lookahead-Funktionalität erweitern Funktioniert
    • FEHLER: beim ' Operator, diverses seltsames Verhalten ausbessern Funktioniert
    • Strings hinter Keywords erkennen, z.B.: case'a'Funktioniert
    • Beim Einfügen von Text inmitten einer Zeile die Zeile neu partitionieren lassen. Funktioniert im Prinzip, wird jedoch nicht jedes Mal aufgerufen
    • Die zwei Bedeutungen von end trennen (wenn es als Array Index verwendet wird, soll es bei der Berechnung der Zeileneinzüge ignoriert werden) Funktioniert
  • Hilfesystem
    • Hilfe für Toolbox-Funktionen
    • Internen Browser verwenden Funktioniert
  • Export eines Matlab-Files wird noch erweitert
    • von außen Funktioniert
    • aus dem MLTutor Funktioniert
      • generierte Files gleich anzeigen lassen Funktioniert
    • Transformationen
      • HTML Funktioniert
      • LaTeX Funktioniert
      • PDF Funktioniert
    • Transformationen gleich vom MLTutor durchführen lassen (damit direkt "Export as..." ...) Funktioniert
    • Zeilennummern
      • XML Format ändern Funktioniert
      • Transformationen anpassen Funktioniert
      • Auswahl (ob Zeilennummern angezeigt werden oder nicht) Funktioniert
    • Markup Language erweitern:
      • Listen Funktioniert
      • Aufzählungen Funktioniert
    • Meldung in der Statuszeile während des Exports
  • Wenn mehrere Zeilen markiert sind: Verhalten von TAB und Ctrl+I aufeinander abstimmen Funktioniert
  • Actions:
    • Befehl zum Einrücken des gesamten Dokuments Funktioniert
    • Comment / Uncomment (markierten Block bzw. aktuelle Zeile) Funktioniert
  • Actions auch im Kontextmenü Funktioniert, im Prinzip
  • Zeilennummern standardmäßig anzeigen Funktioniert
  • Code Folding rauswerfen Funktioniert
  • Exception Handling: Stragegie überlegen und implementieren Funktioniert
  • MatlabDoubleClickStrategy
    • Funktionalität anschauen und gegebenenfalls erweitern
  • Doku
    • Schreiben und ins Eclipse-Hilfesystem einbauen Funktioniert
  • Codeorganisation
    • Bessere Einteilung in Packages Funktioniert

Anfänglich vorhandene Strukturen

Editor

...
  |- org.eclipse.ui.texteditor.AbstractTextEditor
       |- org.eclipse.ui.texteditor.StatusTextEditor
            |- org.eclipse.ui.texteditor.AbstractDecoratedTextEditor
                 |- org.eclipse.ui.editors.text.TextEditor
                      |- at.tugraz.itp.mltutor.meditor.editors.MatlabEditProjection
                           |- at.tugraz.itp.mltutor.meditor.editors.MatlabEditor

Viewer

...
  |- org.eclipse.jface.text.source.projection.ProjectionViewer
       |- at.tugraz.itp.mltutor.meditor.editors.MatlabSourceViewer

Problem: von ProjectionViewer soll eigentlich nicht abgeleitet werden.


Neue Strukturen

Ersetzte deprecated Klassen

  • DefaultPartitioner durch FastPartitioner
    • FastPartitioner implementiert alle benötigten Funktionalitäten, somit keine weiteren Änderungen
  • org.eclipse.ui.help.WorkbenchHelp soll ersetzt werden durch org.eclipse.ui.help.IWorkbenchHelpSystem
    • zumindest laut Eclipse-Hilfe, was aber nicht direkt geht (ist ja auch ein Interface)
    • Ein neues Hilfesystem, welches aber weniger kann als org.eclipse.ui.help.WorkbenchHelp, ist org.eclipse.help.HelpSystem
    • Mit IWorkbenchHelpSystem IWorkbench.getHelpSystem() kann eine Instanz des passenden Interfaces geholt werden.
      • Ein IWorkbench Objekt wiederum bekommt man mit static IWorkbench PlatformUI.getWorkbench()
    • Ein Beispiel:
      Statt WorkbenchHelp.setHelp(...);
      Wird jetzt PlatformUI.getWorkbench().getHelpSystem().setHelp(...) verwendet.
  • Indent Strategy
    • IAutoIndentStrategy ist durch IAutoEditStrategy zu ersetzen
    • damit auch die Funktion getAutoIndentStrategy(...) durch getAutoEditStrategies(...)
    • MatlabAutoIndentStrategy (von DefaultAutoIndentStrategy abgeleitet) wurde ersetzt durch MatlabAutoEditStrategy (von IAutoEditStrategy abgeleitet)
  • DefaultUndoManager durch TextViewerUndoManager
    • macht das Gleiche, keine weiteren Änderungen nötig

Partitionierung des Dokuments

Partitionstypen

           IDocument.DEFAULT_CONTENT_TYPE,
           MATLAB_COMMENT,
           MATLAB_SINGLELINE_STRING,
           MATLAB_KEYWORD, 
           MATLAB_FUNCTION, 
           TOOLBOX_FUNCTION, 
           MATLAB_OPERATOR,
           MATLAB_CODE, 
           MATLAB_NUMBER, 
           MATLAB_WHITESPACE, 
           MATLAB_NEWLINE, 
           MATLAB_CONTINUATION

Partitionscanner und neue Rules

MatlabScanner wurde entfernt. Die darin enthaltenen Funktionalitäten wurden in MatlabPartitionScanner eingebaut. Da dieser nicht mit WordRule umgehen kann, wurde eine neue innere Klasse für das Detektieren der Keywörter eingeführt:

static class WordPredicateRule extends WordRule implements IPredicateRule{
    public WordPredicateRule(IWordDetector detector, IToken successToken, IToken defaultToken);
    ...
}

Anwendung des Adapter (genauer Klassenadapter) Patterns.

Das selbe Spiel wurde für WhitespacePredicateRule gespielt.
Für letztere wird noch eine neue Klasse WhitespaceDetector gebraucht:

private class WhitespaceDetector implements IWhitespaceDetector {
    WhitespaceDetector(char[] whitespaces){}
    public boolean isWhitespace(char c) {}
}

Um Regular Expressions verwenden zu können gibt es die Klasse RegExRule

public class RegExRule implements IPredicateRule {
    public RegExRule(IToken token, Pattern pattern, Pattern completePattern, boolean greedy) {}
    public void setLookback(Pattern lookbackPattern, int lookbackLen){}
    public void setLookahead(Pattern lookaheadPattern, int lookaheadMaxLen){}
    ...
}

Weiters wird die EndOfLineRule benötigt (Kommentare und Fortsetzungszeilen). Da jedoch der Zeilenumbruch von dieser Partition ebenfalls geschluckt wird, und somit nicht als eigene Partition auftaucht, wurde diese Klasse minimalst erweitert um dies zu unterbinden:

public class MatlabEndOfLineRule extends EndOfLineRule {
    public MatlabEndOfLineRule(String startSequence, IToken token) {}
    public IToken evaluate(ICharacterScanner scanner, boolean resume) {
        // super.evaluate ausführen und scanner im Erfolgsfalle um ein Zeichen zurückdrehen
    }
}

Unterscheidung Funktionen - Keywords

Leider ist es etwas schwierig mehrere Rules für verschiedene Wortlisten zu implementieren (es funktioniert auf die naheliegende Weise nicht). Deshalb wurde eine (innere) Hilfsklasse WordListRuleGenerator eingeführt, die eine WordPredicateRule aus mehreren Wortlisten erzeugt. Dabei gehört zu jeder Wortliste ein Token, sodass verschiedene Partitionen für verschiedene Wortlisten erzeugt werden, wobei derzeit zwischen Matlab-Funktionen, Toolbox-Funktionen und Keywords unterschieden wird. Als Keywords wird der Output der Matlab-Funktion iskeyword verwendet:
'break' 'case' 'catch' 'continue' 'else' 'elseif' 'end' 'for' 'function' 'global' 'if' 'otherwise' 'persistent' 'return' 'switch' 'try' 'while'
(entnommen aus der Matlab Hilfe: http://www.mathworks.com/access/helpdesk/help/techdoc/ref/iskeyword.html)

class WordListRuleGenerator {
    public WordListRuleGenerator();
    public void addWordList(String[] words, IToken token);
    public IPredicateRule generateRule(IWordDetector detector, IToken successToken, IToken defaultToken);
}

Operatoren

werden mit einer Regex erkannt. Die Regex ist:

\.?(\+|\-|\*|/|\\|\^)|:|<|<=|>|>=|!=|==|&|\||~|&&|\|\|

Man könnte diese zwar noch hübscher gestalten (z.B. <|<= durch <=? ersetzen), aber dies würde zu unübersichtlicherem Code bei der Erstellung der Regex führen.

Diese Erstellung wird von folgender Klasse erledigt:

private static class OperatorList {
    private final static String[] DOT_OPERATORS = {
        "+", "-", "*", "/", "\\", "^"
    };
    private final static String[] OPERATORS = {
        ":", "<", "<=", ">", ">=", "!=", "==", 
        "&", "|", "~", 
        "&&", "||"
    };
    ...

    public static String getRegexString(){}
    ...
}

Zahlen

Zahlen werden über eine Regex erkannt. Die Basisregex ist:

(\d+\.|\d*\.\d+|\d+)([eEdD][\-\+]?\d+)?

wobei diese auf insgesamt 4 Rules (deren Reihenfolge sehr wichtig ist!) aufgeteilt wurde, da eine besondere Behandlung einer Zahl vor einem DotOperator nötig ist. Zu diesem Zweck wurde die RegExRule um die Möglichkeit eines Lookaheads erweitert.

Um z.B. den Fall 2.^[0:10] richtig zu verarbeiten (der Punkt gehört zum Operator, nicht zur Zahl) wird die Zahl mit der Regex \d+\. und dem Lookahead [^\+\-\*/\\\^'] erkannt. Der Lookahead sorgt dafür, dass im Falle eines auf eine Zahl folgenen DotOperators die Regex nicht anpricht, sondern die nächste Rule mit der Regex \d+ zum Tragen kommt.

Funktionsliste aus File einlesen

Das File wird vom Tool filetools.filesearchtools.MatlabFunctionFileSearch generiert. Falls es vom MatlabPartitionScanner nicht gefunden werden kann, wird die bisher verwendete hardcoded Liste verwendet.

Für das Tool siehe dessen Doku im Wiki

Automatische Einrückung

Anforderungen

Funktionalität:

  • Beim Wechsel in eine neue Zeile (Enter)
    • Übernehmen der Einrücktiefe
    • Automatisches Ein- und Ausrücken nach bestimmten Keywords (for, ...)
      • Dies kann die aktuelle Zeile oder eine nach einem Umbruch neu erzeugte betreffen
  • laufende Aktualisierung der Einrücktiefe (wenn z.B. ein Teil eines Keywords gelöscht wird)
    • korrekte Einrückung für mit copy and paste eingefügte Bereiche
  • Verhalten der Tab-Taste wie im Emacs
  • korrekte Einrückung für einen ganzen Abschnitt (das ganze Dokument)

Stragegie

char command enthält das zuletzt eingetippte "Zeichen".

Beim Sprung in eine neue Zeile

  1. vorhergehende Zeile holen, Einrücktiefe feststellen
  2. vorhergehende Zeile analysieren, dabei mit Partitionen arbeiten (damit können Kommentare leicht ignoriert werden)
    • für jedes Keyword für mehr Einrückung (for, if, else, elseif, ...)
      => Einrücken
    • für jedes Keyword für weniger Einrückung (end, ...)
      => Ausrücken
    • bei Fortsetzungszeilen um einen Fixbetrag gegenüber der ersten fortgesetzten Zeile einrücken
  3. tatsächliche Einrückung für die vorhergehende und die neue Zeile herstellen (passende Whitespaces)
  4. falls der Umbruch mitten in einer Zeile erzeugt wurde, so soll der Textcursor an das Ende des Whitespacebereichs am Anfang der neuen Zeile positioniert werden

Nach dem Fertigtippen eines Keywords

  1. Zeile holen
  2. Vorherige Partition holen
  3. Wenn diese ein Keyword war
    1. Einrücktiefe der vorherigen Zeile feststellen
    2. Einrücktiefe der aktuellen Zeile korrigieren

Drücken von Tab

  1. vorhergehende Zeile analysieren
  2. Einrücktiefe der aktuellen Zeile korrigieren
  3. Textcursor an das Ende des Whitespacebereichs setzen

Löschen und Einfügen von Textteilen

  1. Feststellen welche Zeilen betroffen sind
  2. Diese passend einrücken

Struktur

Neue Singleton Klasse:

public class MatlabAutoEditStrategy implements IAutoEditStrategy {
    public static MatlabAutoEditStrategy getInstance(){}
    public void setSourceViewer(ISourceViewer sourceViewer){
    public void setupStrategy(){}
    public void customizeDocumentCommand(IDocument document, DocumentCommand command) {}
    ...
}

Diese wird explizit ansonsten möglichst nirgends verwendet!

Jedoch wird sie für Reinitialisierungsarbeiten nach Änderungen in der Preferences Page benötigt werden, was meiner Meinung nach OK ist, da die speziellen Einstellungen und unsere spezielle Klasse zusammengehören. (--Osiris 12:43, 9 December 2005 (CET))

Für das korrekte Einrücken eines markierten Bereichs gibt es die Klasse

MatlabIndentationAction extends MatlabAction implements IEditorActionDelegate {
    public MatlabIndentationAction(String text) {}
    public MatlabIndentationAction() {}
    public void run(IAction action) {}
    public void setActiveEditor(IAction action, IEditorPart targetEditor) {}
}

welche haupstächlich das Verhalten von MatlabAction übernimmt.

Leider ist mir noch kein Weg untergekommen um aus der Klasse heraus (über MatlabConfiguration) an die vom Framework verwendete Instanz von MatlabAutoEditStrategy heranzukommen, weshalb ich mich dazu entschloss letztere als Singleton auszuführen. Ich wählte die einfachste Thread-save Implementierung die mir bekannt ist. --Osiris 14:48, 4 January 2006 (CET)

Die Action ist nur über die plugin.xml hinzugefügt und über den Menüpunkt Edit -> Correct Indentation erreichbar.

Querverbindungen:

  • Folgende Klassen wissen was von der konkreten Indent Strategy
    • MatlabConfiguration
      nur innerhalb der Funktion getAutoEditStrategies(...)
    • MatlabEditor
      nur für die Initialisierung des IPropertyChangeListener (um auf Änderungen in der PropertyPage reagieren zu können)
    • MatlabIndentationAction
  • Damit die Indent Strategy die Aktualisierung der Ausgabe erzwingen kann, muss ihr der Source Viewer bekannt gegeben werden, was in der Funktion MatlabConfiguration.getAutoEditStrategies(ISourceViewer sourceViewer, ...) leicht erledigt werden kann.
Offensichtlich ist es auch so gedacht, dass die Indent Strategie "ihren" Source Viewer kennt - klingt ja auch plausibel. --Osiris 15:37, 5 January 2006 (CET)

Änderungen in der PropertyPage sofort übernehmen

Grundstruktur

In MatlabEditor.init(...) wird ein Preferences.IPropertyChangeListener() angelegt, welcher bei Änderung einer Textfarbe MatlabConfiguration.updateSyntaxColor(...) und bei Änderungen an den Einstellungen für die Einrückung MatlabAutoEditStrategy.setupStrategy() aufruft.
In der ersten Funktion wird der passende NonRuleBasedDamagerRepairer geholt und dessen TextAttribute durch ein neues ersetzt.

Hinzugefügte Strukturen

  • NonRuleBasedDamagerRepairer.setTextAttribute(TextAttribute textAttribute)
    ist lediglich ein Setter für die bereits vorhanden gewesene Membervariable.
  • MatlabConfiguration.updateSyntaxColor(String name)
    die DamagerRepairer aller zu der angegebenen Farbe gehörenden Partitionstypen werden aktualisiert.

Im Zuge dessen wurde das Initialisieren des PresentationReconciler (Funktion MatlabConfiguration.getPresentationReconciler(...) refactored.

Hilfesystem

Die Implementierung als Action entspricht der der automatischen Einrückung.

public class MatlabHelpAction extends MatlabAction implements IEditorActionDelegate{
    private final static String PROPERTYFILE      = "helpproperties.xml";
    private final static String EXCEPTIONFILE     = "helpfileexceptions.xml";
    private final static String HELPFILEFUNCFILE  = "help_funcs";

    // weitere Definitionen für Defaultwerte der Parameter

    // Keys der Parameter (für das propertyfile):
    private final static String HELP_HTML_BASE_KEY = "HELP_HTML_BASE";    
    private final static String REFERENCE_HTML_BASE_KEY = "REFERENCE_HTML_BASE";

    public MatlabHelpAction(String text) {}
    public MatlabHelpAction() {}
    public void run(IAction action) {}
    private void launchBrowser(String urlToOpen){}
    ...
}

Vorgehen

  1. Es wird überprüft, ob der Cursor in einer Partition steht, für die Hilfe angeboten werden kann und der zu suchende Text extrahiert. Dies trifft für die Partitionstypen MATLAB_FUNCTION, MATLAB_KEYWORD und MATLAB_OPERATOR zu. Dabei darf der Cursor sowohl direkt vor dem ersten als auch direkt nach dem letzten Zeichen der Partition stehen.
  2. Es wird nachgesehen, ob die gesuchte Funktion in der Liste der Funktionen mit Hilfeseite enthalten ist und falls ja wird eine URL zur Hilfeseite generiert.
  3. Falls nein wird in der Liste der Ausnahmen nach dem Text gesucht und die dort angegebene URL verwendet.
  4. Anschließend wird, sofern eine Hilfeseite gefunden wurde, ein externer Browser mit dieser als Inhalt gestartet, wofur launchBrowser(...) zuständig ist.

Konfiguration

Es existiert eine Property Page, in welcher die Art des Browseraufrufs (Editor, View oder externer Browser) und eine Basis-URL für die Hilfeseiten-Aufrufe angegeben werden. Zwei mögliche solcher URLs sind:

Weiters sind noch zwei Files nötig, um zu Funktionen die passenden Hilfeseiten zu finden.

  1. help_funcs enthält alle Matlab-Funktionen, zu denen es eine Hilfeseite gibt und kann mit filetools.filesearchtools.MatlabfunctionFileSearch erzeugt werden (siehe hier)
  2. helpfileexceptions.xml enthält die Ausnahmen, also Funktionen, für die eine spezielle Hilfeseite angegeben wird. Genaueres zum File im nächsten Abschnitt.

Die Ausnahmen

werden in einem XML-Format gespeichert, welches zwar selbst definiert ist, sich aber an das Java-Property - Format anlehnt. Wird keine Datei gefunden, so wird eine hart codierte Liste, welche die Operatoren beinhaltet, verwendet.
Dieses File liegt in /afs/itp.tugraz.at/proj/mml/MLTutor/mltutor/plugins/at.tugraz.itp.mltutor.meditor_1.0.3/config/ und kann jederzeit editiert werden, um neue Ausnahmen hinzuzufügen.

Eine Beispieldatei:

<?xml version = '1.0' encoding = 'UTF-8'?>
<!DOCTYPE helpexceptions SYSTEM "helpfileexceptions.dtd">
<helpexceptions>
  <exception word="+" >techdoc/matlab_prog/ch12_nd9.html</exception>
  <exception word=".+" >techdoc/matlab_prog/ch12_nd9.html</exception>
  <exception word="-" >techdoc/matlab_prog/ch12_nd9.html</exception>
  ...
</helpexceptions>

Zur Verarbeitung des XML-Files wird ein SAX-Parser, verpackt in folgende Klasse verwendet:

public class HelpExceptionFileReader extends DefaultHandler {
    public HelpExceptionFileReader(){}
    public static Hashtable<String, String> readHelpFile(String directory, String filename){}
    ...
}

XML-Export

Preference Pages

Struktur

AbstractMatlabenginePrefsPage dient als Basisklasse für die einzelnen Preference Pages und stellt Grundfunktionen zum Hinzufügen von Elementen und für die Speicherung der Einstellungen zur Verfügung. Diese und die zu überschreibenden Funktionen (unterer Block) sind folgend angegeben:

public abstract class AbstractMatlabenginePrefsPage extends PreferencePage 
        implements IWorkbenchPreferencePage {

    public AbstractMatlabenginePrefsPage(String description){}
    protected Button addCheckBox(Composite parent, String label, String key, int indentation) {}
    protected Control addTextField(Composite composite, String label, String key, int textLimit, int indentation, boolean isNumber) {}
    protected Control addComboField(Composite parent, String label, String key, String[] entries, int indentation, boolean isNumber) {}
    protected Group addGroup(Composite parent, String title) {}
    protected Composite addRadioButtonField(Composite parent, String title, String[][] buttonInfo, int verticalIndent, int hSpan, int radioButtonIndent) {}
    protected Label addLabel(Composite parent, String text, int verticalIndent, int hSpan) {}
    protected void createDependency(final Button master, String masterKey, final Control slave) {}
    protected static void indent(Control control) {}

    protected static void initializeDefaultPreferences(Preferences prefs) {}
    protected abstract Control createAppearancePage(Composite parent);
    protected abstract OverlayPreferenceStore createOverlayStore();
    ...
}

Zum Speichern der Einstellungen wird die Klasse OverlayPreferenceStore verwendet.

public class OverlayPreferenceStore  implements IPreferenceStore {
    ...
}

Vorhandene Preference Pages

Es sind folgende Preference Pages implementiert:

MatlabenginePrefsPage Grundlegende Editor-Einstellungen
MatlabengineExportPrefsPage Einstellungen für den Export (Menüpunkt File->Export)
HelpBrowserPrefsPage Konfiguration des zu verwendenden Browsers und der Basis-URL für die Hilfe-Funktionen

Exception Handling

Struktur

Es verursachen fast alle Exceptions eine Fehlerausgabe in einem Dialogfenster. Dafür ist die eine Member-Funktion der Klasse Activator zuständig:

    public static void errorDialog(final String message, final Throwable t) {...}

Sollten Exceptions auftreten, welche keine wirklichen Fehlfunktionen verursachen, so kann auch nach dem selben Prinzip eine Warnung ausgegeben werden:

    public static void warningDialog(final String message, final Throwable t) {...}

Der Error-Dialog

Fehler beim Erstellen des Vorschaubildes: Datei fehlt
Beispiel für einen Error Dialog

Im erzeugten Dialogfenster werden neben der Fehlermitteilung auch Details zur Exception und die Stack Trace ausgegeben. Sollte eine abgefangene Exception durch eine andere verursacht worden sein, so wird die Stack Trace des Verursachers zur Ausgabe herangezogen.

Weitere Schritte

Hilfesystem

  • Wenn keine Ausnahme in der Map definiert ist, dann könnte in der helpfile - Datenbank gesucht werden. Dabei müsste aber dem User entweder vom MLTutor eine Auswahlmöglichkeit (mehrere Suchresultate!) zur Verfügung gestellt werden, oder es wird eine Page mit Suchfunktionen aufgerufen, wobei letzteres sicher die einfachere Variante wäre.
  • Preference Page?
    mögliche Einstellungen:
    • Angeben der config-Files
    •  ?

Verbindung mit Matlab-Konsole / Verbindungen nach außen

  • Text an Matlab senden und Matlab-Output zurückbekommen (oder holen)
  • Befehl für "Run matlab command"
  • Befehl "isfunction" implementieren und zugänglich machen

Anstehende Refactorings / Verbesserungen

  • RegExRule.evaluate(...)
    Lookaheads und Lookbacks automatisch aus der Regex extrahieren
  • MatlabPartitionScanner
    braucht vom Activator gar nix mehr wissen (configfileDir dem Konstruktor übergeben und "leeren" Konstruktor rausschmeißen)
  • MatlabEnginePrefsPage
    • Maps verwenden als Keys Objekte wie Button oder Text und als Value einen String namens key?!!!!!
      in was Sinnvolles umschreiben, insbesondere da die speziellen Eigenschaften/Vorteile assoziativer Arrays nicht genutzt werden.
  • MatlabConvertTabToSpace
    • ist von MatlabConvertSpaceToTab abgeleitet, weil es eine Funktion braucht. Andere Klassenstruktur einführen, sodass beide gleichwertig behandelt werden.

Diverses

Weitere Seiten

  • Archiv: Hier werden für die aktuelle Entwicklung nicht mehr relevante Texte archiviert.
  • Benutzerseite: Fehlerberichte und Verbesserungsvorschläge
  • Filetools: Diverse selbst programmierte, eigenständige Tools die rund um den MLTutor entwickelt wurden.
  • XML-Export: Seite für den Exporter.

Anmerkungen zur Entwicklung

Folgende Plugins werden vom Meditor-Plugin benötigt (einzutragen bei Dependencies)

  • org.eclipse.core.runtime
  • org.eclipse.core.resources
  • org.eclipse.jdt.ui
  • org.eclipse.jface.text
  • org.eclipse.ui
  • org.eclipse.ui.browser
  • org.eclipse.ui.editors
  • org.eclipse.ui.ide
  • org.eclipse.ui.views
  • org.eclipse.ui.workbench.texteditor

Patterns
Einer der Vorteile von Patterns ist die sehr gute Kommunizierbarkeit. Damit dieser jedoch überhaupt zum Tragen kommen kann müssen verwendete Patterns auch genannt werden. Deshalb werden im Zuge des Ausbaus des Editors neue Anwendungen von Patterns entsprechend gekennzeichnet.

Erstellen eines eigenen Editors (nur Anmerkungen)

  1. Klasse von AbstractTextEditor ableiten
  2. Klasse von SourceViewerConfiguration ableiten
    Dies ist der Ausgangspunkt für das Hinzufügen von eigenen Funktionalitäten
  3. Einen DocumentProvider erweitern um ein IDocument Objekt, welches die Datenrepräsentation darstellt, zu erhalten. Dies ist auch der Ausgangspunkt für Notifacations.
  4. Actions werden in der Funktion createActions() (Memberfunktion des erzeugten Editors) hinzugefügt.

Hinzufügen von Keybindings

Für Extension Points in denen <Action ... > verwendet wird, wie z.B. org.eclipse.ui.editorActions oder org.eclipse.ui.actionSets:

  1. In der Action wird das Attribut definitionId gesetzt.
  2. Dann wird über den Extension Point org.eclipse.ui.commands ein Command definiert.
    • In diesem wird die zuvor vergebene ID im Attribut id wieder verwendet.
    • Weiters wird eine Category benötigt
  3. Die Verknüpfung mit einer Tastenkombination erfolgt mit Hilfe des Extension Points org.eclipse.ui.bindings durch die Definition eines Keys, in welchem die ID im Attribut commandId angegeben wird.

Ein Beispiel:

<extension
  point="org.eclipse.ui.editorActions">
  <editorContribution
    id= "at.tugraz.itp.mltutor.meditor.editors.MatlabHelpAction"
    targetID= "at.tugraz.itp.mltutor.meditor.editors.MatlabEditor">
    <menu id= "Help"
      label="&Help Menu" >
      <separator name= "group1" />
    </menu>
    <action id= "at.tugraz.itp.mltutor.meditor.editors.MatlabHelpAction"
      label= "Matlab help"
      menubarPath="Help/group1"
      class="at.tugraz.itp.mltutor.meditor.editors.MatlabHelpAction"
      definitionId="at.tugraz.itp.mltutor.actions.helpaction">
      <selection class="org.eclipse.core.resources.IFile"
        name="*.m"/>
    </action>
  </editorContribution>
... 
</extension>
...
<extension
  point="org.eclipse.ui.commands">
  <command
    name="Matlab help"
    description="Get matlab help for a function/keyword"
    categoryId="at.tugraz.itp.mltutor.actions"
    id="at.tugraz.itp.mltutor.actions.helpaction">
  </command>
...
  <category
    name="Matlab actions"
    description="Matlab actions"
    id="at.tugraz.itp.mltutor.actions">
  </category>
</extension>
...
<extension
  point="org.eclipse.ui.bindings">
  <key
    sequence="F1"
    commandId="at.tugraz.itp.mltutor.actions.helpaction"
    schemeId="org.eclipse.ui.defaultAcceleratorConfiguration">
  </key>
...
</extension>

Fragen

Offene

  • Soll das Syntax-Highlighting noch verfeinert werden? Derzeit wird folgendes hervorgehoben:
    Kommentare, Zahlen, Strings, Matlab-Funktionen, Keywords, Operatoren
  • Weiß wer wie man in einer Action an die verwendete SourceviewerConfiguration rankommt?
  • Die im Punkt "Anstehende Refactorings / Verbesserungen" geschilderten Probleme betreffend:
    • Wozu waren die diversen Felder und werden sie evtl. noch irgendwann verwendet?
    • Einwände gegen das Entfernen dieser?
  • Nachdem jetzt auf Java 5 umgestellt wurde, auch ÜBERALL generic types verwenden?

Erledigte