Fazer uma IDE usando Pascal Script e SynEdit
-
20-08-2019 - |
Pergunta
Estou criando um built-in motor de script usando PascalScript de RemObjects (excelente) e o editor SynEdit. É quase terminado de usar o exemplo IDE fornecido com PascalScript eo exemplo IDE em SynEdit - mas - eu não posso ver como pedir PascalScript se uma linha fonte numerada é 'executável' ou não. (Posso, então, usar isso para marcar a sarjeta SynEdit com o 'ponto azul Delphi'). Eu acho que pode ter que fazer uma desmontagem da saída ROPS?
Qualquer especialistas PascalScript aqui? Obrigado. Brian.
Solução
Tenha um olhar para o código-fonte do Inno Setup . Ele mostra um pequeno ponto na área da calha do SynEdit para linhas com código executável, os cinzentos para linhas que são executáveis, mas não foram executados, uns verdes para as linhas que foram atingidos pelo menos uma vez.
O código para esta pode ser encontrada em CompForm.pas
, olhar para o tipo TLineState
. A informação está configurado no estado iscbNotifySuccess
do retorno do compilador, você poderia fazer o mesmo em seu IDE. Pode ser necessário adaptar o código para lidar com vários arquivos de origem, como o Inno Setup ofertas de compilador com trechos de código no arquivo de origem única.
Nas fontes Pascal Script você deve ter um olhar para o método TPSCustomDebugExec.TranslatePositionEx()
-. Ele não retornar o nome do arquivo de origem, bem
Outras dicas
Eu não sei exatamente como ele faz isso, mas o projeto IDE no pacote PascalScript (encontrado em \ samples \ debug) é capaz de funcionalidade oferta Step Into e Step Over (F7 e F8), então logicamente ele tem de ter alguma forma de associar PS bytecode com linhas de código script. Tente examinar o projeto para ver como ele faz isso. Como um bônus, ele usa SynEdit também, então as idéias será fácil se adaptar ao seu próprio sistema.
Eu sei que isto é uma questão de idade, mas tenho vindo a fazer a mesma coisa a mim mesmo e as sugestões acima realmente não ajuda. Inno configuração, por exemplo, não usa SynEdit, ele usa editor scintilla.
Além disso, o TPSCustomDebugExec.TranslatePositionEx () faz o oposto do que é procurado, dá um número de linha de origem a partir de uma posição do código de tempo de execução.
Depois de faffing torno de algum tempo, cheguei à conclusão de que a maneira mais fácil era para adicionar uma função para o código PascalScript.
o novo método é adicionado à classe TPSCustomDebugExec na unidade uPSdebugger.
function TPSCustomDebugExec.HasCode(Filename:string; LineNo:integer):boolean;
var i,j:integer; fi:PFunctionInfo; pt:TIfList; r:PPositionData;
begin
result:=false;
for i := 0 to FDebugDataForProcs.Count -1 do
begin
fi := FDebugDataForProcs[i];
pt := fi^.FPositionTable;
for j := 0 to pt.Count -1 do
begin
r:=pt[j];
result:= SameText(r^.FileName,Filename) and (r^.Row=LineNo);
if result then exit
end;
end;
end;
e a chamada de retorno sarjeta tinta na forma de edição principal é como abaixo
procedure Teditor.PaintGutterGlyphs(ACanvas:TCanvas; AClip:TRect;
FirstLine, LastLine: integer);
var a,b:boolean; LH,LH2,X,Y,ImgIndex:integer;
begin
begin
FirstLine := Ed.RowToLine(FirstLine);
LastLine := Ed.RowToLine(LastLine);
X := 14;
LH := Ed.LineHeight;
LH2:=(LH-imglGutterGlyphs.Height) div 2;
while FirstLine <= LastLine do
begin
Y := LH2+LH*(Ed.LineToRow(FirstLine)-Ed.TopLine);
a:= ce.HasBreakPoint(ce.MainFileName,FirstLine);
b:= ce.Exec.HasCode(ce.MainFileName,FirstLine);
if Factiveline=FirstLine then
begin
if a then
ImgIndex := 2 //Blue arrow+red dot (breakpoint and execution point)
else
ImgIndex := 1; //Blue arrow (current line execution point)
end
else
if b then
begin
if a then
ImgIndex := 3 //Valid Breakpoint marker
else
ImgIndex := 0; //blue dot (has code)
end
else
begin
if a then
ImgIndex := 4 //Invalid breakpoint (No code on this line)
else
ImgIndex := -1; //Empty (No code for line)
end;
if ImgIndex >= 0 then
imglGutterGlyphs.Draw(ACanvas, X,Y,ImgIndex);
Inc(FirstLine);
end;
end;
end;
O SynEdit com números de linha, pontos de código, pontos de interrupção, marcadores e ponto de execução olhar como na imagem abaixo