Модераторы: Vitalik

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [ENG] SynEdit2.0.3stable + CodeFolding(MyStix0.31), For english users 
:(
    Опции темы
DavidCl0nel
Дата 31.7.2006, 11:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 44
Регистрация: 31.7.2006
Где: Berlin/Germany

Репутация: 1
Всего: 1



Hello,

first of all, please speak english with me, i cant speak any word russian.

i've found this little summary SynMix (http://sepa.spb.ru/d.php?syn/SynMix.rar) because i fail with compile of the mystix-source code.
Your code works, but with a little changes, because i use an old Delphi version (5).

In "TSynEditCodeFoldingPlugin.AfterPaint", "TSynEditCodeFoldingPlugin.LinesDeleted" and "TSynEditCodeFoldingPlugin.LinesInserted" you call inherited. These methods are override of the upper class TSynEditPlugin. In this class these 3 methods are virtual; abstract. - What should the compiler do? It crashs hard... I comment it out of the code and it works good. You apparently dont have this problems with a newer delphi version.

Second Change is in "TCustomSynEdit.ReScanForFoldRanges". I changed it to:
Цитата

//  TList.Assign exists only on Delphi6 and later, WorkAround with Delphi6-Sources <-->
//    TemporaryAllFoldRanges.Ranges.Assign(fAllFoldRanges.Ranges);
    TemporaryAllFoldRanges.Ranges.Clear;
    TemporaryAllFoldRanges.Ranges.Capacity := fAllFoldRanges.Ranges.Capacity;
    for i := 0 to fAllFoldRanges.Ranges.Count-1 do
      TemporaryAllFoldRanges.Ranges.Add(fAllFoldRanges.Ranges[i]);



Now i can compile it with Delphi 5 and it works.... but it crashs. In my little test program I set in the main.formcreate:
Цитата
  SynMemo1.CodeFolding.Enabled := True;
  SynMemo1.CodeFolding.FolderBarColor := clBtnFace;
  SynMemo1.CodeFolding.HighlighterFoldRegions := False;
  SynMemo1.CodeFolding.CollapsedCodeHint := True;
//...
  SynMemo1.CodeFolding.FoldRegions.Add(rtKeyWord, False, False, True, 'If', 'EndIf');
//... more folds
  SynMemo1.InitCodeFolding;


In the SynMemo.OnChange-Method i call "ReScanForFoldRanges". If I start my test program and edit the text (i.e. change a endif to other things, that he dont fold this code), it works good.

But if I fold a block (only then!) and add lines after it and delete it, the lines and [+] are painted wrong and later it crashs with an Access Violation in "TSynEditFoldRanges.GetCount".
What I do wrong or do you have the same problems?

Help me. smile 

PS: I have also changed "CanExecuteInLine". There were some errors too, if you backspace a Line to a folded block above and such things.
And another thing, that I can copy folded blocks (that he dont copy only the first line).. But if I paste it, it crashs also, because he called OnChange->RescanforFoldRanges.... 

Это сообщение отредактировал(а) DavidCl0nel - 31.7.2006, 11:23
PM MAIL   Вверх
Sep.
Дата 31.7.2006, 23:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 109
Регистрация: 22.7.2004

Репутация: нет
Всего: 6



Цитата

What I do wrong or do you have the same problems?

Yes, we have same problems and work on them. There are sometimes drop of all foldranges when you have some line collapsed and delete text somwhere. But it depends on highlughter you are using. Now i can't say more =(
Copying & deleting of collapsed lines can be done. It needs to write codefolded version of TCustomSynEdit.GetSelText so undo/redo will work with deleting collapsed lines. I've write it but take many strange bugs in other parts of code. If anyone can properly implement it, please post it here. 
--------------------
Syn - TotalCommander lister plugin |  SynTree - coders sourcebook  
PM MAIL   Вверх
DavidCl0nel
Дата 1.8.2006, 10:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 44
Регистрация: 31.7.2006
Где: Berlin/Germany

Репутация: 1
Всего: 1



After further investigation I found the problem for the crash.

In "ReScanForFoldRanges"
Цитата
// And finally we have to free memory and repaint the control
//fAllFoldRanges.Free;
fAllFoldRanges := TemporaryAllFoldRanges;


This free (I commented it) called the destructor (see below) and destroys in his loop TemporaryAllFoldRanges.
Цитата
destructor TSynEditAllFoldRanges.Destroy;
var i: Integer;                                                //###mod memory leak
begin
  if not Assigned(fAllRanges) then Exit;                       //###mod memory leak
  for i := 0 to fAllRanges.Count - 1 do TObject(fAllRanges[i]).Free();//###mod memory leak
  FreeAndNil(fAllRanges);                                      //###mod memory leak
    inherited;
    //fAllRanges.Free;                                           //###mod memory leak
end;


In the part above "Now we need to combine collapsed items with new one's" you add (AddFold) the FoldRanges to Temp. AddFold does TList.Add and this TList work with the Pointer, so you dont copy the fold, you only put a pointer to it. And later you free the items and the pointer points to somewhere. These Informations you copy from Temp to fAllFoldRanges. In my debug session all was right, only one FromLine-Attribute was set to a very high line number, that doesnt exists.
I have commented the free now, and it works.




Another bug occur, if you edit, and all folds are collapsed. Then you get an EListError. In "TCustomSynEdit.UpdateFoldRangeParents" I changed the loop to:
Цитата
          with fAllFoldRanges do
           if Ranges.Count > 0 then
            repeat
              if FoldRanges[j].FromLine > CollapsedFromLine then
               begin
                Ranges.Insert(j, fAllFoldRanges[i]);
                  Break;
               end;
  
                Inc(j);
             until j >= Count - 1 //<--> ">=" instead of "="
            else
             Ranges.Add(fAllFoldRanges[i]);






Another change (i sayed it in last post), that I changed the function, that controls, what key you are allowed to press at/near collapsed folds, that you dont destroy the lines. In your version you can Backspace a line to a collapsed block above and the line is add to the collapsed-headerline. If you uncollapse the block the added line is in your folded block.... Some more cases I've catched, but maybe I miss something. Try it. I changed "TCustomSynEdit.CanExecuteInLine" to
Цитата
         if (aKey = VK_RETURN) and (CaretX = 1) then
           Result := True
         else if (aKey = VK_RETURN) and (CaretX >= Length(TrimRight(Lines[CaretY - 1])) + 1) then begin     //###mod caret beyond EOL
           Result := True;
           CaretY := CaretY + 1;
           CaretX := 1;
         end else if (aKey = VK_RETURN) and (not FoldRangeForLine(CaretY).Collapsed) then
           Result := True
         else if (aKey = VK_BACK) and (CaretX = 1) and ((FoldRangeForLine(CaretY-1) = nil) or (not FoldRangeForLine(CaretY-1).Collapsed)) then
           Result := True
         else if (aKey = VK_DELETE) and (CaretX >= Length(TrimRight(Lines[CaretY-1])) + 1) and (FoldRangeForLine(CaretY+1) = nil) then begin
           Result := True;
           CaretX := Length(Lines[CaretY-1])+1;
         end else
           if ((FoldRangeForLine(CaretY) = nil) or (not FoldRangeForLine(CaretY).Collapsed)) then
             Result := true
           else
             //Allow only special keys (Cursor-Down, ..)
             Result := (aKey in [VK_SHIFT, VK_CONTROL, VK_MENU {Alt}, VK_ESCAPE, VK_F1..VK_F12, VK_PRIOR, VK_NEXT, VK_END, VK_HOME, VK_LEFT, VK_UP, VK_RIGHT, VK_DOWN, VK_SELECT, VK_PRINT, VK_EXECUTE, VK_SNAPSHOT, VK_INSERT]);





I changed GetSelText to, that he copy all lines.
Цитата
        case fActiveSelectionMode of
          smNormal:
            if (First = Last) then
              Result := Copy(Lines[First], ColFrom, ColTo - ColFrom)
            else begin
              // <-->
              // step1: calculate total length of result string
              iLineCount := 0;
              //first line
              Inc(TotalLen, Length(TrimRight(GetUncollapsedStrings[GetRealLineNumber(First)])));
              Inc(iLineCount);
              //middle lines
              for i := GetRealLineNumber(First)+1 to GetRealLineNumber(Last+1)-2 do begin
                Inc(TotalLen, Length(TrimRight(GetUncollapsedStrings[i])));
                Inc(iLineCount);
              end;
              //last line
              Inc(TotalLen, ColTo - 1);
              Inc(TotalLen, Length(sLineBreak) * iLineCount);

              // step2: build up result string
              SetLength(Result, TotalLen);
              P := PChar(Result);
              //first line
              CopyAndForward(TrimRight(GetUncollapsedStrings[GetRealLineNumber(First)]), ColFrom, MaxInt, P);
              CopyAndForward(sLineBreak, 1, MaxInt, P);
              //middle lines
              for i := GetRealLineNumber(First)+1 to GetRealLineNumber(Last+1)-2 do begin
                CopyAndForward(TrimRight(GetUncollapsedStrings[i]), 1, MaxInt, P);
                CopyAndForward(sLineBreak, 1, MaxInt, P);
              end;
              //last line
              CopyAndForward(TrimRight(GetUncollapsedStrings[GetRealLineNumber(Last+1)-1]), 1, ColTo-1, P);
            end;
          smColumn:
//unchanged, here i must think of something
          smLine:
            begin
              // <-->
              // If block selection includes LastLine,
              // line break code(s) of the last line will not be added.
              // step1: calculate total length of result string
              for i := GetRealLineNumber(First) to GetRealLineNumber(Last+2)-2 do begin
                Inc(TotalLen, Length(TrimRight(GetUncollapsedStrings[i])) + Length(sLineBreak));
              end;
              if Last = Lines.Count then Dec(TotalLen, Length(sLineBreak));
                
              // step2: build up result string
              SetLength(Result, TotalLen);
              P := PChar(Result);
              for i := GetRealLineNumber(First) to GetRealLineNumber(Last+2)-2 do begin
                CopyAndForward(TrimRight(GetUncollapsedStrings[i]), 1, MaxInt, P);
                CopyAndForward(sLineBreak, 1, MaxInt, P);
              end;
            end;





Please cross-check my changes, that I dont do any evil things. More eyes see more errors. ;)

Now it works stable with my tests, but one time I get a weird error while editing (he destroys the folds again), but i cant see it again.







Edit:
Another little change: Uncollapsing all folds, before you disable CodeFolding.
Цитата
  procedure TCustomSynEdit.CodeFoldingOnChange(Event: TSynCodeFoldingChanges);
  begin
    if Event = fcEnabled then
    begin
    if CodeFolding.Enabled then
      Gutter.RightOffset := 21
     else begin
       UncollapseAll;  // UncollapseAll before disable (and lose) folded Blocks
      Gutter.RightOffset := 2;
     end;
    end
    else if Event = fcRescan then
     InitCodeFolding;
    
    Invalidate;
  end;


Question: For what using is "procedure TCustomSynEdit.UpdateBmps", it isnt used yet?

Это сообщение отредактировал(а) DavidCl0nel - 1.8.2006, 14:31
PM MAIL   Вверх
Sep.
Дата 2.8.2006, 10:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 109
Регистрация: 22.7.2004

Репутация: нет
Всего: 6



Great work man!
But why do you use 
Код

           Result := True;
           CaretY := CaretY + 1;
           CaretX := 1;

Isn't it automatically moves caret to next line by ENTER?
I make all changes you post here but still have some bugs:
1. i have collapsed line 
begin [...] end
i place cursor to start of line below it and press BkSpace = drop all foldranges
2. i have collapsed line
i try to paste a block of text above it, and again take drop of foldranges
3. collapsed line in selected text. Pressing Del deletes colapsed range. But pressing Ctrl-Z = drop again
Do you have same bugs? May be we have some changes in other parts of code, because i have some edits after last upload of SynMix. Can you mail me your SynEdit.pas? (sepich()rambler.ru) I wanna look to it thru WinDiff.

Let's sinchronize our work and take this bugs down =)

--------------------
Syn - TotalCommander lister plugin |  SynTree - coders sourcebook  
PM MAIL   Вверх
DavidCl0nel
Дата 2.8.2006, 11:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 44
Регистрация: 31.7.2006
Где: Berlin/Germany

Репутация: 1
Всего: 1



I use folded blocks without ending, maybe you use it in another way. And I have a other language syntax highlighting, but i translate it to delphi code blocks:
Цитата

  for x := 0 to 5 do begin [...]
  end // <--- this i dont want and i set the options, so i have only first line of collapsed blocks (see first post with initialization of codefolding)

Maybe you use it on the other Way and get such weird things?


If you have two folded lines now without a free line between them:
Цитата

  for x := 0 to 5 do begin [...]
  for x := 0 to 5 do begin [...]

And put the cursor with Key END to the end of first line (There are two endings, if you press END more than one. One after the line, and another 5 spaces behind the [...] - why?! Can you explain it?). I have add this case, that he goes to the next line and insert the new line.
Цитата

  for x := 0 to 5 do begin [...]
.
  for x := 0 to 5 do begin [...]

. = Cursor Position

If i dont have this case, i have no opportunity to devide such folded blocks.






Tomorrow I will test your 3 cases again (today no free time for it) and send you both pas files (I have another little changed in SynEditCodeFolding.pas i think...)
PM MAIL   Вверх
Sep.
Дата 3.8.2006, 10:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 109
Регистрация: 22.7.2004

Репутация: нет
Всего: 6



Цитата

I use folded blocks without ending, maybe you use it in another way.

Yes i use endings. There are mod named "//###mod pos of [...] to left" which makes from
begin end [...]
to
begin [...] end
This 5 spaces are needed to provide space for [...] sign. 
Цитата

If you have two folded lines now without a free line between them:

i have this working normal without manually move caret =) 

--------------------
Syn - TotalCommander lister plugin |  SynTree - coders sourcebook  
PM MAIL   Вверх
DavidCl0nel
Дата 3.8.2006, 10:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 44
Регистрация: 31.7.2006
Где: Berlin/Germany

Репутация: 1
Всего: 1



Ok, I have tested your 3 cases and I have the same errors. Number1 I solved yet and now I check the complete behaviour of CanExecuteInLine with SelText. For pasting I have no idea where i should search at the moment.

I have send a email with both pas files to you.

Edit: If I don't move Cursor, it destroys the fold, if I press return at the end of Line1 of 2 collapsed lines.

Это сообщение отредактировал(а) DavidCl0nel - 3.8.2006, 10:39
PM MAIL   Вверх
DavidCl0nel
Дата 3.8.2006, 15:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 44
Регистрация: 31.7.2006
Где: Berlin/Germany

Репутация: 1
Всего: 1



Changes in "TCustomSynEdit.CanExecuteInLine" for Selecting Text:
Цитата
    // if there is a collapsed fold range in current line then deny executing
     if (FoldRange1 <> nil) and (not FoldRange1.ParentCollapsed) then begin
       if SelAvail then begin // if selection is available
         // <-->
         if (aKey in [VK_SHIFT, VK_CONTROL, VK_MENU {Alt}, VK_ESCAPE, VK_F1..VK_F12, VK_PRIOR, VK_NEXT, VK_END, VK_HOME, VK_LEFT, VK_UP, VK_RIGHT, VK_DOWN, VK_SELECT, VK_PRINT, VK_EXECUTE, VK_SNAPSHOT, VK_INSERT]) then begin
           Result := True;
         end else begin
           if BlockBegin.Line = BlockEnd.Line then begin
             Result := False;
             if ((BlockBegin.Char = 1) and (BlockEnd.Char = Length(TrimRight(Lines[BlockEnd.Line - 1])) + 1))
               or ((BlockEnd.Char = 1) and (BlockBegin.Char = Length(TrimRight(Lines[BlockBegin.Line - 1])) + 1)) then begin

               fCodeFoldingPlugin.LinesDeleted(CaretY, 1);
               Result := True;
             end;

           end else 
             for i := BlockBegin.Line to BlockEnd.Line-1 do begin 
               FoldRange1 := CollapsableFoldRangeForLine(i);
               if (FoldRange1 <> nil) and (FoldRange1.Collapsed) and (not FoldRange1.ParentCollapsed) then begin
                 fCodeFoldingPlugin.LinesDeleted(FoldRange1.FromLine, FoldRange1.ToLine-FoldRange1.FromLine+1);
                 Result := True;
                 Exit;
               end;
             end; // for 
         end;
       end
       else begin // if no selection


I have changed it for case3, he delete the block now correctly, but he keep the wrong part in UndoBuffer. So, if you do undo, there are some lines missing. I don't found the real place for the problem. In my quoted part he calls "fCodeFoldingPlugin.LinesDeleted" with the correct ranges, but later (Step Step Step through the programm) he comes through "TCustomSynEdit.ExecuteCommand". This command calls SelText to get the selected Strings, to put this info into the UndoBuffer, but there he copy only the marked line count, not with the uncollapsed. But the same function is called, if I copy selected text to clipboard. For both cases he takes the BlockBegin and BlockEnd positions, but for the Delete-Case it are wrong.

Snip of "TCustomSynEdit.GetSelText":
Цитата
              for i := GetRealLineNumber(First)+1 to GetRealLineNumber(Last+1)-2 do begin
                Inc(TotalLen, Length(TrimRight(GetUncollapsedStrings[i])));
                Inc(iLineCount);
              end;

If I change the -2 to 0 then he fill the UndoBuffer correctly, but crashs, if i copy the SelText to Clipboard. I hope you can understand me. Help! I don't find the correct place to change this behavior at the moment.

For this problem I try to copy a space line, a folded block and another space line (so 3 visible lines with 3 collapsed lines in the folded block). I mark this 3 lines in NormalMode. In LineMode for Selection he destroys something with Delete this Block, but it seems to work correct with Undo. Graaarr!

The paste-problem (case-2) is also unsolved.




Edit: I have forgotten this method. I had to reimplement the Delete-Instruction (why you commented it?!):
Цитата
   procedure TSynEditCodeFoldingPlugin.LinesDeleted(FirstLine,
     Count: integer);
   var
     i: Integer;
     StartBC, EndBC: TBufferCoord;
   begin
     if Count > 0 then
     begin
      for i := fOwner.fAllFoldRanges.AllCount - 1 downto 0 do
         with fOwner.fAllFoldRanges[i] do
//           if (Collapsed) and (not ParentCollapsed) then
             if ( (Count = 1) and (FromLine = FirstLine) ) or
            ( (Count > 1) and (FromLine >= FirstLine) and (FromLine <= Pred(FirstLine + Count)) ) then
             begin
              StartBC.Line := FromLine;
               StartBC.Char := 1;
               EndBC.Line := ToLine;
//               EndBC.Line := FromLine;
               EndBC.Char := Length( fOwner.GetUncollapsedStrings[fOwner.fAllFoldRanges[i].ToLine - 1] );
//               EndBC.Char := Length( fOwner.Lines[FromLine - 1] );
              fOwner.fUndoList.AddChange(crDeleteCollapsedFold, StartBC, EndBC,
                 '', fOwner.SelectionMode{, fOwner.fAllFoldRanges[i], i});
               //<-->
               fOwner.fAllFoldRanges.Delete(i);     //###mod collapsed line edit
             end;

       fOwner.UpdateFoldRanges(FirstLine-1, -Count);
        fOwner.GutterChanged(fOwner);
     end;
//  inherited of a abstract method? - ignored <-->
//     inherited;
   end;



And another Edit: Whats with the commented fAllFoldRanges.Free (it destroys TemporaryFoldRanges) in "ReScanForFoldRanges"? Is it really necessary (then we had to think about it, how to implement it correctly that it don't destroy Temp) or is it ok so now? I don't test it with a profiler yet, that I can see the memleaks.

Это сообщение отредактировал(а) DavidCl0nel - 3.8.2006, 16:12
PM MAIL   Вверх
Sep.
Дата 4.8.2006, 19:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 109
Регистрация: 22.7.2004

Репутация: нет
Всего: 6



Hi!
Sorry for late answer, i was left city for a day. 
I add all your changes to SynMix. Your problem with move cursor in 2 collapsed lines is fixed. It will be good if you download new pack and make all patches from it. So we will speak about same things. I also fixed wrong indent of all text (from 2 to 4 spaces) There was also some memory leaks fixed by Vitalik, after last upload SynMix. This changes are also here.

So what bugs we have now:
1. deleting and editing near collapsed line all works ok, but here is drop of foldranges when place cursor on line after it and press BkSpace
2. paste of block text above collapsed line
3. copy collapsed line and paste it somewhere = drop
4. delete collapsed line in selection and press Ctrl-Z
5. if collapsed line was selected in normal mode - there no copy contents to buffer. if select it in line mode - all ok (but bug when paste it)
6. pressing Del key on line above collapsed. This line must be non empty. Collapsed text destroys.

Цитата(DavidCl0nel @  3.8.2006,  15:57 Найти цитируемый пост)
I have changed it for case3, he delete the block now correctly, but he keep the wrong part in UndoBuffer. So, if you do undo, there are some lines missing.

i have such: undo buffer is store right text, but drop of foldranges
Цитата(DavidCl0nel @  3.8.2006,  15:57 Найти цитируемый пост)
I had to reimplement the Delete-Instruction (why you commented it?!):

it was bug with pressing Del on empty line above collapsed. Now it fixed my method slightly differ from standart.
Цитата(DavidCl0nel @  3.8.2006,  15:57 Найти цитируемый пост)
 I don't test it with a profiler yet, that I can see the memleaks.

How do you test memleaks? Do you use FastMM4?

PS I not very professional programmer. Those codefolding implementation is very dislike me and this almost at top of my programming level. So my methods may be not wonderfull. Feel free to change them and post here. Also this forum has [ code] tag, try to use it instead of [ quote], so code will look more like in SynEdit =)
--------------------
Syn - TotalCommander lister plugin |  SynTree - coders sourcebook  
PM MAIL   Вверх
DavidCl0nel
Дата 4.8.2006, 23:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 44
Регистрация: 31.7.2006
Где: Berlin/Germany

Репутация: 1
Всего: 1



I look at your merged code on Monday. 1. and 6. sounds like to fix it in the CanExecute-Method.

For pasting i dont have a idea, where i start to search for the bug. 

I dont look for memleaks at the moment, if you (or Vitalik) check it, its ok. ;) But if so, then i use FastMM, yes. But not at the moment with my little testbench.

The codefolding code is a good start, but all this little things, that destroy the folds, seeming not checked at the moment. I cant compile the mystix cause some missing other controls, but if i test it with a compiled binary, it has the same hazardous behaviour - so we must go on to fix it. ;)
PM MAIL   Вверх
DavidCl0nel
Дата 8.8.2006, 14:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 44
Регистрация: 31.7.2006
Где: Berlin/Germany

Репутация: 1
Всего: 1



I show you my last changes

Problem 1 with pasting above collapsed blocks:
Код
TCustomSynEdit.KeyDown
...
begin
  //### Code Folding ###                                   //###mod collapsed line edit
  if (not (ssCtrl in Shift))                               //###mod collapsed line edit
  and (not CanExecuteInLine(CaretY, Key)) then
    Exit
  //<--> FoldRanges Update in LinesInserted
  ;{else if (Key = VK_RETURN) then
    UpdateFoldRanges(CaretY, 1);}


It is done here (there it was in comments):
Код
procedure TSynEditCodeFoldingPlugin.LinesInserted(FirstLine,
  Count: integer);
begin
  //<--> Update all Foldranges, if Lines inserted
  fOwner.UpdateFoldRanges(FirstLine-1, Count); 
  //inherited; //###mod delphi5
end;



Problem 2 with Undo and Redo after Delete a Block... It wasnt implemented! The type has a new element "crDeleteCollapsedFold", but it isnt used in both functions. I implement it and add a case else with an message box. Maybe there are on some cases also missed instructions.
Код
TCustomSynEdit.UndoItem
...
case....
....
      //<-->
      //### Code Folding ###
      crDeleteCollapsedFold:
        begin
             SetSelTextPrimitiveEx(Item.ChangeSelMode, PChar(Item.ChangeStr),
               False );
          InternalCaretXY := Item.ChangeStartPos;
          SetCaretAndSelection(Item.ChangeStartPos, Item.ChangeStartPos,
            Item.ChangeEndPos);
          fRedoList.AddChange(Item.ChangeReason, Item.ChangeStartPos,
            Item.ChangeEndPos, '', Item.ChangeSelMode);
        end;
      //### End Code Folding ###    
      else Application.MessageBox('Unimplemented Undo Branch', 'Undo Error', ID_OK);

Код
procedure TCustomSynEdit.RedoItem;
...
case....
....
      //<-->
      //### Code Folding ###
      crDeleteCollapsedFold:
        begin
          SetCaretAndSelection(Item.ChangeStartPos, Item.ChangeStartPos,
            Item.ChangeEndPos);
          fUndoList.AddChange(Item.ChangeReason, Item.ChangeStartPos,
            Item.ChangeEndPos, SelText, Item.ChangeSelMode);
          SetSelTextPrimitiveEx( Item.ChangeSelMode, PChar(Item.ChangeStr),
            False );
          InternalCaretXY := Item.ChangeEndPos;
        end;
      //### End Code Folding ###        
      else Application.MessageBox('Unimplemented Redo Branch', 'Redo Error', ID_OK);


And the structure fUndoList had to fill correctly if you delete lines. The function is now:
Код
procedure TSynEditCodeFoldingPlugin.LinesDeleted(FirstLine,
  Count: integer);
var
  i: Integer;
  StartBC, EndBC: TBufferCoord;
begin
  if Count > 0 then
  begin
    for i := fOwner.fAllFoldRanges.AllCount - 1 downto 0 do
      with fOwner.fAllFoldRanges[i] do
        if (Collapsed) and (not ParentCollapsed) then
{          if ( (Count = 1)and(
          (fOwner.BlockEnd.Char>3)or((fOwner.BlockEnd.Line<>FirstLine)and(fOwner.BlockBegin.Line<>fOwner.BlockEnd.Line)) //###mod collapsed line edit
          ) and (FromLine = FirstLine) ) or
          ( (Count > 1) and (FromLine >= FirstLine) and (FromLine <= Pred(FirstLine + Count)) ) then}
          if ( (Count = 1) and (FromLine = FirstLine) ) or
            ( (Count > 1) and (FromLine >= FirstLine) and (FromLine <= Pred(FirstLine + Count)) ) then
          begin
//            if fOwner.BlockBegin.Line=fOwner.BlockEnd.Line then count:=0; //###mod collapsed line edit
            //<-->
            StartBC.Line := fOwner.GetRealLineNumber(fOwner.BlockBegin.Line);
            StartBC.Char := fOwner.BlockBegin.Char;
            EndBC.Line := fOwner.GetRealLineNumber(fOwner.BlockEnd.Line);
            EndBC.Char := fOwner.BlockEnd.Char;
            fOwner.fUndoList.AddChange(crDeleteCollapsedFold, StartBC, EndBC,
              fOwner.SelText, fOwner.SelectionMode, fOwner.fAllFoldRanges[i], i);
            fOwner.fAllFoldRanges.Delete(i);
          end;

    fOwner.UpdateFoldRanges(FirstLine-1, -Count);
    fOwner.GutterChanged(fOwner);
  end;
  //inherited; //###mod delphi5
end;

There are some changes with "fOwner.BlockEnd.Char>3" and such things. What should it do there? I commented it like in my older version and change the filling of fUndoList correctly.

! At this time Delete a Block and undo it works correctly, but Redo (delete again) the block destroys the fold. There are a error in it, but i don't know where at the moment.



PM MAIL   Вверх
DavidCl0nel
Дата 8.8.2006, 14:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 44
Регистрация: 31.7.2006
Где: Berlin/Germany

Репутация: 1
Всего: 1



And the biggest change is in CanExecuteInLine... complete function:
Код
function TCustomSynEdit.CanExecuteInLine(aLine: Integer; aKey: Word): Boolean;
var
  FoldRange: TSynEditFoldRange;
  i: integer;
begin
  Result := False;

  if (CodeFolding.Enabled) or (CodeFolding.IndentGuides) then
  begin
    //<-->
    //FoldRange := CollapsableFoldRangeForLine(CaretY);

    // if there is a collapsed fold range in current line then deny executing
    // if (FoldRange <> nil) and (not FoldRange.ParentCollapsed)
    // {and (FoldRange.Collapsed)} then  //###mod CF bugs
    // begin
      // if selection is avaible
      if SelAvail then
      //###mod CF bugs
      begin // if selection is available
         // <-->
         if (aKey in [VK_SHIFT, VK_CONTROL, VK_MENU {Alt}, VK_ESCAPE, VK_F1..VK_F12, VK_PRIOR, VK_NEXT, VK_END, VK_HOME, VK_LEFT, VK_UP, VK_RIGHT, VK_DOWN, VK_SELECT, VK_PRINT, VK_EXECUTE, VK_SNAPSHOT, VK_INSERT]) then begin
           Result := True;
         end else begin
           if BlockBegin.Line = BlockEnd.Line then begin
             Result := False;
             if ((BlockBegin.Char = 1) and (BlockEnd.Char = Length(TrimRight(Lines[BlockEnd.Line - 1])) + 1))
               or ((BlockEnd.Char = 1) and (BlockBegin.Char = Length(TrimRight(Lines[BlockBegin.Line - 1])) + 1)) then begin

               fCodeFoldingPlugin.LinesDeleted(CaretY, 1);
               Result := True;
             end;

           end else
             for i := BlockBegin.Line to BlockEnd.Line-1 do begin
               FoldRange := CollapsableFoldRangeForLine(i);
               if (FoldRange <> nil) and (FoldRange.Collapsed) and (not FoldRange.ParentCollapsed) then begin
                 fCodeFoldingPlugin.LinesDeleted(FoldRange.FromLine, FoldRange.ToLine-FoldRange.FromLine+1);
                 Result := True;
                 Exit;
               end
               else begin
                 fCodeFoldingPlugin.LinesDeleted(BlockBegin.Line, BlockEnd.Line-BlockBegin.Line+1);
                 Result := True;
                 Exit;
               end;
             end; // for
         end;
       end
       //###mod CF bugs

      {begin
        FoldRange1 := CollapsableFoldRangeForLine(BlockBegin.Line);
        FoldRange2 := CollapsableFoldRangeForLine(BlockEnd.Line);
  
        // only allow when selection begins at first char and ends at last
        //char or vice versa in lines with collapsed folds
        Result := False;  //###mod CF bugs
        if (FoldRange1 <> nil) and (FoldRange1.Collapsed)
        and (not FoldRange1.ParentCollapsed) then
          if ((BlockBegin.Char = 1) and (BlockEnd.Char = Length(Lines[BlockEnd.Line - 1]) + 1))
          or ((BlockEnd.Char = 1) and (BlockBegin.Char = Length(Lines[BlockBegin.Line - 1]) + 1)) then
          begin
            if (aKey = VK_BACK) or (aKey = VK_DELETE) then
              fCodeFoldingPlugin.LinesDeleted(CaretY, 1);

            Result := True;
          end;

        if (FoldRange2 <> nil) and (FoldRange2.Collapsed)
        and(FoldRange2<>FoldRange1)    //###mod collapsed line delete
        and (not FoldRange2.ParentCollapsed) then
          if ((BlockBegin.Char = 1) and (BlockEnd.Char = Length(Lines[BlockEnd.Line - 1]) + 1))
          or ((BlockEnd.Char = 1) and (BlockBegin.Char = Length(Lines[BlockBegin.Line - 1]) + 1)) then
          begin
            if (aKey = VK_BACK) or (aKey = VK_DELETE) then
              fCodeFoldingPlugin.LinesDeleted(CaretY, 1);
  
            Result := True;
          end;
      end}
      // if no selection
      else
      begin
         //<-->
         if aKey = VK_RETURN then begin                                                                                                               //###mod colapsed line edit
           if CaretX = 1 then begin                                                                                                                   //
             Result := True;                                                                                                                          //
           end else if CaretX >= Length(TrimRight(Lines[CaretY - 1])) + 1 then begin     //###mod caret beyond EOL                                    //
             Result := True;                                                                                                                          //
             if FoldRangeForLine(CaretY) <> nil then Uncollapse(FoldRangeForLine(CaretY));     //Uncollapse this Block                                //
                                                                                                                                                      //
           end else if not FoldRangeForLine(CaretY).Collapsed then begin                                                                              //
             Result := True;                                                                                                                          //
           end;                                                                                                                                       //
                                                                                                                                                      //
         end else if (aKey = VK_BACK) and (CaretX = 1) then begin                                                                                     //
           if (FoldRangeForLine(CaretY-1) = nil) or FoldRangeForLine(CaretY-1).Collapsed then begin                                                   //
             Result := True;                                                                                                                          //
             if FoldRangeForLine(CaretY) <> nil then Uncollapse(FoldRangeForLine(CaretY));     //Uncollapse this Block                                //
             if FoldRangeForLine(CaretY-1) <> nil then begin                                                                                          //
               Uncollapse(FoldRangeForLine(CaretY-1)); //Uncollapse Block above                                                                       //
               CaretY := CaretY + FoldRangeForLine(CaretY-1).LinesCollapsed + 1; //Put Cursor to the correct line after uncollapse                    //
             end;                                                                                                                                     //
                                                                                                                                                      //
           end else                                                                                                                                   //
             Result := False;                                                                                                                         //
                                                                                                                                                      //
         end else if (aKey = VK_DELETE) and (CaretX >= Length(TrimRight(Lines[CaretY-1])) + 1) then begin                                             //
           if (FoldRangeForLine(CaretY+1) = nil) or FoldRangeForLine(CaretY+1).Collapsed then begin                                                   //
             Result := True;                                                                                                                          //
             if FoldRangeForLine(CaretY+1) <> nil then Uncollapse(FoldRangeForLine(CaretY+1)); //Uncollapse Block below                               //
             if FoldRangeForLine(CaretY) <> nil then begin                                                                                            //
               Uncollapse(FoldRangeForLine(CaretY));     //Uncollapse this Block                                                                      //
               CaretY := CaretY + FoldRangeForLine(CaretY).LinesCollapsed + 1; //Put Cursor to the correct line after uncollapse                      //
             end;                                                                                                                                     //
           end else                                                                                                                                   //
             Result := False;                                                                                                                         //
                                                                                                                                                      //
         //Allow only special keys (Cursor-Down, ..)                                                                                                  //
         end else if (aKey in [VK_SHIFT, VK_CONTROL, VK_MENU {Alt}, VK_ESCAPE, VK_F1..VK_F12, VK_PRIOR, VK_NEXT, VK_END, VK_HOME, VK_LEFT, VK_UP,     //
                               VK_RIGHT, VK_DOWN, VK_SELECT, VK_PRINT, VK_EXECUTE, VK_SNAPSHOT, VK_INSERT]) then begin                                //
           Result := True;                                                                                                                            //
                                                                                                                                                      //
         //Allow in non collapsed (or non folded lines) all keys                                                                                      //
         end else if ((FoldRangeForLine(CaretY) = nil) or (not FoldRangeForLine(CaretY).Collapsed)) then begin                                        //
           Result := True;                                                                                                                            //
         end else                                                                                                                                     //
           Result := False;                                                                                                                           //###mod colapsed line edit
      end;
    //end;
  end;
end;

It works a little bit different now. In older version it didnt look at folded lines and allow editing. Now it deny all changes, except the cases that are allowed in the code. Maybe there are some problems even at the moment. A known error is, if you add lines near a collapsed block. Sometimes he change the position of the foldstart wrong. 

Another error, that I didn't can re-adjust always, is, that it destroys the fold, if select something in normal select mode and then switch to line select mode.




So my new error list is:
  1. Return near collapsed line may destroy fold
  2. Redo after Undo ater delete collapsed Line
  3. Sometimes it drops folding if select something in normal mode and then switch to line select mode 


Maybe you find other errors (I dont hope smile it should be sometime all correctly ).

I send the file by email, maybe i miss to say a change here.


PS: I had to split the post in 2 parts, because it was to big for one. Be sure, to see both. ;)

Это сообщение отредактировал(а) DavidCl0nel - 8.8.2006, 14:45
PM MAIL   Вверх
Sep.
Дата 9.8.2006, 10:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 109
Регистрация: 22.7.2004

Репутация: нет
Всего: 6



Finally forum start work for me!
Here is some fixed part of CanExecuteInLine, that i sent to you yesterday:
Код

      else
      begin
      //###mod colapsed line edit
         tmp:=FoldRangeForLine(CaretY);
         tmp2:=FoldRangeForLine(CaretY-1);
         if aKey = VK_RETURN then begin
           if CaretX = 1 then begin
             Result := True;
           end else if CaretX >= Length(TrimRight(Lines[CaretY - 1])) + 1 then begin     //###mod caret beyond EOL
                 Result := True;
             if (tmp <> nil)and(tmp.Collapsed)and(not tmp.ParentCollapsed) then Uncollapse(tmp); //Uncollapse this Block

           end else if not tmp.Collapsed then begin
             Result := True;
           end;

         end else if (aKey = VK_BACK)and(CaretX = 1) then begin
           if (tmp2=nil)or(tmp2.Collapsed) then begin
             Result := True;
             if (tmp<>nil)and(tmp.Collapsed)and(not tmp.ParentCollapsed) then Uncollapse(tmp);//Uncollapse this Block
             if (tmp2<>nil)and(tmp2.Collapsed)and(not tmp2.ParentCollapsed) then begin
               Uncollapse(tmp2); //Uncollapse Block above
               CaretY := CaretY + tmp2.LinesCollapsed + 1; //Put Cursor to the correct line after uncollapse
             end;                                                                                                                                   

           end else if (tmp2<>nil)and(not tmp2.Collapsed)and(not tmp2.ParentCollapsed) then begin
             Result := true;
           end else
             Result := false;

         end else if (aKey = VK_DELETE) and (CaretX >= Length(TrimRight(Lines[CaretY-1])) + 1) then begin
           if (FoldRangeForLine(CaretY+1) = nil) or FoldRangeForLine(CaretY+1).Collapsed then begin
             Result := True;
             tmp2:=FoldRangeForLine(CaretY+1);
             if (tmp2<>nil)and(tmp2.Collapsed)and(not tmp2.ParentCollapsed) then Uncollapse(tmp2); //Uncollapse Block below
             if (tmp<>nil)and(tmp.Collapsed)and(not tmp.ParentCollapsed) then begin
               Uncollapse(tmp);     //Uncollapse this Block
               CaretY := CaretY + tmp.LinesCollapsed + 1; //Put Cursor to the correct line after uncollapse
             end;                                                                                                                                   
           end else
             Result := False;                                                                                                                       
                                                                                                                                                    
         //Allow only special keys (Cursor-Down, ..)
         end else if (aKey in [VK_SHIFT, VK_CONTROL, VK_MENU {Alt}, VK_ESCAPE, VK_F1..VK_F12, VK_PRIOR, VK_NEXT, VK_END, VK_HOME, VK_LEFT, VK_UP,   
                               VK_RIGHT, VK_DOWN, VK_SELECT, VK_PRINT, VK_EXECUTE, VK_SNAPSHOT, VK_INSERT]) then begin                              
           Result := True;                                                                                                                          

         //Allow in non collapsed (or non folded lines) all keys                                                                                    
         end else if ((tmp = nil)or(not tmp.Collapsed)) then begin
           Result := True;                                                                                                                          
         end else
           Result := False;
    //###mod colapsed line edit
    end;

There was some bugs when using collapsed line endings, and try to press enter, del, bkSpace at start/end of non collapsed lines.
--------------------
Syn - TotalCommander lister plugin |  SynTree - coders sourcebook  
PM MAIL   Вверх
DavidCl0nel
Дата 9.8.2006, 12:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 44
Регистрация: 31.7.2006
Где: Berlin/Germany

Репутация: 1
Всего: 1



And again some changes..

Complete CanExecute is now. It based on yours, but i renamed your tmp-vars:
Код
function TCustomSynEdit.CanExecuteInLine(aLine: Integer; aKey: Word): Boolean;
var
  FoldRange1, FoldRange2: TSynEditFoldRange;
  i: integer;
begin
  if CodeFolding.Enabled or CodeFolding.IndentGuides then
  begin
    Result := False; // deny all except following cases
    // if selection is avaible
    if SelAvail then
    //###mod CF bugs
    begin // if selection is available
      // <-->
      if (aKey in [VK_SHIFT, VK_CONTROL, VK_MENU {Alt}, VK_ESCAPE, VK_F1..VK_F12, VK_PRIOR, VK_NEXT, VK_END, VK_HOME, VK_LEFT, VK_UP, VK_RIGHT, VK_DOWN, VK_SELECT, VK_PRINT, VK_EXECUTE, VK_SNAPSHOT, VK_INSERT]) then begin
        Result := True;
      end else begin
        if BlockBegin.Line = BlockEnd.Line then begin
          Result := True;
          if ((BlockBegin.Char = 1) and (BlockEnd.Char = Length(TrimRight(Lines[BlockEnd.Line - 1])) + 1))
            or ((BlockEnd.Char = 1) and (BlockBegin.Char = Length(TrimRight(Lines[BlockBegin.Line - 1])) + 1)) then begin

            fCodeFoldingPlugin.LinesDeleted(CaretY, 1);
          end;

        end else
          for i := BlockBegin.Line to BlockEnd.Line-1 do begin
            fCodeFoldingPlugin.LinesDeleted(BlockBegin.Line, BlockEnd.Line-BlockBegin.Line+1);
            Result := True;
            Exit;
          end; // for
      end; // if aKey-else
    end // if SelAvail
     //###mod CF bugs

    // if no selection
    else begin
      //<-->
      //###mod colapsed line edit
      FoldRange1 := FoldRangeForLine(CaretY);
      FoldRange2 := FoldRangeForLine(CaretY-1);
      if aKey = VK_RETURN then begin
        if CaretX = 1 then begin
          Result := True;
          if FoldRange2 <> nil then CaretY := CaretY + 1;
        end else if CaretX >= Length(TrimRight(Lines[CaretY - 1])) + 1 then begin     //###mod caret beyond EOL
          Result := True;
          if (FoldRange1 <> nil) and FoldRange1.Collapsed and not FoldRange1.ParentCollapsed then Uncollapse(FoldRange1); //Uncollapse this Block

        end else if not FoldRange1.Collapsed then begin
          Result := True;
        end;

      end else if (aKey = VK_BACK) and (CaretX = 1) then begin
        if (FoldRange2 = nil) or FoldRange2.Collapsed then begin
          Result := True;
          if (FoldRange1 <> nil) and FoldRange1.Collapsed and not FoldRange1.ParentCollapsed then Uncollapse(FoldRange1);//Uncollapse this Block
          if (FoldRange2 <> nil) and FoldRange2.Collapsed and not FoldRange2.ParentCollapsed then begin
            Uncollapse(FoldRange2); //Uncollapse Block above
            CaretY := CaretY + FoldRange2.LinesCollapsed + 1; //Put Cursor to the correct line after uncollapse
          end;

        end else if (FoldRange2 <> nil) and not FoldRange2.Collapsed and not FoldRange2.ParentCollapsed then begin
          Result := True;
        end else
          Result := False;

      end else if (aKey = VK_DELETE) and (CaretX >= Length(TrimRight(Lines[CaretY-1])) + 1) then begin
        FoldRange2 := FoldRangeForLine(CaretY+1);
        if (FoldRange2 = nil) or FoldRange2.Collapsed then begin
          Result := True;
          if (FoldRange2 <> nil) and FoldRange2.Collapsed and not FoldRange2.ParentCollapsed then begin
            Uncollapse(FoldRange2); //Uncollapse Block below
          end;
          if (FoldRange1 <> nil) and FoldRange1.Collapsed and not FoldRange1.ParentCollapsed then begin
            Uncollapse(FoldRange1); //Uncollapse this Block
            CaretY := CaretY + FoldRange1.LinesCollapsed + 1; //Put Cursor to the correct line after uncollapse
          end;
    
        end else
          Result := False;

      //Allow only special keys (Cursor-Down, ..)
      end else if (aKey in [VK_SHIFT, VK_CONTROL, VK_MENU {Alt}, VK_ESCAPE, VK_F1..VK_F12, VK_PRIOR, VK_NEXT, VK_END, VK_HOME, VK_LEFT, VK_UP,
                            VK_RIGHT, VK_DOWN, VK_SELECT, VK_PRINT, VK_EXECUTE, VK_SNAPSHOT, VK_INSERT]) then begin
        Result := True;


      //Allow in non collapsed (or non folded lines) all keys
      end else if ((FoldRange1 = nil) or (not FoldRange1.Collapsed)) then begin
        Result := True;

      end else
        Result := False;
       //###mod colapsed line edit
    end; //else
  end //if CodeFolding.Enabled
  else Result := True;
end;

It now modificate your case, if you press return on collapsed line. It set the cursor (quick and dirty) to another line and it works now. All other cases should be also ok.

LinesDeleted had to fill correctly the UndoBuffer and is now:
Код
procedure TSynEditCodeFoldingPlugin.LinesDeleted(FirstLine,
  Count: integer);
var
  i: Integer;
  StartBC, EndBC: TBufferCoord;
  Updated: Boolean;
begin
  Updated := False;
  if Count > 0 then
  begin
    for i := fOwner.fAllFoldRanges.AllCount - 1 downto 0 do
      if ( (Count = 1) and (fOwner.fAllFoldRanges[i].FromLine = FirstLine-1) ) or
         ( (Count > 1) and (fOwner.fAllFoldRanges[i].FromLine >= FirstLine) and (fOwner.fAllFoldRanges[i].FromLine < Pred(FirstLine+Count))) then
      begin
        //<-->
        StartBC.Line := fOwner.GetRealLineNumber(fOwner.BlockBegin.Line);
        StartBC.Char := fOwner.BlockBegin.Char;
        EndBC.Line := fOwner.GetRealLineNumber(fOwner.BlockEnd.Line);
        EndBC.Char := fOwner.BlockEnd.Char;
        fOwner.fUndoList.AddChange(crDeleteCollapsedFold, StartBC, EndBC,
          fOwner.SelText, fOwner.SelectionMode, fOwner.fAllFoldRanges[i], i);
        fOwner.fAllFoldRanges.Delete(i);
        Updated := True;
        fOwner.SetSelTextPrimitive('');
      end;

    if not Updated then fOwner.UpdateFoldRanges(FirstLine-1, fOwner.BlockBegin.Line - fOwner.BlockEnd.Line);
    fOwner.GutterChanged(fOwner);
  end;
  //inherited; //###mod delphi5
end;


LinesInserted isnt changed i think:
Код
procedure TSynEditCodeFoldingPlugin.LinesInserted(FirstLine,
  Count: integer);
begin
  //<--> Update all Foldranges, if Lines inserted
  fOwner.UpdateFoldRanges(FirstLine-1, Count); 
  //inherited; //###mod delphi5
end;



Redo is now:
Код
procedure TCustomSynEdit.RedoItem;
...
      //### Code Folding ###
      crDeleteCollapsedFold:
        begin
          InternalCaretXY := Item.ChangeEndPos;
          fUndoList.AddChange(Item.ChangeReason, Item.ChangeStartPos,
            Item.ChangeEndPos, SelText, Item.ChangeSelMode, Item.ChangeData, Item.ChangeIndex);
          fAllFoldRanges.Delete(Item.ChangeIndex);
          SetCaretAndSelection(Item.ChangeStartPos, Item.ChangeStartPos,
            Item.ChangeEndPos);
          SetSelTextPrimitiveEx( Item.ChangeSelMode, PChar(Item.ChangeStr),
            False );
        end;
      //### End Code Folding ###        


Undo is now:
Код
procedure TCustomSynEdit.UndoItem;
...
      //### Code Folding ###
      crDeleteCollapsedFold:
        begin
             SetSelTextPrimitiveEx(Item.ChangeSelMode, PChar(Item.ChangeStr),
               False );
          InternalCaretXY := Item.ChangeStartPos;
          SetCaretAndSelection(Item.ChangeStartPos, Item.ChangeStartPos,
            Item.ChangeEndPos);
          fRedoList.AddChange(Item.ChangeReason, Item.ChangeStartPos,
            Item.ChangeEndPos, '', Item.ChangeSelMode, Item.ChangeData, Item.ChangeIndex);
        end;
      //### End Code Folding ###    


Undo and Redo of deleting collapsed blocks works well now.


Remaining Error is now, if you delete 2 collapsed blocks... it crashs complete. smile I search....

Это сообщение отредактировал(а) DavidCl0nel - 9.8.2006, 13:01
PM MAIL   Вверх
Sep.
Дата 9.8.2006, 13:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 109
Регистрация: 22.7.2004

Репутация: нет
Всего: 6



My two cents: =)

There was bug when you try to Ctrl-A, Ctrl-C file greater than 120kb with foldranges.
Memory leak and performance improve in TCustomSynEdit.GetSelText:
Код

      smNormal:
        //###mod copy collapsed line
        if (First = Last) then
          Result := Copy(Lines[First], ColFrom, ColTo - ColFrom)
        else begin
          ts:=GetUncollapsedStrings;
          // step1: calculate total length of result string
          iLineCount := 0;
          //first line
          Inc(TotalLen, Length(TrimRight(ts[GetRealLineNumber(First)])));
          Inc(iLineCount);
          //middle lines
          for i := GetRealLineNumber(First)+1 to GetRealLineNumber(Last+1)-2 do begin
            Inc(TotalLen, Length(TrimRight(ts[i])));
            Inc(iLineCount);
          end;
          //last line
          Inc(TotalLen, ColTo - 1);
          Inc(TotalLen, Length(sLineBreak) * iLineCount);
          // step2: build up result string
          SetLength(Result, TotalLen);
          P := PChar(Result);
          //first line
          CopyAndForward(TrimRight(ts[GetRealLineNumber(First)]), ColFrom, MaxInt, P);
          CopyAndForward(sLineBreak, 1, MaxInt, P);
          //middle lines
          for i := GetRealLineNumber(First)+1 to GetRealLineNumber(Last+1)-2 do begin
            CopyAndForward(TrimRight(ts[i]), 1, MaxInt, P);
            CopyAndForward(sLineBreak, 1, MaxInt, P);
          end;
          //last line
          CopyAndForward(TrimRight(ts[GetRealLineNumber(Last+1)-1]), 1, ColTo-1, P);
          ts.Free;
        end;
        //###mod copy collapsed line

...

      smLine:
        //###mod copy collapsed line
        begin
          // <-->
          // If block selection includes LastLine,
          // line break code(s) of the last line will not be added.
          // step1: calculate total length of result string
          ts:=GetUncollapsedStrings;
          for i := GetRealLineNumber(First) to GetRealLineNumber(Last+2)-2 do begin
            Inc(TotalLen, Length(TrimRight(ts[i])) + Length(sLineBreak));
          end;
          if Last = Lines.Count then Dec(TotalLen, Length(sLineBreak));

          // step2: build up result string
          SetLength(Result, TotalLen);
          P := PChar(Result);
          for i := GetRealLineNumber(First) to GetRealLineNumber(Last+2)-2 do begin
            CopyAndForward(TrimRight(ts[i]), 1, MaxInt, P);
            CopyAndForward(sLineBreak, 1, MaxInt, P);
          end;
          ts.free;
        end;
        //###mod copy collapsed line

GetUncollapsedStrings returns not pointer but copy of strings. You allways need to free it. Same as you can't use GetUncollapsedStrings.Count because there will be memory leak, need to assign first.

I have drops of foldranges again, when highlighter is delphi =(. php highlighter works good. Simple open SynEdit.pas(400kb) in test programm, collapse line, place cursor to start of collapsed line and press Enter.
--------------------
Syn - TotalCommander lister plugin |  SynTree - coders sourcebook  
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Rules and hints for the forum "SynUniHighlighter"
Vit
Vitalik

Hello, dear user!

This is official forum for SynUniHighlighter component and unofficial forum for SynEdit, Codefolding and all related projects.


Some rules for the forum:

1. Do not create new topic if exactly the same already exists.

2. Don't ask several questions in the same topic. One topic - one question.

3. If discussion changes to far from original topic context, then create a separate thread for new discussion subject.


If you already registered then click here to log in.


If you havent't registered yet then click here and register. You need to type username, password (twice), email (twice) and security code.

Next you need go here and choose English language instead of Russian and press Enter.


Some hints for enghlish-speaking users:

- create new topic;     - create new vote;     - answer to the topic.


With regards, Vit, Vitalik.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | SynUniHighlighter and SynEdit (English Language) | Следующая тема »


 




[ Время генерации скрипта: 0.1886 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.