Создание IDE с использованием Pascal Script и SynEdit
-
20-08-2019 - |
Вопрос
Я создаю встроенный механизм сценариев, используя PascalScript из RemObjects (отлично) и редактор SynEdit.Он почти закончен с использованием примера IDE, поставляемого с PascalScript, и примера IDE в SynEdit, но я не понимаю, как спросить PascalScript, является ли пронумерованная строка исходного кода «исполняемой» или нет.(Затем я могу использовать это, чтобы пометить желоб SynEdit синей точкой Delphi).Полагаю, мне, возможно, придется разобрать выход ROPS?
Есть здесь эксперты по PascalScript?Спасибо.Брайан.
Решение
Взгляните на исходный код Настройка Инно.В области желоба SynEdit отображается небольшая точка для строк с исполняемым кодом, серые — для строк, которые являются исполняемыми, но не были выполнены, зеленые — для строк, которые были выполнены хотя бы один раз.
Код для этого можно найти в CompForm.pas
, ищите TLineState
тип.Информация размещается в iscbNotifySuccess
состояние обратного вызова компилятора, вы можете сделать то же самое в своей IDE.Возможно, вам придется адаптировать код для обработки нескольких исходных файлов, поскольку компилятор Inno Setup работает с фрагментами кода только в одном исходном файле.
В исходниках Pascal Script вам следует взглянуть на TPSCustomDebugExec.TranslatePositionEx()
метод - он также возвращает имя исходного файла.
Другие советы
Я не знаю точно, как он это делает, но проект IDE в пакете PascalScript (находится в \samples\debug ) может предлагать функции Step Into и Step Over (F7 и F8), поэтому логически он должен иметь некоторые способ связывания байт-кода PS со строками кода сценария.Попробуйте изучить этот проект, чтобы увидеть, как он это делает.В качестве бонуса он также использует SynEdit, поэтому идеи можно будет легко адаптировать к вашей собственной системе.
Я знаю, что это старый вопрос, но я сам делал то же самое, и приведенные выше предложения не очень помогают.Например, установка Inno не использует Synedit, а использует редактор scintilla.
Кроме того, TPSCustomDebugExec.TranslatePositionEx() делает противоположное желаемому: он дает номер исходной строки из позиции кода времени выполнения.
Повозившись некоторое время, я пришел к выводу, что проще всего добавить функцию в код Pascalscript.
новый метод добавляется в класс TPSCustomDebugExec в модуле 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;
и обратный вызов поля краски в форме основного редактора выглядит следующим образом:
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;
Synedit с номерами строк, точками кода, точками останова, закладками и точкой выполнения выглядит, как на изображении ниже.