Creazione di un IDE utilizzando Pascal Script e SynEdit
-
20-08-2019 - |
Domanda
Sto creando un motore di script integrato usando PascalScript di RemObjects (eccellente) e l'editor SynEdit. Ha quasi finito di usare l'esempio IDE fornito con PascalScript e l'esempio IDE in SynEdit, ma non riesco a vedere come chiedere a PascalScript se una riga di origine numerata è "eseguibile" oppure no. (Posso quindi usarlo per contrassegnare la grondaia SynEdit con il 'punto blu Delphi'). Immagino che dovrei fare un disassemblaggio dell'uscita ROPS?
Qualche esperto PascalScript qui? Grazie. Brian.
Soluzione
Dai un'occhiata al codice sorgente di Inno Setup . Mostra un puntino nell'area del margine interno di SynEdit per le linee con codice eseguibile, quelle grigie per le linee eseguibili ma che non sono state eseguite, quelle verdi per le linee che sono state colpite almeno una volta.
Il codice per questo può essere trovato in CompForm.pas
, cerca il tipo TLineState
. Le informazioni sono impostate nello stato iscbNotifySuccess
del callback del compilatore, è possibile fare lo stesso nel proprio IDE. Potrebbe essere necessario adattare il codice per gestire più file di origine, poiché il compilatore di Inno Setup si occupa dei frammenti di codice solo nel singolo file di origine.
Nelle fonti Pascal Script dovresti dare un'occhiata al metodo TPSCustomDebugExec.TranslatePositionEx()
- restituisce anche il nome del file sorgente.
Altri suggerimenti
Non so esattamente come lo fa, ma il progetto IDE nel pacchetto PascalScript (che si trova in \ samples \ debug) è in grado di offrire funzionalità Step Into e Step Over (F7 e F8), quindi logicamente ha per avere un modo di associare il bytecode PS a righe di codice di script. Prova a esaminare quel progetto per vedere come lo fa. Come bonus, usa anche SynEdit, quindi le idee saranno facili da adattare al tuo sistema.
So che questa è una vecchia domanda, ma ho fatto la stessa cosa da solo e i suggerimenti di cui sopra non mi aiutano molto. In nessuna installazione, ad esempio, non si utilizza Synedit, si utilizza l'editor scintilla.
Anche TPSCustomDebugExec.TranslatePositionEx () fa l'opposto di ciò che si desidera, fornisce un numero di riga di origine da una posizione del codice di runtime.
Dopo essermi lasciato andare per un po 'di tempo, sono giunto alla conclusione che il modo più semplice era aggiungere una funzione al codice Pascalscript.
il nuovo metodo viene aggiunto alla classe TPSCustomDebugExec nell'unità 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 il callback di paint gutter nel modulo dell'editor principale è il seguente
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;
Il Synedit con numeri di riga, punti di codice, punti di interruzione, segnalibri e punto di esecuzione appare come nell'immagine seguente