amxmodx/editor/editor2/UnitTextAnalyze.pas
2005-05-18 20:54:43 +00:00

206 lines
7.7 KiB
ObjectPascal
Executable File

unit UnitTextAnalyze; // Unit for analyzing code for code explorer, auto
// complete and call tips
interface
uses SysUtils, Classes, ComCtrls, Windows, Forms, Messages, ScintillaLanguageManager;
procedure UpdateList(Code: String);
procedure AddAutoComplete(eAdd: String; AddCallTip: Boolean);
var eExpand1, eExpand2, eExpand3, eExpand4, eExpand5: Boolean;
implementation
uses UnitfrmMain, UnitFunc;
procedure UpdateList(Code: String);
var i, k: integer;
eStr, eStr2: TStringList;
eEndVariables: Boolean;
eParent1, eParent2, eParent3, eParent4, eParent5: TTreeNode;
eBracketsOpen, eStartLine: Integer;
eTemp: String;
begin
eStr := TStringList.Create;
eStr2 := TStringList.Create;
eStr.Text := Code;
frmMain.sacComplete.AStrings.Text := frmMain.StdAutoComplete;
frmMain.cltEditor.ApiStrings.Text := frmMain.StdCallTips;
frmMain.trvFunctions.Items.BeginUpdate;
for i := 0 to 4 do
frmMain.trvFunctions.Items[i].DeleteChildren;
for i := eStr.Count -1 downto 0 do begin
eStr[i] := TrimLeft(eStr[i]);
if (Pos('//', eStr[i]) > 0) then
eStr[i] := Copy(eStr[i], 1, Pos('//', eStr[i]) -2);
if (Pos('/*', eStr[i]) > 0) then
eStr[i] := Copy(eStr[i], 1, Pos('/*', eStr[i]) -2);
if (Pos('*', eStr[i]) = 1) then
eStr.Delete(i);
if (Pos('*/', eStr[i]) > 0) then
eStr[i] := Copy(eStr[i], 1, Pos('*/', eStr[i]) -2);
end;
eEndVariables := False;
eBracketsOpen := -1;
eStartLine := -1;
eParent1 := frmMain.trvFunctions.Items[3];
eParent2 := frmMain.trvFunctions.Items[1];
eParent3 := frmMain.trvFunctions.Items[4];
eParent4 := frmMain.trvFunctions.Items[0];
eParent5 := frmMain.trvFunctions.Items[2];
for i := 0 to eStr.Count -1 do begin
// Included:
if Pos('#include', LowerCase(eStr[i])) = 1 then begin
if (ExtractFileExt(Between(eStr[i], '<', '>')) = '') and (ExtractFileExt(Between(eStr[i], '"', '"')) = '') then begin
if Pos('<', eStr[i]) > 0 then
frmMain.trvFunctions.Items.AddChild(eParent1, Between(eStr[i], '<', '>') + '.inc')
else
frmMain.trvFunctions.Items.AddChild(eParent1, Between(eStr[i], '"', '"') + '.inc');
end
else begin
if Pos('<', eStr[i]) > 0 then
frmMain.trvFunctions.Items.AddChild(eParent1, Between(eStr[i], '<', '>'))
else
frmMain.trvFunctions.Items.AddChild(eParent1, Between(eStr[i], '"', '"'));
end;
end;
// Defined
if Pos('#define', LowerCase(eStr[i])) = 1 then begin
eStr[i] := Copy(eStr[i], 8, Length(eStr[i]));
if Pos(#32, eStr[i]) <> 0 then begin
frmMain.trvFunctions.Items.AddChild(eParent2, Copy(TrimLeft(eStr[i]), 1, Pos(#32, TrimLeft(eStr[i])) -1));
AddAutoComplete(Copy(TrimLeft(eStr[i]), 1, Pos(#32, TrimLeft(eStr[i])) -1), False);
end
else begin
frmMain.trvFunctions.Items.AddChild(eParent2, TrimLeft(eStr[i]));
AddAutoComplete(TrimLeft(eStr[i]), False);
end;
end;
// Variables and constants
if not eEndVariables then begin
if Pos('new', LowerCase(eStr[i])) = 1 then begin
if Pos(',', eStr[i]) > 0 then begin
eStr2.Text := StringReplace(Trim(Copy(eStr[i], 4, Length(eStr[i]))), ',', #13, [rfReplaceAll]);
for k := 0 to eStr2.Count -1 do begin
if Pos('=', eStr[i]) = 0 then
frmMain.trvFunctions.Items.AddChild(eParent3, Trim(eStr2[k]))
else
frmMain.trvFunctions.Items.AddChild(eParent4, Trim(eStr2[k]));
AddAutoComplete(Trim(eStr2[k]), False);
end;
end
else if Pos('{', Trim(eStr[i])) = Length(Trim(eStr[i])) then begin
if Pos('=', eStr[i]) = 0 then
frmMain.trvFunctions.Items.AddChild(eParent3, TrimLeft(Copy(eStr[i], 4, Length(eStr[i]))) + ' Array }')
else
frmMain.trvFunctions.Items.AddChild(eParent4, TrimLeft(Copy(eStr[i], 4, Length(eStr[i]))) + ' Array }');
AddAutoComplete(Trim(Copy(eStr[i], 1, Pos('{', eStr[i]) -1)), False);
end
else begin
if Pos('=', eStr[i]) = 0 then
frmMain.trvFunctions.Items.AddChild(eParent3, TrimLeft(Copy(eStr[i], 4, Length(eStr[i]))))
else
frmMain.trvFunctions.Items.AddChild(eParent4, TrimLeft(Copy(eStr[i], 4, Length(eStr[i]))));
AddAutoComplete(TrimLeft(Copy(eStr[i], 4, Length(eStr[i]))), False);
end;
end;
end;
// Functions
if (Pos('forward', LowerCase(eStr[i])) = 1) or (Pos('public', LowerCase(eStr[i])) = 1) or (Pos('native', LowerCase(eStr[i])) = 1) or (Pos('stock', LowerCase(eStr[i])) = 1) then begin
eBracketsOpen := 0;
eEndVariables := True;
if ((Pos('{', eStr[i]) = 0)) or (Pos('{', eStr[i]) <> 0) and (Pos('}', eStr[i]) <> 0) then begin
eTemp := Copy(eStr[i], 1, Pos(#32, eStr[i]));
frmMain.FunctionType.Add(eTemp);
frmMain.trvFunctions.Items.AddChild(eParent5, Copy(eStr[i], Pos(#32, eStr[i]) +1, Length(eStr[i])));
AddAutoComplete(Copy(eStr[i], Pos(#32, eStr[i]) +1, Length(eStr[i])), True);
end;
end;
if Pos('{', eStr[i]) <> 0 then begin
if eStartLine = -1 then
eStartLine := i;
Inc(eBracketsOpen, 1);
end;
if Pos('}', eStr[i]) <> 0 then begin
Inc(eBracketsOpen, -1);
if (eBracketsOpen = 0) then begin
eStr[eStartLine] := StringReplace(eStr[eStartLine], '{', '', [rfReplaceAll]);
eStr[eStartLine] := TrimRight(eStr[eStartLine]);
if (Pos(#32, eStr[eStartLine]) <> 0) and (Pos(#32, eStr[eStartLine]) < Pos('(', eStr[eStartLine])) then
eTemp := Copy(eStr[eStartLine], 1, Pos(#32, eStr[eStartLine]))
else
eTemp := '';
frmMain.FunctionType.Add(eTemp);
frmMain.trvFunctions.Items.AddChild(eParent5, Copy(eStr[eStartLine], Pos(#32, eStr[eStartLine]) +1, Length(eStr[eStartLine])));
AddAutoComplete(Copy(eStr[eStartLine], Pos(#32, eStr[eStartLine]) +1, Length(eStr[eStartLine])), True);
eStartLine := -1;
eBracketsOpen := -2;
end;
end;
end;
for i := frmMain.trvFunctions.Items.Count -1 downto 0 do begin
if Assigned(frmMain.trvFunctions.Items[i].Parent) then begin
frmMain.trvFunctions.Items[i].ImageIndex := 20;
frmMain.trvFunctions.Items[i].SelectedIndex := 20;
end
else begin
frmMain.trvFunctions.Items[i].ImageIndex := 18;
frmMain.trvFunctions.Items[i].SelectedIndex := 18;
end;
if frmMain.trvFunctions.Items[i].Text = '' then // Remove empty items
frmMain.trvFunctions.Items.Delete(frmMain.trvFunctions.Items[i]);
end;
eStr.Free;
eStr2.Free;
frmMain.trvFunctions.Items.AlphaSort(True);
frmMain.trvFunctions.FullExpand;
if not eExpand1 then
eParent1.Collapse(False);
if not eExpand2 then
eParent2.Collapse(False);
if not eExpand3 then
eParent3.Collapse(False);
if not eExpand4 then
eParent4.Collapse(False);
if not eExpand5 then
eParent5.Collapse(False);
frmMain.trvFunctions.Perform(WM_VSCROLL, SB_TOP, 0);
frmMain.trvFunctions.Items.EndUpdate;
Application.ProcessMessages;
end;
procedure AddAutoComplete(eAdd: String; AddCallTip: Boolean);
function AlreadyAdded: Boolean;
var i: integer;
eTemp: String;
begin
Result := False;
eTemp := Trim(eAdd);
for i := 0 to frmMain.sacComplete.AStrings.Count -1 do begin
if Trim(frmMain.sacComplete.AStrings[i]) = eAdd then
Result := True;
if Trim(frmMain.sacComplete.AStrings[i] + '()') = eAdd then
Result := True;
end;
end;
begin
if not AlreadyAdded then begin
if Pos('(', eAdd) <> 0 then
frmMain.sacComplete.AStrings.Add(Copy(eAdd, 1, Pos('(', eAdd) -1))
else
frmMain.sacComplete.AStrings.Add(eAdd);
if AddCallTip then
frmMain.cltEditor.ApiStrings.Add(eAdd);
end;
end;
end.