[no repro] ATSynEdit: TFPSList.CheckIndex error
[no repro] ATSynEdit: TFPSList.CheckIndex error
TFPSList.CheckIndex(AIndex : Integer); ATSynEdit_fgl threw an error
I am not able back track it. I searched for the problem and there was an indexed web page on this problem but the web page have been deleted. From the Google search it suggested that this error can have something to do with undo redo.
Any idea what could cause such an error?
Thanks,
Rune
I am not able back track it. I searched for the problem and there was an indexed web page on this problem but the web page have been deleted. From the Google search it suggested that this error can have something to do with undo redo.
Any idea what could cause such an error?
Thanks,
Rune
Sorry for taking a long time to reply. I had to make a simple example that reproduce the error which toke me some time since I was not sure what caused the error. I am now rather confident that the problem is related to the lexers. I made the below program using the components from CudaText. Note it is possible that I am not using the components correctly. For the below program, I have a directory in the program folder named "lex" with the Lexers from CudaText. I then open four files (three small R files and one big R file of 5000 lines) and then move up and down in the listbox to change the code. After a short while "procedure TFPSList.CheckIndex(AIndex : Integer);" is triggered. If I do not load a big R file then I have not been able to trigger "procedure TFPSList.CheckIndex(AIndex : Integer);". However, it might be that this just requires more time for the error to appear. The error can be reproduced with different big R files typically above 3000 lines.
Thanks,
Rune
Thanks,
Rune
Code: Select all
unit main;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls,
Menus, ComCtrls,LazFileUtils, IniFiles,
ATSynEdit,ec_SyntAnal,FileUtil,proc_globdata,ec_LexerList,proc_lexer_styles,ATSynEdit_Adapter_EControl,ATSynEdit_Gutter_Decor;
type
{ TForm1 }
TForm1 = class(TForm)
btnStop: TButton;
ed: TATSynEdit;
GroupBox1: TGroupBox;
GroupBox2: TGroupBox;
GroupBox3: TGroupBox;
Label1: TLabel;
Label2: TLabel;
ListBox1: TListBox;
MainMenu1: TMainMenu;
MenuItem1: TMenuItem;
MenuItem2: TMenuItem;
OpenDialog1: TOpenDialog;
progress: TProgressBar;
Splitter1: TSplitter;
Splitter2: TSplitter;
Splitter3: TSplitter;
StatusMsg: TStatusBar;
procedure edChange(Sender: TObject);
procedure edChangeCaretPos(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure ListBox1Click(Sender: TObject);
procedure MenuItem2Click(Sender: TObject);
private
homedir:string;
codefiles:Tstringlist;
codefilesL:array of tstringlist;
Icurrent:integer;
Adapter:TATAdapterEControl;
function getIndexOfCurrentLine:integer;
function getIndexOfCursorX:integer;
public
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.edChangeCaretPos(Sender: TObject);
begin
label2.Caption:='X: '+inttostr(self.getIndexOfCursorX)+' Y: '+inttostr(self.getIndexOfCurrentLine); // +' cnt:'+inttostr(self.globalPositionOfCursor)+' '+ed.text[self.globalPositionOfCursor]
end;
procedure TForm1.edChange(Sender: TObject);
begin
ed.Gutter.Update;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
i,j:integer;
ini: TIniFile;
an: TecSyntAnalyzer;
fn, fn_ops,LexName:string;
ListFiles:Tstringlist;
begin
homedir:=ExtractFileDir(ParamStr(0));//GetCurrentDir;
// basic options for editor
ed.Font.Name:= 'Courier New';
ed.Font.size:=10;
ed.Align:= alClient;
ed.OptUnprintedVisible:= false;
ed.OptRulerVisible:= true;
ed.OptWrapMode:=cWrapOn;
ed.Colors.TextBG:= $ffffff; // ;
ed.OptCaretVirtual:=false;
// adapters
ListFiles:=Tstringlist.Create;
FindAllFiles(ListFiles, form1.homedir+'/lex', '*.lcf', false);
ListFiles.Sort;
if ListFiles.Count=0 then
showmessage('No lex files found!');
AppManager:= TecLexerList.Create(Self);
//ListFiles.Add('/media/rune/DATA/New2/lazarus/programs/RscripterCool/lex/R.lcf');
for i:= 0 to ListFiles.Count-1 do
begin
an:= AppManager.AddLexer;
//an.Name:= '_lx_'+LexerFilenameToComponentName(ListFiles[i]);
an.LoadFromFile(ListFiles[i]);
//load *.cuda-lexops
fn_ops:= GetAppLexerOpsFilename(an.LexerName);
if FileExistsUTF8(fn_ops) then
DoLoadLexerStylesFromFile_JsonLexerOps(an, fn_ops, UiOps.LexerThemes);
end;
ListFiles.Destroy;
//
//correct sublexer links
for i:= 0 to AppManager.LexerCount-1 do
begin
an:= AppManager.Lexers[i];
fn:= GetAppLexerMapFilename(an.LexerName);
if FileExists(fn) then
begin
ini:= TIniFile.Create(fn);
try
for j:= 0 to an.SubAnalyzers.Count-1 do
begin
LexName:= ini.ReadString('ref', IntToStr(j), '');
if LexName<>'' then
an.SubAnalyzers[j].SyntAnalyzer:= AppManager.FindLexerByName(LexName);
end;
finally
FreeAndNil(ini);
end;
end;
end;
//an:=AppManager.Lexers[idx];
Adapter:= TATAdapterEControl.Create(Self);
//Adapter.Lexer:=AppManager.Lexers[idx];
Adapter.Lexer:=AppManager.FindLexerByName('R');
Adapter.AddEditor(ed);
end;
procedure TForm1.ListBox1Click(Sender: TObject);
var
ext:string;
begin
ext:=ExtractFileExt(self.codefiles[listbox1.ItemIndex]);
codeFilesL[Icurrent].Text:=ed.Text;
Icurrent:=listbox1.ItemIndex;
ed.Text:=codeFilesL[Icurrent].Text;
//
if ext='.R' then
Adapter.Lexer:=AppManager.FindLexerByName('R');
if ext='.py' then
Adapter.Lexer:=AppManager.FindLexerByName('Python');
//
ed.SetFocus;
ed.update(true,true);
end;
procedure TForm1.MenuItem2Click(Sender: TObject);
begin
if opendialog1.Execute then
begin
if codefiles=nil then
codefiles:=Tstringlist.Create;
codefiles.Add(opendialog1.FileName);
listbox1.Items.Add(ExtractFileName(opendialog1.FileName));
//
setlength(codefilesL,length(codefilesL)+1);
codefilesL[length(codefilesL)-1]:=tstringlist.Create;
codefilesL[length(codefilesL)-1].LoadFromFile(opendialog1.FileName);
Icurrent:=codefiles.Count-1;
ed.Text:=codeFilesL[Icurrent].Text;
listbox1.ItemIndex:=Icurrent;
end;
end;
function TForm1.getIndexOfCurrentLine: integer;
begin
result:=ed.Carets[0].PosY;
end;
function TForm1.getIndexOfCursorX: integer;
begin
result:=ed.Carets[0].PosX+1;
end;
end.
The program can be downloaded from below link:
https://drive.google.com/open?id=1rX-Y7 ... fpn6lRk9T4
Thanks,
Rune
https://drive.google.com/open?id=1rX-Y7 ... fpn6lRk9T4
Thanks,
Rune
I see that after MenuItem click file is not colored, you activate lexer wrong.
In MenuItem click you must do this:
also in ListboxClick detect lexer this way:
In MenuItem click you must do this:
Code: Select all
ed.AdapterForHilite:= nil;
ed.Text:=codeFilesL[Icurrent].Text;
Adapter.Lexer:= AppManager.FindLexerByFilename(opendialog1.FileName, nil);
ed.AdapterForHilite:= Adapter;
ed.Update; //not sure it's needed
Code: Select all
Adapter.Lexer:=AppManager.FindLexerByFileName(...);
//if not colored, call also: ed.Update and/or ed.DoEventChange
Thanks a lot for your comments. I followed your suggestions and changed the two functions to the below code. However, I still get the procedure TFPSList.CheckIndex(AIndex : Integer);" triggered after a few clicks if I have one file above 3000 lines.
Code: Select all
procedure TForm1.ListBox1Click(Sender: TObject);
var
ext:string;
begin
ext:=ExtractFileExt(self.codefiles[listbox1.ItemIndex]);
codeFilesL[Icurrent].Text:=ed.Text;
Icurrent:=listbox1.ItemIndex;
ed.Text:=codeFilesL[Icurrent].Text;
//
Adapter.Lexer:=AppManager.FindLexerByFileName(self.codefiles[listbox1.ItemIndex],nil);
//
ed.SetFocus;
ed.update(true,true);
end;
procedure TForm1.MenuItem2Click(Sender: TObject);
begin
if opendialog1.Execute then
begin
if codefiles=nil then
codefiles:=Tstringlist.Create;
codefiles.Add(opendialog1.FileName);
listbox1.Items.Add(ExtractFileName(opendialog1.FileName));
//
setlength(codefilesL,length(codefilesL)+1);
codefilesL[length(codefilesL)-1]:=tstringlist.Create;
codefilesL[length(codefilesL)-1].LoadFromFile(opendialog1.FileName);
Icurrent:=codefiles.Count-1;
ed.AdapterForHilite:= nil;
ed.Text:=codeFilesL[Icurrent].Text;
Adapter.Lexer:= AppManager.FindLexerByFilename(opendialog1.FileName, nil);
ed.AdapterForHilite:= Adapter;
ed.Update; //not sure it's needed
listbox1.ItemIndex:=Icurrent;
end;
end;
I use linux mint 19, Lazarus 2.1.0 and FPC 3.04. If you do not have the error then it must be related to FPC on linux mint.
I just click once in the listbox and then use arrow keys to go up and down and the error occurs relatively fast (within a few seconds). You can see the video below:
https://drive.google.com/file/d/1KCVXy_ ... tt9hi/view
I just click once in the listbox and then use arrow keys to go up and down and the error occurs relatively fast (within a few seconds). You can see the video below:
https://drive.google.com/file/d/1KCVXy_ ... tt9hi/view
I dont see ListError but see another error (broken lexer hiliting after clicking in listbox). the reason is Timer which is used in EControl adapter: adapter starts timer, timer then hilites text, and we have changed text when timer ticks. To solve this: don't load all N files into 1 ATSynedit, load N files into N ATSynedits, and change edits Visible on clicking listbox items.