Hacer un IDE usando Pascal Script y SynEdit
-
20-08-2019 - |
Pregunta
Estoy creando un motor de script incorporado usando PascalScript de RemObjects (excelente) y el editor SynEdit. Casi ha terminado de usar el ejemplo IDE enviado con PascalScript y el ejemplo IDE en SynEdit, pero no puedo ver cómo preguntarle a PascalScript si una línea de origen numerada es 'ejecutable' o no. (Entonces puedo usar esto para marcar el canal SynEdit con el 'punto azul Delphi'). Supongo que podría tener que hacer un desmontaje de la salida ROPS?
¿Algún experto en PascalScript aquí? Gracias. Brian.
Solución
Eche un vistazo al código fuente de Inno Setup . Muestra un pequeño punto en el área de la canaleta SynEdit para líneas con código ejecutable, grises para líneas que son ejecutables pero no se han ejecutado, verdes para líneas que han sido golpeadas al menos una vez.
El código para esto se puede encontrar en CompForm.pas
, busque el tipo TLineState
. La información se configura en el estado iscbNotifySuccess
de la devolución de llamada del compilador, puede hacer lo mismo en su IDE. Es posible que deba adaptar el código para manejar múltiples archivos de origen, ya que el compilador Inno Setup trata con fragmentos de código en el único archivo de origen solamente.
En las fuentes de Pascal Script, debe echar un vistazo al método TPSCustomDebugExec.TranslatePositionEx()
; también devuelve el nombre del archivo fuente.
Otros consejos
No sé exactamente cómo lo hace, pero el proyecto IDE en el paquete PascalScript (que se encuentra en \ samples \ debug) puede ofrecer la funcionalidad Step Into and Step Over (F7 y F8), por lo que lógicamente tiene tener alguna forma de asociar el bytecode de PS con líneas de código de script. Intenta examinar ese proyecto para ver cómo lo hace. Como beneficio adicional, también utiliza SynEdit, por lo que las ideas serán fáciles de adaptar a su propio sistema.
Sé que esta es una vieja pregunta, pero yo he estado haciendo lo mismo y las sugerencias anteriores realmente no ayudan. Inno setup, por ejemplo, no usa Synedit, usa el editor scintilla.
También el TPSCustomDebugExec.TranslatePositionEx () hace lo contrario de lo que se desea, le da un número de línea de origen desde una posición de código de tiempo de ejecución.
Después de perder el tiempo por un tiempo, llegué a la conclusión de que la forma más fácil era agregar una función al código Pascalscript.
el nuevo método se agrega a la clase TPSCustomDebugExec en la unidad 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;
y la devolución de llamada de la canaleta de pintura en el formulario del editor principal es la siguiente
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;
El Synedit con números de línea, puntos de código, puntos de interrupción, marcadores y punto de ejecución se ven como en la imagen a continuación