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.