Meditor 101

Aus Physik
Zur Navigation springen Zur Suche springen

Ziel

Ein professioneller Editor für Matlab

Features:

  • Syntax-Highlighting
  • Automatische Einrückung
  • Matching Brackets
  • Templates?
  • Hilfefunktionen?
    • Für Matlab - Funktionen wird die passende Matlab-Hilfeseite aufgerufen (Browser)
      • korrekter Seitennamen kann oft aus dem Funktionsnamen generiert werden
      • Ausnahmen könnten in einem assiozativen Array gespeichert werden (ist Funktionsname im Array, dann nimm die darin angegebene Seite, ansonsten generiere einen Seitennamen)


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

Was fehlt - nächste Schritte

  • Partitionierung verbessern:
    • Differenzieren zwischen dem ' Operator und Strings
    • Bei Eingaben wird die vorhergehende Partition nicht aktualisiert, was in einigen Fällen eine falsche Partitionierung nach sich zieht
  • Änderungen der Preferences Page sollen sofort Auswirkungen zeigen
  • Einrückstragegie um Fortsetzungszeilen erweitern


Anfänglich vorhandene Strukturen

In grün Geschriebenes sind die selbst entwickelten Klassen.

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


Partitionierung des Dokuments

PartitionScanner ist MatlabPartitionScanner.

java.lang.Object
  |- org.eclipse.jface.text.rules.RuleBasedScanner
       |- org.eclipse.jface.text.rules.BufferedRuleBasedScanner
            |- org.eclipse.jface.text.rules.RuleBasedPartitionScanner
                 |- at.tugraz.itp.mltutor.meditor.editors.MatlabPartitionScanner

Der Partitioner ist FastPartitioner (war vorher der deprecated DefaultPartitioner)


Weiters gibt es MatlabScanner, welche allerdings nur für die Erstellung eines DefaultDamageRepairer in der Funktion MatlabConfiguration.getPresentationReconciler(...) verwendet wird.

java.lang.Object
  |- org.eclipse.jface.text.rules.RuleBasedScanner
       |- at.tugraz.itp.mltutor.meditor.editors.MatlabScanner

Warum zwei Scanner:
FastPartitioner wird von MatlabDocumentProvider.createDocument(...) verwendet, und braucht ein IPartitionTokenScanner. Dieses wird von RuleBasedPartitionScanner implementiert, jedoch nicht von RuleBasedScanner. RuleBasedPartitionScanner ist jedoch für IPredicateRules, was von WordRule nicht implementiert ist, gedacht. Letzteres wird für das Scannen nach den Keywords benutzt, weshalb für diesen Zweck letztendlich eine weitere Klasse von RuleBasedScanner abgeleitet wurde.
ABER: es gibt auch die Funktion RuleBasedPartitionScanner.setRules(IRule[] rules), es müsste nur ausprobiert werden, ob die WordRules damit wirklich funktionieren (bin ein wenig durch die Hilfe verwirrt --Osiris).

Ist ausprobiert und: geht NICHT

Indent Strategy

public class MatlabConfiguration extends SourceViewerConfiguration {
    public IAutoIndentStrategy getAutoIndentStrategy(ISourceViewer sourceViewer,String contentType){
        if (autoIndentStrategy == null){
            autoIndentStrategy = new MatlabAutoIndentStrategy();
        }
        return autoIndentStrategy;
    }
    ...
}

Recht ungut weil

  1. Deprecated
  2. MatlabAutoIndentStrategy() ist von DefaultAutoIndentStrategy abgeleitet.
    • Diese ist ebenfalls deprecated
    • Davon soll nicht abgeleitet werden - und vom "neuen" Äquivalent ebenfalls nicht

Eine Änderung des Typs der Indent Strategy hat Auswirkungen in:

  • MatlabConfiguration.autoEditStrategy
  • MatlabConfiguration.getAutoEditStrategies(...)
  • MatlabConfiguration.resetIndentPrefixes()
  • MatlabEditor.indentStrategy
  • MatlabEditor.MatlabEditor()
  • MatlabEditor.resetForceTabs()

- ist mir ein bissi viel - meiner Meinung nach braucht nur die MatlabConfiguration was von der Indent Strategy zu wissen --Osiris 13:45, 1 December 2005 (CET)


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(...)
    • und weiters kann dann MatlabAutoIndentStrategy() nicht mehr von DefaultAutoIndentStrategy, sondern von DefaultIndentLineAutoEditStrategy abgeleitet werden.
      • funktioniert, ist aber nicht gut, da von letzterer nicht abgeleitet werden soll.
    • oder man kann statt MatlabAutoIndentStrategy() gleich DefaultIndentLineAutoEditStrategy verwenden, wofür diese Klasse eigentlich gedacht ist.
      • geht aber nicht direkt, da Funktionen von MatlabAutoIndentStrategy() an diversen Stellen verwendet werden :-(

Partitionierung des Dokuments

Partitionscanner und neue Rule

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 noch eine neue Klasse WhitespaceDetector gebraucht:

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

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 bisher lediglich zwischen den Matlab-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);
}

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
  • Verhalten der Tab-Taste wie im Emacs (auch Java-Editor von Eclipse)
  • 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
  3. tatsächliche Einrückung für die vorhergehende und die neue Zeile herstellen (passende Whitespaces)

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. Feststellen, ob dieses am Zeilenanfang oder im Whitespacebereich am Beginn einer Zeile eingegeben wurde
  2. vorhergehende Zeile analysieren
  3. Einrücktiefe der aktuellen Zeile korrigieren

Struktur

Neue Klasse:

public class MatlabAutoEditStrategy implements IAutoEditStrategy {
    public void setupStrategy(){}
    public void customizeDocumentCommand(IDocument document, DocumentCommand command) {}
    ...
}

Diese wird explizit ansonsten 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))

Allgemein weiß nur MatlabConfiguration was von der Indent Strategy, und dort wird IAutoEditStrategy benutzt.


Weitere Schritte

Partitionierung

Weiters ist das Problem des ' Zeichens zu lösen. Wird dieses als Operator zwei Mal in einer Zeile verwendet, so wird der dazwischenliegende Teil als String interpretiert.

  • Idee: Es gibt eine Regular Expression für Strings mit 'bla', mit der eine RegExRule statt der SinglelineRule verwendet wird. Diese regex müsste dahingehend erweitert werden, dass nur "gültige" Strings als solche erkannt werden

Automatische Einrückung

Anforderungen

Funktionalität:

  • korrekte Einrückung für einen ganzen Abschnitt (das ganze Dokument)?


Diverses

Archiv

Anmerkungen zur Entwicklung

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

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

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.


Fragen

Offene

  • Soll das Syntax-Highlighting noch verfeinert werden? Derzeit wird folgendes hervorgehoben:
    Kommentare, Zahlen, Strings, Matlab-Funktionen, Keywords
    • Operatoren wären noch möglich (schnell über regex implementierbar)

Erledigte

  • Wie wichtig ist eine korrekte Partitionierung des Dokuments? => evt. sollten die beiden Scanner zusammengelegt werden.
Wäre wesentlich schöner und ausbaufähiger wenn es nur einen Scanner gibt
=> werden zusammengelegt. --Osiris 11:34, 24 November 2005 (CET)
  • Deprecated Klassen wegkriegen?
Wäre vielleicht nicht schlecht, unter Eclipse 3.2 solltens aber noch funktionieren, wenn das ähnlich wie beim aktuellen RC läuft. --Camhy 09:18, 14 November 2005 (CET)
Unbedingt notwendig, da man sich typischerweise besser auskennt, wenn man gerade daran arbeitet. Sonst kann sich jemand in relativer zeitlicher Nähe wieder damit bechäftigen. Das heisst insgesamt sollte man bei solchen Projekten eher auf Zukunftssicherheit setzen.--Winny 11:42, 14 November 2005 (CET)
Hätt ich auch gedacht, v.a. da der ML-Tutor einige Eclipse-Upgrades miterleben dürfte. Ich würde sagen, dass das als erstes zu erledigen wär, damit wir gleich auf den "neueren" Klassen aufbauen. --Osiris 11:54, 14 November 2005 (CET)