![]() |
AutoComplete mit SynEdit
Liste der Anhänge anzeigen (Anzahl: 1)
Ich möchte gerne einen AutoComplete ala Delphi realisieren, wie kann ich das machen ? Wenn ich das richtige Kürzel eintrage und mein AutoComplete per Tastenkombination aufrufe, vervollständigt er meinen Code. Nur wenn ich jetzt einen Bruchteil davon eingebe und die Tastenkombination drücke kommt keine Auswahl, so wie in Delphi (s. Bild im Anhang).
Ich nehme als Ausgang die Demo AutoCompleteDemo von SynEdit. |
Re: AutoComplete mit SynEdit
Hi,
bei mir geht das ohne Probleme. Ich habe es nur schnell so gemacht: SynEdit auf's Formular, TSynAutoComplete ebenfalls und mit dem SynEdit verknüpfen und habe bei TSynAutoComplete das eingegeben: Zitat:
Edit: Oder meinst du bei doppelten Einträgen? Da geht es bei mir auch nicht, sehe ich gerade. :gruebel: |
Re: AutoComplete mit SynEdit
Wenn ich es genau so mache wie Du, bekomme ich die folgene Zeile im SynEdit :
Zitat:
|
Re: AutoComplete mit SynEdit
Hi,
da musst du einfach unter "options" von TSynAutoComplete scoUseInsertList auf true stellen. |
Re: AutoComplete mit SynEdit
Danke Matthias. Das funktioniert schonmal soweit. Auch das mit den mehreren Zeilen habe ich jetzt hinbekommen. Dazu muss folgendes in die AutoCompleteList eingetragen werden :
Code:
Damit wird der mehrzeilge Case-Befehl ins SynEdit eingetragen. Trotzdem bleibt es mit immer noch ein Rätsel, wie ich das Popup suaber hinbekomme, so wie es im ersten Beitrag im Bild zu sehen ist.
arrayd
=array[0..|] of ; arrayc =array[0..|] of = (); cases =case | of = : ; = : ; =end; |
Re: AutoComplete mit SynEdit
So, habe es jetzt erstmal gelöst. Vielleicht nicht ganz elegant, aber es funktioniert.
Man füllt eine Datei mit folgenden Inhalt :
Code:
Diese Datei speichert man als einfach Textfile ab. Dann lädt man dieses Textfile in die Komponente TSynAutoComplete. Danach wendet man noch den folgenden Code an :
[select | Einfache Select-Anweisung]
select | from ; [selectw | Select-Anweisung mit Where] select | from | where |; [created | Erstellen einer Datenbank] create database |; [createt | Erstellen einer Tabelle] CREATE TABLE | ( );
Delphi-Quellcode:
Und dann erzeugt man noch die folgende Procedure :
CompletionCmd.InsertList := fAutoComplete.Completions;
for counter := 0 to fAutoComplete.CompletionComments.Count - 1 do begin CompletionCmd.ItemList.Add(fAutoComplete.Completions.Strings[counter] + ' | ' + fAutoComplete.CompletionComments.Strings[counter]); end;
Delphi-Quellcode:
Nun wird der Insert-Wert aus der Komponente TSynCompletionProposol (hier mit CompletionCmd bezeichnet) an die Komponete TSynAutoComplete übergeben und der dazugehörige Code im SynEditMemo eingefügt.
procedure TMainEditForm.CompletionCmdAfterCodeCompletion(Sender: TObject;
const Value: String; Shift: TShiftState; Index: Integer; EndToken: Char); begin fAutoComplete.ExecuteCompletion(CompletionCmd.InsertItem(Index),SynEditMemo); end; |
Re: AutoComplete mit SynEdit
Hallo!
Kann mir wirklich niemend helfen bei der Codevervollständigung des SynEdit Projektes? Hier ist das Demo Beispiel. Das funktioniert. Warum aber funktioniert dann mein Lösung nicht? Die ist im Quellcode mit der Methode Assign
Delphi-Quellcode:
Warum wird mein Editor nicht korrekt zugewiesen. Im übergeordneten Programm habe ich bereits meinen zuzuweisenden Editor auf NIL getestet. Mein zuzuweisender Editor ist gültig, das heißt er ist nicht NIL und ich erhalten den Quelltext des Editors, für den ich die Codevervollständigung realisieren will. Der AutoCompleter ist auch zugewiesen. Nur der Editor lässt sich aus mir rätselhaftem Grund nicht an die Editoreigenschaft des AutoCompleters zuweisen.
unit frmMain1;
{$I SynEdit.inc} interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, SynEditHighlighter, SynHighlighterPas, SynEdit, SynEditKeyCmds, SynEditAutoComplete, Menus; type TForm1 = class(TForm) SynEdit1: TSynEdit; SynPasSyn1: TSynPasSyn; MainMenu1: TMainMenu; miNewForm: TMenuItem; procedure FormCreate(Sender: TObject); procedure miNewFormClick(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private fAutoComplete: TSynAutoComplete; end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.FormCreate(Sender: TObject); begin if Application.MainForm = nil then begin fAutoComplete := TSynAutoComplete.Create(Self); fAutoComplete.Editor := SynEdit1; fAutoComplete.AutoCompleteList.LoadFromFile('Delphi32.dci'); end else Form1.fAutoComplete.AddEditor(SynEdit1); SynEdit1.AddKey(ecAutoCompletion, word('J'), [ssCtrl], 0, []); end; procedure TForm1.miNewFormClick(Sender: TObject); begin with TForm1.Create(Application) do Show; end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin Action := caFree; end; end. //Schöni-Lösung: //Diese wird bei jedem Öffnen eines neuen Editors aufgerufen procedure TfpasIDE.AssignCodeCompletion(AEditor: TSynEdit); begin if Assigned(AutoCompleter) then begin if AutoCompleter.AutoCompleteList.Count = 0 then AutoCompleter.LoadFromFile('fp.dci'); //Damit die Datei mit den Codevervollständigungen nur einmal beim ersten Aufruf der //Methode gelesen und später nur noch verwendet wird. AutoCompleter.Editor := AEditor; //AddEditor wird intern aufgerufen und Editor ist der aktuelle Editor if Assigned(AutoCompleter.Editor) then AutoCompleter.Editor.AddKey(ecAutoCompletion, word('J'), [ssCtrl], 0, []); //Der Editor wird nicht zugewiesen, was ich daran sehe, das ich ohne die "If Assigned() Abfrage //eine Exception erhalte und zwar eine EAccessViolation. Der Debugger springt dann in AddKey von //TCustomSynEdit. //Warum aber wird der Editor nicht zugewiesen? end; end; //Mein AutoCompleter sieht so aus: unit CompleteManager; interface uses Sysutils, Classes, SynEditAutoComplete, SynCompletionProposal, SynEdit; type //Der TAutoCompleteManager ist entstanden, weil ich mir auch die Demos von //TSynCompletionProposal angeguckt habe und dort die Codes und die Vervollständigungen //in 2 verschidenen Listen verwaltet werden und ich eine Vereinfachung des resultierenden //Codes haben will. TAutoCompleteManager = class(SynCompletionProposal.TSynCompletionProposal) private public //Hier kann ich die AutoCompleteList aus dem AutoCompleter zuweisen procedure Assign(AList: TStrings); //Hier weise ich die beiden gtrennten Listen zu, wie das im Demobeispiel //vorgeführt wird, allerdings ohne diese Klasse. Dort passiert das einfach //im Quellcode unter Nutzung der Originalklasse TSynCompletionProposal procedure AssignList(AList: TStrings; Separator: String; AComments: TStrings); end; //Hier ist nun eine verbesserte AutoComplete Klasse TAutoCompleter = class(SynEditAutoComplete.TSynAutoComplete) private FCompleteManager: TAutoCompleteManager; public procedure Assign(AList: TStrings); constructor Create(AOwner: TComponent); destructor Destroy; override; procedure LoadFromFile(Filename: String); //Falls ich in der Finalversion die Funktionalitäten beider Kompnenten //zusammenfassen muss, um ein optimales Ergebnis zu erhalten. property CompleteManager: TAutoCompleteManager read FCompleteManager; end; var AutoCompleter: TAutoCompleter; AutoCompleteManager: TAutoCompleteManager; implementation type TManagerContainer = class(SynCompletionProposal.TSynAutoComplete) private public end; //Diese Klasse TSynAutoComplete ist namensgleich mit TSynAutoComplete in //TSynEditAutoComplete. Deshalb habe ich auch die Unitnamen vor den Namen //der Vorfahrklasse gesetzt. Die namensgleiche Klasse in der Unit mit dem //Namen TSynCompletionProposal ist jedoch anders inmlementiert, als die //gleichnamige Klasse in der Unit SynEditAutoComplete, die ich für die //Codevervollständigung verwende. Falls die TSynAutoComplete-Klasse des //hiesigen Imlementationsteils zur Unterstützung des AutoComplete-Managers, //abgeleitet von TSynCompltionProposal, benötigt wird, ist sie hier als //Typdefinition vorhanden. Sollte sie hier nicht gebraucht werden in der //Finalversion dieser Unit, werde ich sie später entfernen. { TAutoCompleteManager } procedure TAutoCompleteManager.Assign(AList: TStrings); begin ItemList.Assign(AList); end; procedure TAutoCompleteManager.AssignList(AList: TStrings; Separator: String; AComments: TStrings); var Counter: Integer; begin InsertList.Assign(AList); for Counter := 0 to AComments.Count - 1 do ItemList.Add(AList[Counter]+Separator+AComments[Counter]); end; { TAutoComplete } procedure TAutoCompleter.Assign(AList: TStrings); begin AutoCompleteList.Assign(AList); end; constructor TAutoCompleter.Create(AOwner: TComponent); begin inherited Create(AOwner); FCompleteManager := TAutoCompleteManager.Create(AOwner); AutoCompleteManager := FCompleteManager; AutoCompleter := self; end; destructor TAutoCompleter.Destroy; begin FCompleteManager.Free; inherited Destroy; end; procedure TAutoCompleter.LoadFromFile(FileName: String); begin AutoCompleteList.LoadFromFile(FileName); end; end. Wer kann mir hier helfen? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:39 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz