MultiEdit mit Evolve

Aus Wiki des Deutschsprachige Xbaseentwickler e. V.
Zur Navigation springen Zur Suche springen

Historie

MultiEdit for Windows ist ein Produkt von Multi Edit Software, Incorporated. (früher: American Cybernetics), das von MultiEdit/DOS erfolgreich auf die Windows-Plattform migriert wurde.

Neben dem Zusatzpaket Evolve, das inzwischen zum Lieferumfang gehört, fasziniert bei MEW die Tatsache, dass es derzeit der einzige mir bekannte Editor ist, der auch spaltenorientiert arbeiten kann.

Viele Features von MEW sind heute Standard wie unterschiedliche farbige Darstellung der Syntax, automatisches Einrücken und Macro-Unterstützung.


Evolve

Bill French hatte in den 90er Jahren des vergangenen Jahrhunderts für BRIEF (Basic Reconfigurable Interactive Editing Facility (oder so ähnlich)) einen Zusatz namens dBrief programmiert, der eine Unterstützung von Clipper-Programmierer bereitstellte. Neben der Kenntnis der Clipper-Syntax gab es Zugriff auf DBF-Strukturen und viele hilfreiche Erweiterungen, welche die Programmierung vereinfachten. Irgendwann packte Bill French (im übertragenen Sinne) die Koffer und kam zu MultiEdit/DOS und "portierte" dBrief zu Evolve.

Da Evolve im Quelltext vorliegt, ist es mit geringem Aufwand möglich, Anpassungen und Erweiterungen vorzunehmen.

Ein paar Beispiele:

- gibt man '#in' ein, erscheint '#INCLUDE(".CH")', wobei der Cursor vor dem . steht, so dass man nur noch den Namen der Include-Datei angeben muss;
- '#D' erzeugt ein '#DEFINE ', wobei auch hier der Cursor nach der Leerstelle steht;
- 'fun ' (Leerstelle beachten!) erzeugt ein FUNCTION () / RETURN(.T.) Konstrukt, wobei der Cursor vor der sich öffnenden Klammer steht, wo der Funktionsname eingetragen wird

Wenn man sich an diese Art der Unterstützung gewöhnt hat, tut man sich mit anderen Programmen schwer.




Anpassung des Editierverhaltens für XPJ-Dateien

XPJ ist eine Alaska-eigene Erweiterung, mit der kein Programm etwas anfangen kann. MEW behandelt XPJ-Dateien daher wie Text-Dateien, was unter anderem dazu führt, dass keine Einrückung stattfindet.

Über Tools -> Customize kommt man in den Konfigurations-Dialog. File Name extensions ruft die Konfiguration für bestimmte Dateitypen auf. Über Insert wird ein neuer Satz angelegt, bei dem XPJ als Dateierweiterung eingetragen wird.

- Edit Mode = Text
- Insert Style = Auto
- Language = NONE
- Use tab and margin settings = 8 (Tab spacing), 254 (Right margin)
- Expand to spaces = X

Mit diesen Einstellungen kann man XPJ-Dateien bearbeiten, und das Editierverhalten entspricht dem, was man bereits von PRG-Dateien kennt.

Mit OK wird ein neuer Eintrag angelegt (oder ein bestehender geändert).


Konfiguration von PRG-Dateien

PRG in der Liste markieren und auf Edit klicken.

Die folgenden Eintragungen werde ich:

- Edit Mode = Text
- Indent style = Smart
- Language = CLI.CA-CLIPPER (Xbase++ hat's hier noch nicht zur gewünschten Aufmerksamkeit gebracht)
- Options - Auto-template Expansion = X
- Use tab and margin settings = 3 (Tab spacing), 2048 (Right margin)

Die rechte Grenze sollte so hoch eingestellt werden, damit es nicht zu ungewollten Zeilenumbrüchen kommt, wenn diese Spalte erreicht wird.

Die Änderung - wie gehabt - mit OK speichern.


Konfiguration für CH-Dateien

Auch die CH-Dateien sind Clipper-spezifisch und besitzen keinen entsprechenden Eintrag in der Liste. Das führt dazu, dass CH-Dateien ebenfalls wie Text-Dateien behandelt werden.

Nun liegt es in der Natur der Sache, dass man in CH-Dateien überwiegend #DEFINE und #INCLUDE findet, da es sich aber dem Anschein nach nicht um eine PRG-Datei handelt, greifen auch die automatischen Funktionen von Evolve nicht.

In der Liste der Datei-Erweiterungen PRG anklicken und auf COPY klicken und die Dialog-Seite wieder mit OK schliessen (die Einstellungen sollten alle passen).

Ab jetzt greifen auch die Evolve-Erweiterungen, wenn CH-Dateien editiert werden.


Erweitern von Evolve

Persönlich arbeite ich oft mit externen Dateien, die in Xbase++ über die #PRAGMA-Anweisung eingebunden werden. Leider wurde diese Anweisung in Evolve nicht berücksichtigt, da Evolve sich sehr stark an den Möglichkeiten (und Begrenzungen) von Clipper orientiert.

Ausgehend von Windows 7, 64bit, befinden sich die Evolve-Quellen in

C:\Program Files (x86)\Multi-Edit 2008\AddOns\Evolve

Neben den oben beschriebenen automatischen Erweiterungen, die auf #in oder #de reagieren, gibt es auch die Erweiterungen, die auf fun_ (_ steht für ein Leerzeichen) reagieren. Evolve prüft bei jeder Taste, ob ein entsprechendes Konstrukt hinterlegt ist.

Unter int evEventHandler( Int en ) wird festgelegt, wie auf bestimmte Tasten reagiert wird. Das von mir gewünschte #p_ muss hier erst einmal definiert werden.

Es gibt ein case Konstrukt, bei dem ich vor dem abschliessenden default zwei Abfragen eingefügt habe:

case 112:
  cSequence = cSequence + "P";
  break;
case 80:
  cSequence = cSequence + "p";
  break;

Auf die default-Anweisung folgt eine Abfolge von IF/ELSEIF Anweisungen. Dort habe ich diesen Code eingefügt:

} else if ( (caps(cSequence) == "#P") & ( global_int('!EVgTemplatePrepr') == 1) ) {
  cExpandText = 'ragma Library(".LIB")';
  nMove = -6;
  call expandPreprTemplate;

Dieser Code soll nur ausgeführt werden, wenn TemplateExpansion aktiviert ist. Der zu ergänzende Text besteht aus dem fehlenden Code für die #PRAGMA-Anweisung. Da der Cursor am Ende hinter (!) dem eingefügten Text steht, müsste man den Cursor jedesmal manuell 6 Stellen nach links bewegen. Über die Variable nMove kann man das vorgeben.

Die Funktion expandPreprTemplate übernimmt jetzt das Zusammenfügen und Versetzen des Cursors (da sie eine Standard-Funktion von Evolve ist, wird hier nicht näher auf ihren Aufbau eingegangen).


Alternativ kann man aber auch noch andere Möglichkeiten nutzen. Das gezeigte Beispiel geht von einem vorhandenen Beginn des Konstruktes (#P) aus. Man kann diesen Teil aber auch überschreiben. Auch hierzu ein Beispiel.

Der Trigger #a_ soll zu einer Anweisung übersetzt werden. Zuerst müssen zwei Anweisungen im case-Teil eingefügt werden, die a bzw. A akzeptieren.

} else if ( (caps(cSequence) == "#A") & ( global_int('!EVgTemplatePrepr') == 1) ) {
  cExpandText = 'cLine := Driver=(" + SQLUGetDriverName(oCon) ...'
  nMove = -100;
  cSequence = "  ";
  call expandPreprTemplate;

Den zugewiesenen Text habe ich hier gekürzt. Da auch hier Einträge vorgenommen werden, habe ich den Cursor entsprechend rückpositioniert durch eine entsprechende Zuweisung an nMove.

Damit das in cSequence hinterlegt "#A" nicht im Ergebnis auftaucht, weise ich cSequence einen Leerstring zu. Da in expandPreprTemplate cSequence und cExpandText concatiniert werden, ist es am einfachsten, cSequence zu "löschen".


Anschliessend muss die Datei gespeichert werden, um dann über Tools -> Execute Compiler -> Select compiliert zu werden.

Damit die Änderungen greifen, muss MEW beendet und neu gestartet werden.


Homepage von MultiEdit

Die Homepage von Multiedit ist über MultiEdit.com zu erreichen.