Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
custom: ['https://pag.ae/7ZhEY1xKr']
github: [Code4Delphi]
custom: ['https://code4delphi.com.br/blog/apoie-com-um-cafe/']
4 changes: 3 additions & 1 deletion Package/DelphiAIDeveloper.dpk
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ contains
DelphiAIDev.Test.Client in '..\Src\Test\DelphiAIDev.Test.Client.pas',
DelphiAIDev.CodeCompletion.KeyTab in '..\Src\CodeCompletion\DelphiAIDev.CodeCompletion.KeyTab.pas',
DelphiAIDev.AI.Response in '..\Src\AI\DelphiAIDev.AI.Response.pas',
DelphiAIDev.AI.Mistral in '..\Src\AI\DelphiAIDev.AI.Mistral.pas';
DelphiAIDev.AI.Mistral in '..\Src\AI\DelphiAIDev.AI.Mistral.pas',
DelphiAIDev.Utils.Context in '..\Src\Utils\DelphiAIDev.Utils.Context.pas',
DelphiAIDev.Test.ContextDemo in '..\Src\Test\DelphiAIDev.Test.ContextDemo.pas';

end.
477 changes: 359 additions & 118 deletions Package/DelphiAIDeveloper.dproj

Large diffs are not rendered by default.

Binary file modified Package/DelphiAIDeveloper.res
Binary file not shown.
26 changes: 2 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Delphi AI Developer (Copilot)
Inspired by GitHub Copilot, Delphi AI Developer is a plugin that adds Artificial intelligence (AI) interaction capabilities to the Delphi IDE, using both the OpenAI API, Gemini API and Groq API, as well as offering offline AI support.
# Delphi AI Developer
Inspired by GitHub Copilot, Delphi AI Developer is a plugin that adds Artificial intelligence (AI) interaction capabilities to the Delphi IDE, using both the OpenAI API, Gemini API, Mistral API and Groq API, as well as offering offline AI support.

With Delphi AI Developer, you will have assistance in generating and refactoring code, facilitating and accelerating development.

Expand All @@ -15,28 +15,6 @@ Receive suggestions for creating and improving code directly in the IDE and take
[![Course](https://img.shields.io/badge/Course-Delphi-F00?logo=delphi)](https://go.hotmart.com/U81331747Y?dp=1)
[![E-mail](https://img.shields.io/badge/E--mail-Send-yellowgreen?logo=maildotru&logoColor=yellowgreen)](mailto:contato@code4delphi.com.br)

<p align="left">
<a href="https://t.me/Code4Delphi" target="_blank">
<img src="https://img.shields.io/badge/Telegram-Join%20Channel-blue?logo=telegram">
</a>
&nbsp;
<a href="https://www.youtube.com/@code4delphi" target="_blank">
<img src="https://img.shields.io/badge/YouTube-Join%20Channel-red?logo=youtube&logoColor=red">
</a>
&nbsp;
<a href="https://www.linkedin.com/in/cesar-cardoso-dev" target="_blank">
<img src="https://img.shields.io/badge/LinkedIn-Follow-blue?logo=LinkedIn&logoColor=blue">
</a>
&nbsp;
<a href="https://go.hotmart.com/U81331747Y?dp=1" target="_blank">
<img src="https://img.shields.io/badge/Course-Open%20Tools%20API-F00?logo=delphi">
</a>
&nbsp;
<a href="mailto:contato@code4delphi.com.br" target="_blank">
<img src="https://img.shields.io/badge/E--mail-Send-yellowgreen?logo=maildotru&logoColor=yellowgreen">
</a>
</p>

## 🚀 INSTALLATION

1 - Download Delphi AI Developer. You can download the .zip file or clone the project on your PC.
Expand Down
7 changes: 7 additions & 0 deletions Src/CodeCompletion/DelphiAIDev.CodeCompletion.Search.pas
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ TDelphiAIDevCodeCompletionSearch = class(TInterfacedObject, IDelphiAIDevCodeCo

implementation

uses
DelphiAIDev.Utils.Context;

class function TDelphiAIDevCodeCompletionSearch.New: IDelphiAIDevCodeCompletionSearch;
begin
Result := Self.Create;
Expand Down Expand Up @@ -83,7 +86,11 @@ procedure TDelphiAIDevCodeCompletionSearch.Process(const AContext: IOTAKeyContex

procedure TDelphiAIDevCodeCompletionSearch.ProcessQuestions(const AContext: IOTAKeyContext);
begin
FVars.FullUnitInterface := TUtilsContext.GetUnitInterfaceCode;

FQuestions.Clear;
if not FVars.FullUnitInterface.Trim.IsEmpty then
FQuestions.Add('Unit Interface Context:' + sLineBreak + FVars.FullUnitInterface);
FQuestions.Add(FSettings.LanguageQuestions.GetLanguageDefinition);
FQuestions.Add(FSettings.LanguageQuestions.GetMsgCodeCompletionSuggestion);
FQuestions.Add(FSettings.LanguageQuestions.GetMsgCodeOnly);
Expand Down
3 changes: 3 additions & 0 deletions Src/CodeCompletion/DelphiAIDev.CodeCompletion.Vars.pas
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ TDelphiAIDevCodeCompletionVars = class
FRow: Integer;
FColumn: Integer;
FContents: TStrings;
FFullUnitInterface: string;
constructor Create;
public
class function GetInstance: TDelphiAIDevCodeCompletionVars;
Expand All @@ -29,6 +30,7 @@ TDelphiAIDevCodeCompletionVars = class
property Row: Integer read FRow write FRow;
property Column: Integer read FColumn write FColumn;
property Contents: TStrings read FContents write FContents;
property FullUnitInterface: string read FFullUnitInterface write FFullUnitInterface;
end;

implementation
Expand Down Expand Up @@ -65,6 +67,7 @@ procedure TDelphiAIDevCodeCompletionVars.Clear;
FRow := 0;
FColumn := 0;
FContents.Clear;
FFullUnitInterface := '';
end;

initialization
Expand Down
48 changes: 48 additions & 0 deletions Src/Test/DelphiAIDev.Test.ContextDemo.pas
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
unit DelphiAIDev.Test.ContextDemo;

interface

uses
System.SysUtils;

type
// Classe de exemplo para testar o Contexto Global da IA
TShoppingCartItem = class
private
FItemName: string;
FQuantity: Integer;
FPrice: Currency;
FDiscount: Currency;
FTotal: Currency;
procedure SetTotal(const Value: Currency);
public
// A IA deve ser capaz de ler estas propriedades na interface
// mesmo que o cursor esteja lá embaixo na implementação.
property ItemName: string read FItemName write FItemName;
property Quantity: Integer read FQuantity write FQuantity;
property Price: Currency read FPrice write FPrice;
property Discount: Currency read FDiscount write FDiscount;
property Total: Currency read FTotal write SetTotal;

// Descomente a linha abaixo antes do teste, parao Delphi não reclamar..
// procedure CalculateFinalPrice;
end;

implementation

{ TShoppingCartItem }

procedure TShoppingCartItem.SetTotal(const Value: Currency);
begin
FTotal := Value;
end;

// -----------------------------------------------------------------------------
// CASO DE TESTE:
// Posicione o cursor na linha abaixo e acione o Code Completion (Alt+Enter padrão)
// Tente algo como: "Implemente o metodo CalculateFinalPrice considerando desconto"
// -----------------------------------------------------------------------------

// << PONTO DE TESTE AQUI >>

end.
75 changes: 75 additions & 0 deletions Src/Utils/DelphiAIDev.Utils.Context.pas
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
unit DelphiAIDev.Utils.Context;

interface

uses
System.SysUtils,
System.Classes,
ToolsAPI;

type
TUtilsContext = class
public
class function GetUnitInterfaceCode: string;
end;

implementation

class function TUtilsContext.GetUnitInterfaceCode: string;
const
ChunkSize = 1024;
var
LModule: IOTAModule;
LEditor: IOTASourceEditor;
LReader: IOTAEditReader;
LBuffer: array[0..ChunkSize - 1] of AnsiChar;
LPartStr: AnsiString;
LTotalText: AnsiString;
LPos: Integer;
LBytesRead: Integer;
LImplPos: Integer;
i: Integer;
begin
Result := '';
if not Assigned(BorlandIDEServices) then Exit;

LModule := (BorlandIDEServices as IOTAModuleServices).CurrentModule;
if not Assigned(LModule) then Exit;

LEditor := nil;
for i := 0 to LModule.GetModuleFileCount - 1 do
begin
if Supports(LModule.GetModuleFileEditor(i), IOTASourceEditor, LEditor) then
Break;
end;

if not Assigned(LEditor) then Exit;

LReader := LEditor.CreateReader;
if not Assigned(LReader) then Exit;

try
LPos := 0;
LTotalText := '';

repeat
LBytesRead := LReader.GetText(LPos, PAnsiChar(@LBuffer), ChunkSize);
if LBytesRead > 0 then
begin
SetString(LPartStr, PAnsiChar(@LBuffer), LBytesRead);
LTotalText := LTotalText + LPartStr;
Inc(LPos, LBytesRead);
end;
until LBytesRead < ChunkSize;

Result := String(LTotalText);

LImplPos := Pos('implementation', LowerCase(Result));
if LImplPos > 0 then
Result := Copy(Result, 1, LImplPos - 1);
finally
LReader := nil;
end;
end;

end.