Intellisense in SynEdit-Komponente

Rund um die LCL und andere Komponenten

Intellisense in SynEdit-Komponente

Beitragvon kirchfritz » 28. Mai 2018, 20:43 Intellisense in SynEdit-Komponente

Hallo,

laut Wikipedia gilt:
"IntelliSense ist ein von Microsoft angebotenes Hilfsmittel zur automatischen Vervollständigung bei der Bearbeitung von Quellcode durch einen Programmierer."
Ich kenne dies vom Lazarus QuelltextEditor, wenn ich hinter dem Namen eines Objects einen Punkt "." eingebe, erscheint die Menge der möglichen Methoden oder Properties in einem Auswahlfenster.
Ich möchte so ein Verhalten jetzt in einer SynEditKomponente in meinem Programm verwenden.
Leider habe ich keine blasse Ahnung, wo man da ansetzen muss.
es gibt zwar ein Beispielprogramm zu SynEdit-AutoCompletion, aber daraus werde ich nicht schlau.
Kann mir mal jemand auf die Sprünge helfen?

Konkret sieht mein Problem so aus:
Ich habe in meinem SynEdit-Text verschiedenste Tags zum Beispiel
<NA>Mustermann<<VN>Max
<ST>Musterstrasse<HN>17
<PZ>12345<PO>Musterstadt

Dabei bedeutet <NA>=Name <VN>=Vorname <ST>=Strasse <HN>=Hausnummer <PZ>=Postleitzahl <PO>=Postort
Wenn man diesen Beispieltext mit dem SynXML-Highllighter im SynEdit-Kontroll darstellt, schaut er sogar super eingefärbt gut aus.

Nun soll der Texterfasser aber die einzelne Bestandteile dieses Adress-Satzes "verschönern"

<NA.s2.f17>Mustermann<VN.f35.s3>Max
<ST>Musterstrasse<HN>17
<PZ>12345<PO>Musterstadt

Die Bedeutung der ersten Zeile wäre dann etwa:
Der Name ist in der Schrift "s2" und in der farbe "f17" auszugeben, während der Vorname in der Schrift "s3" und der farbe "f35" auszugeben ist.
Wie dieser verschönerte Adress-Satz letzt endlich ausgegeben wird, spielt jetzt keine Rolle.

Konkret will ich eigentlich nur erreichen, dass der Erfasser <NA. tippt, und dann die Menge der gültigen Schriften und Farben zur Auswahl gestellt bekommt.

Wie geht das konkret? Jede Hilfe ist willkommen.
kirchfritz
 
Beiträge: 49
Registriert: 3. Jan 2011, 13:34
OS, Lazarus, FPC: Win10 (L 1.7 FPC 3.1.1) | 
CPU-Target: 32Bit
Nach oben

Beitragvon Warf » 29. Mai 2018, 00:35 Re: Intellisense in SynEdit-Komponente

Erstmal, Intellisense ist einfach nur der Microsoft Name für Autovervollständigung. Aber die ist eigentlich ganz einfach.

Du benötigst eine Completion Komponente von der Syn Edit Seite. Die Completion hat zwei events, Execute und SearchPosition. Execute wird aufgerufen wenn die Completion liste gezeigt wird (z.B. Strg + Leer im editor drücken), SearchPosition sobland etwas verändert wird während der Dialog offen ist.

In diesen Events kannst du dann die ItemList der Completion bearbeiten. Den bereits getippten teil des Wortes kannst du mit CurrentString auslesen (um z.B. einen Filter zu machen).
Ein beispiel:
Code: Alles auswählen
 
Completion.ItemList.Clear;
for i := 0 to FCompletionList.Count - 1 do // FCompletionlist enthält alle möglichen vervollständigungen
  if Pos(LowerCase(Completion.CurrentString),
    LowerCase(FCompletionList[i])) >= 1 then // falls das aktuelle wort in dem eintrag vor kommt
      Completion.ItemList.Add(FCompletionList[i]); // Füge zur liste hinzu


Wenn du spaß dran hast kannst du auch im Paint Event syntax highlighting betreiben


Die Syntaxhighlight hingegen wird schon etwas schwieriger. Dafür musst eine neue Highlighter Klasse schreiben und das kann ich dir jetzt auf die schnelle nicht erklären. Dafür gibt es allerdings einen guten Wikieintrag: Link der mir damals sehr geholfen hat.

Ich habe mal eine kleine IDE geschrieben, die kannst du dir ansehen: Link ist allerdings wahrscheinlich schwer reinzukommen (Code schreiben ist immer einfacher als lesen). Aber für dich wären die Verzeichnisse Highlighter und Editor relevant
Warf
 
Beiträge: 985
Registriert: 23. Sep 2014, 16:46
Wohnort: Aachen
OS, Lazarus, FPC: Mac OSX 10.11 | Win 10 | FPC 3.0.0 | L trunk | 
CPU-Target: x86_64, i368, ARM
Nach oben

Beitragvon thosch » 29. Mai 2018, 08:49 Re: Intellisense in SynEdit-Komponente

Da wäre dann noch die Frage zu klären, wie die Completion List gefüllt wird?
thosch
 
Beiträge: 155
Registriert: 10. Jul 2017, 19:32

Beitragvon kirchfritz » 29. Mai 2018, 09:03 Re: Intellisense in SynEdit-Komponente

Bitte der Reihe nach.

Ich habe jetzt mal ein kleines Demo-Programm erstellt und in der Execute-Methode einzig und allein mit

Code: Alles auswählen
ShowMessage(SynCompletion1.CurrentString);


den Currentstring ausgegeben.
Dabei habe ich festgestellt, dass in der Execute-Methode der CurrentString "<NA" lautet, wenn der Cursor hinter "<NA" steht und ich CTRL+Space drücke. Das ist soweit in Ordnung.

Stelle ich aber den Cursor hinter "<NA." , dann ist beim Aufruf der Execute-Methode der CurrentString leer. Das ist aus meiner Sicht nicht erwünscht.

Ich hätte schon gerne, dass man einen Punkt "." eintippt, und dann mit CTRL-Space die Vorschlagsliste zu sehen bekommt.
Weiß jemand, was da gerade schiefläuft, dass der Punkt den CurrentString leert ??

Wozu die SearchPosition Methode gut sein soll erschliesst sich mir nicht.

Das Befüllen der Completion.ItemList sehe ich weniger als Problem. Das ist vielmehr von mir zu erbringende Fleissarbeit.
kirchfritz
 
Beiträge: 49
Registriert: 3. Jan 2011, 13:34
OS, Lazarus, FPC: Win10 (L 1.7 FPC 3.1.1) | 
CPU-Target: 32Bit
Nach oben

Beitragvon Warf » 29. Mai 2018, 16:30 Re: Intellisense in SynEdit-Komponente

kirchfritz hat geschrieben:Bitte der Reihe nach.

Ich habe jetzt mal ein kleines Demo-Programm erstellt und in der Execute-Methode einzig und allein mit

Code: Alles auswählen
ShowMessage(SynCompletion1.CurrentString);


den Currentstring ausgegeben.
Dabei habe ich festgestellt, dass in der Execute-Methode der CurrentString "<NA" lautet, wenn der Cursor hinter "<NA" steht und ich CTRL+Space drücke. Das ist soweit in Ordnung.

Stelle ich aber den Cursor hinter "<NA." , dann ist beim Aufruf der Execute-Methode der CurrentString leer. Das ist aus meiner Sicht nicht erwünscht.

Ich hätte schon gerne, dass man einen Punkt "." eintippt, und dann mit CTRL-Space die Vorschlagsliste zu sehen bekommt.
Weiß jemand, was da gerade schiefläuft, dass der Punkt den CurrentString leert ??

Wozu die SearchPosition Methode gut sein soll erschliesst sich mir nicht.

Das Befüllen der Completion.ItemList sehe ich weniger als Problem. Das ist vielmehr von mir zu erbringende Fleissarbeit.


1. Die SynCompletion hat eine Eigenschaft EndOfTokenChr. Diese enthält die Charaktere die Tokens abtrennen. Standardmäßig sind das (, ), {, }, . Um punkte zu erlaube also einfach nur den . löschen (und eventuell < und > hinzufügen, da die ja nicht direkt zum token gehören)
2. Die Searchposition selbst (also den paramter) verwende ich in meiner IDE selbst auch nicht (ich glaube das ist der aktuelle ItemIndex, kann mich aber auch irren), das Event ist allerdings wichtig, da das immer gefeurt wird sobald sich irgendwas am currentString ändert, du also die Liste anpassen musst (z.B. du hast als vorschäge ABA und AAB. Wenn jemand jetzt A eintippt sollen beide gezeigt werden, wenn man als zweiten Buchstaben B oder A eintippt sollte die liste entsprechend angepasst werden, sodass das andere nicht mehr angezeigt wird)
Warf
 
Beiträge: 985
Registriert: 23. Sep 2014, 16:46
Wohnort: Aachen
OS, Lazarus, FPC: Mac OSX 10.11 | Win 10 | FPC 3.0.0 | L trunk | 
CPU-Target: x86_64, i368, ARM
Nach oben

Beitragvon kirchfritz » 29. Mai 2018, 19:11 Re: Intellisense in SynEdit-Komponente

Gut, das mit dem Punkt habe ich hinbekommen.
Der nächste Schritt wäre jetzt, das die ausgewählte Zeichenkette an den currentstring drangehängt wird und nicht bei Auswahl den currentstring ersetzt.
Wie geht das denn?
kirchfritz
 
Beiträge: 49
Registriert: 3. Jan 2011, 13:34
OS, Lazarus, FPC: Win10 (L 1.7 FPC 3.1.1) | 
CPU-Target: 32Bit
Nach oben

Beitragvon Warf » 29. Mai 2018, 19:58 Re: Intellisense in SynEdit-Komponente

Das ist auch ganz einfach, dafür gibt es das Event CodeCompletion mit der methodensignatur:
Code: Alles auswählen
CodeCompletion(var Value: string;
  SourceValue: string; var SourceStart, SourceEnd: TPoint; KeyChar: TUTF8Char;
  Shift: TShiftState);

Value ist dabei eine variable, und was du da reinschreibst wird dann ersetzt. SourceValue ist die original Value also der CurrentString (kann mich aber auch irren). SourceStart und SourceEnd geben dir die Position im SynEdit an (z.B. accessbar via TextBetweenPoints), Keyhar der Key mit dem Bestätigt wurde, shif enthält die modifikatoren (z.B. wenn strg beim bestätigen gedrückt wurde).

Einfaches Beispiel, hier wird der ausgewählte wert mit einem X vorne dran hingeschrieben statt der normal:
Code: Alles auswählen
CodeCompletion(var Value: string;
  SourceValue: string; var SourceStart, SourceEnd: TPoint; KeyChar: TUTF8Char;
  Shift: TShiftState);
begin
  Value := 'X' + Value;
end;
Warf
 
Beiträge: 985
Registriert: 23. Sep 2014, 16:46
Wohnort: Aachen
OS, Lazarus, FPC: Mac OSX 10.11 | Win 10 | FPC 3.0.0 | L trunk | 
CPU-Target: x86_64, i368, ARM
Nach oben

• Themenende •

Zurück zu Komponenten und Packages



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 5 Gäste

porpoises-institution
accuracy-worried