Модераторы: 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   Вверх
DavidCl0nel
Дата 9.8.2006, 14:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Hmm, it works good at me. I test it with SynEdit.pas and a little Add to "SynMemo1.CodeFolding.FoldRegions.Add(..)" for only an IF-Fold, and it looks ok, if i press return at start of line.

Maybe I missed a change here. I copy your "two cents"-Changes in mine and send it per mail.
PM MAIL   Вверх
DavidCl0nel
Дата 10.8.2006, 17:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Some hours sweat and work later....

Because of the problem, if i delete two blocks and Undo and Redo.... i had to redesign this function. And I think its very good now. In the last version I prevent the second Call fo fUndoList.AddChange with normal crDelete, because i have done this in my deleteLine-Function. This causes such errors.

Now he add 2 Undo Items, one "normal" for crDelete (it consist the lines except the collapsed lines around a block) and another crDeleteCollapsedFold which carry only the collapsed lines... better it carry the data-element for the collapsed lines. The undo (and redo later) only add this data in the array, and the complete code is back! It looks very simple now!

Код
procedure TSynEditCodeFoldingPlugin.LinesDeleted(FirstLine,
  Count: integer);
var
  i: Integer;
  sText: String;
  StartBC, EndBC: TBufferCoord;
begin
  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
        //<-->
        fOwner.fUndoList.AddChange(crDeleteCollapsedFold, StartBC, EndBC,
          sText, fOwner.SelectionMode, fOwner.fAllFoldRanges[i], i);
        fOwner.fAllFoldRanges.Delete(i);
      end;
         
    fOwner.UpdateFoldRanges(FirstLine-1, -Count);
    fOwner.GutterChanged(fOwner);
  end;
  //inherited; //###mod delphi5
end;


And here i could delete very very much. I hold the case for this "version" with VK_SHIFT and such, but it isnt needed anymore. In next version its "if selavail then Result := True" smile
Код
function TCustomSynEdit.CanExecuteInLine(aLine: Integer; aKey: Word): Boolean;
var
  FoldRange1, FoldRange2: TSynEditFoldRange;
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
        Result := True;
      end; // if aKey-else
    end // if SelAvail
     //###mod CF bugs

    // if no selection
    else begin



Код
procedure TCustomSynEdit.RedoItem;
...
      crDelete, crSilentDelete:
        begin
          SetCaretAndSelection(Item.ChangeStartPos, Item.ChangeStartPos,
            Item.ChangeEndPos);
          //<--> Copy only the lines around the collapsed line (the "real" lines), SelText give also the collapsed lines back
          for i := Item.ChangeStartPos.Line to Item.ChangeEndPos.Line-1 do
            TempString := TempString + Lines[i-1] + #13#10;

          fUndoList.AddChange(Item.ChangeReason, Item.ChangeStartPos,
            Item.ChangeEndPos, TempString, Item.ChangeSelMode);
          SetSelTextPrimitiveEx( Item.ChangeSelMode, PChar(Item.ChangeStr),
            False );
          InternalCaretXY := Item.ChangeStartPos;
        end;
...
      //### Code Folding ###
      crDeleteCollapsedFold:
        begin
          fUndoList.AddChange(Item.ChangeReason, Item.ChangeStartPos,
            Item.ChangeEndPos, '', Item.ChangeSelMode, Item.ChangeData, Item.ChangeIndex);
          fAllFoldRanges.Delete(Item.ChangeIndex);
        end;
      //### End Code Folding ###        
      else Application.MessageBox('Unimplemented Redo Branch', 'Redo Error', ID_OK);

Look how easy Redo is now. The changes for Delete had to made, cause he keep SelText in Mind for Undo - but this SelText-function I rewrite to copy also the collapsed lines (you remember?). So i had to write a workaround here, that he only copy the normal lines around the collapsed lines.


Undo the same like Redo:
Код
procedure TCustomSynEdit.UndoItem;
...
      //### Code Folding ###
      crDeleteCollapsedFold:
        begin
          fAllFoldRanges.AddFold(Item.ChangeData);
          fRedoList.AddChange(Item.ChangeReason, Item.ChangeStartPos,
            Item.ChangeEndPos, '', Item.ChangeSelMode, fAllFoldRanges[fAllFoldRanges.AllCount-1], fAllFoldRanges.AllCount-1);
        end;
      //### End Code Folding ###    
      else Application.MessageBox('Unimplemented Undo Branch', 'Undo Error', ID_OK);



In the ExecuteCommand i got the same problem with SelText. Same Workaround.
Код
procedure TCustomSynEdit.ExecuteCommand(Command: TSynEditorCommand; AChar: char;
  Data: pointer);
    
  procedure SetSelectedTextEmpty;
  var
    vSelText: string;
    vUndoBegin, vUndoEnd: TBufferCoord;
    i: Integer;
  begin
    vUndoBegin := fBlockBegin;
    vUndoEnd := fBlockEnd;
    //<--> Copy only the lines around the collapsed line (the "real" lines), SelText give also the collapsed lines back
    //vSelText := SelText;
    for i := fBlockBegin.Line to fBlockEnd.Line-1 do
      vSelText := vSelText + Lines[i-1] + #13#10;
    SetSelTextPrimitive('');
    if (vUndoBegin.Line < vUndoEnd.Line) or (
      (vUndoBegin.Line = vUndoEnd.Line) and (vUndoBegin.Char < vUndoEnd.Char) ) then
    begin
      fUndoList.AddChange( crDelete, vUndoBegin, vUndoEnd, vSelText,
        fActiveSelectionMode );
    end
    else begin
      fUndoList.AddChange( crDeleteAfterCursor, vUndoBegin, vUndoEnd, vSelText,
        fActiveSelectionMode );
    end;
  end;


And the last, also very important and the main issue, cause it needed so many hours... This function is called, if you add a item in the Undo or Redo-Structure... But it calls OnChange there, and in this method i call Rescanforfoldranges. And if i add a item in function LinesDeleted to the Undo-Structure it calls it and make many trouble.
Код
procedure TCustomSynEdit.UndoRedoAdded(Sender: TObject);
begin
  UpdateModifiedStatus;
    
  // we have to clear the redo information, since adding undo info removes
  // the necessary context to undo earlier edit actions
  if (Sender = fUndoList) and not fUndoList.InsideRedo and
     (fUndoList.PeekItem<>nil) and (fUndoList.PeekItem.ChangeReason<>crGroupBreak) then
    fRedoList.Clear;
  if TSynEditUndoList(Sender).BlockCount = 0 then
  //Change calls ReScanForFoldRanges and this destroys data at this time, if a new UndoRedo is added <-->
  //DoChange;
end;


I'm very glad that it works good and very simple.

Maybe i missed a change again, i send it by email.... 
PM MAIL   Вверх
Sep.
Дата 11.8.2006, 10:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Ok. =)
I've updated SynMix basing on your mail.
SynMix update 11/08/06 download (400kb)
There was also added //###mod uncollapse dont reset selection
Код

procedure TCustomSynEdit.UncollapseAll;
var
  i: Integer;
  bb,be: TBufferCoord; //###mod uncollapse dont reset selection
begin
  bb.Char:=fBlockBegin.Char;                    //###mod uncollapse dont reset selection
  bb.Line:=GetRealLineNumber(fBlockBegin.Line); //
  be.Char:=fBlockEnd.Char;                      //
  be.Line:=GetRealLineNumber(fBlockEnd.Line);   //
  
  Lines.BeginUpdate;
  for i := 0 to 9 do
    UncollapseLevel(i, False);
  Lines.EndUpdate;
  
  fBlockBegin:=bb;                              //
  fBlockEnd:=be;                                //###mod uncollapse dont reset selection
end;

Also here is small bug in CanExecuteInLine. 
Код

...
      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 (FoldRange1=nil)or(not FoldRange1.Collapsed) then begin
          Result := True;
        end;
...

There was missed 'if (FoldRange1=nil)' in last 'else'.

PS Here is ours test application
LeakTest (4kb)
You'll need to place test file named 1111.pas in folder of app. We usually use renamed SynEdit.pas as test =)
Also you need SynUniHighlighter - which allows to load highlighters in runtime. Not hardcoded in exe like original SynEdit.
SynUniHighlighter 2.0beta4 (77kb)
Also here used FastMM4, but of course can be commented out.
So in this test app are drops of foldranges:
Collapse line, place cursor to it's start, and press enter.
When using 'php.hgl' there no bug. Does it problem of SynUniHighlighter? =)
--------------------
Syn - TotalCommander lister plugin |  SynTree - coders sourcebook  
PM MAIL   Вверх
DavidCl0nel
Дата 14.8.2006, 10:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



I tried your Leak-program, but i haven't the problems on enter on start of line. This works... Hmm.

But i found a other bug. If you press enter on end of line of a collapsed block, he uncollapse it correctly, and add the line after it. But the fold range start he also move one line after it. I look for it now.




But another thing.

I consider to reject the SelText-changes to its default old function. So he only copy the lines not the collapsed parts.
Reason: I had to make 2 workarounds in my last post for the Undo/Redo. Maybe i should reset SelText, then i dont need this workarounds.

For CopyToClipboard and CutToClipboard i can use the current SelText-function (Maybe i should rename it to SelCompleteText or such).

What do you think?
PM MAIL   Вверх
Sep.
Дата 14.8.2006, 11:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



It's very strange that you don't have bug with drop of foldranges. What version of Delphi do you use? May be some bug in {IFDEF} code.
Цитата(DavidCl0nel @  14.8.2006,  10:02 Найти цитируемый пост)
For CopyToClipboard and CutToClipboard i can use the current SelText-function (Maybe i should rename it to SelCompleteText or such).What do you think?

I think you need left it as is, it's right when in SelText stored all selected text, so i can use it in programm. If you rewrite CutToClipboard what will be with undo and SynEdit.SelText? 
May be it need to rewrite pressing enter at end of collapsed line, so it'll be no uncollapse but insert line after collapsed. If it's possible =)
--------------------
Syn - TotalCommander lister plugin |  SynTree - coders sourcebook  
PM MAIL   Вверх
DavidCl0nel
Дата 14.8.2006, 15:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Delphi5. Got some strange things with compiling SynUniHighlighter at first time with the Include of *.inc. Dont know, what he want, but later he compiles it only with some warnings, not with Errors... Anyway, i dont got the problems like you said it.
 
The remaining unclarity with D5 is also the "inherited" in the TSynEditCodeFoldingPlugin-Methods. I got a really hard crash, if Delphi5 should call inherited, because there are no inherited method, because it is abstract. You, with Delphi X (7? newer?), apparently don't have this problem, because your original source code has the inherited. Maybe you need it (but i couldn't imagine, what he should do there). Try to set a break point to it and have a look, what he does. If you need it (or if your compiler silent ignores it), the commented inherited should set in IFNDEF VER130.





Because of another bug at the workaround with SelText (Undo) I really did it. Before I write a workaround around the workaround, i decide to do this. Now I have a SelCompleteText (the current, called in CopyToClipboard, maybe we should think about the name a little bit) and the old SelText. All old functions, that call SelText, used the old one and we got the expected behavior. The CodeFolding-Feature is a Plugin and care about safe the collapsed parts, if it needs. The complete "model" looks better now.
Undo and Redo are in two parts (you have 2 structures in the Array), one that hold the "real" text, that was deleted (and this was made by the original code, without workarounds and such weird things) and the second new part with the folding-array-element made by TSynEditCodeFoldingPlugin.LinesDeleted. 



Another problem we should talk about...
In "TCustomSynEdit.UndoRedoAdded(Sender: TObject);" I commented the call of DoChange. In my program I call RescanForFoldRanges in the SynMemo.OnChange()-Event, because at this time he should update the foldranges, if you change the collapse-keywords. (And this is right, if I change the word "FOR" in source code to "F OR" the current block shouldnt exist any more).
The problem now wasm if I add a Undo at TSynEditCodeFoldingPlugin.LinesDeleted he called the UndoRedoAdded-Function (its looks right), this called OnChange-Event and this called RescanForFoldRanges and destroys the foldranges behind the back of LinesDeleted. If he returns to LinesDeleted he hasnt the same FoldRanges in the Array and you have the big problem.
So I decided to comment this OnChange - but this is also nonsense, now he never call OnChange-Event (weird...). So I can change FOR to F OR and he dont update all foldranges... This is crap.
Now I dont call Rescanforfoldranges in OnChange, only in Keyup, but this is also not enough. If I destroy a keyword with drag and drop for example he didnt updated it too. OnChange-Event is really the right place for it (And If you are dont allow to do that an other user of this SynMemo should know about this behavior...) This is no solution, but i have actually no idea, why this is the only place to call OnChange. If he add and Undo he maybe call the OnChange (because the Undo was added by changing text, so its right to call onchange...). But... I'm helpless at the moment.




The third thing is CanExecuteInLine. I dont thought of removing only some chars of a collapsed line... He should prevent it like before. So I added some code again to
Код
      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
        FoldRange1 := CollapsableFoldRangeForLine(BlockBegin.Line);
        if BlockBegin.Line = BlockEnd.Line then begin
          //One Line selected
          if (FoldRange1 <> nil) and (FoldRange1.Collapsed) and (not FoldRange1.ParentCollapsed) then begin
            Result := False;
            //Allow only delete complete line, if collapsed
            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
              //Search and delete complete fold range
              for iFold := fAllFoldRanges.AllCount - 1 downto 0 do
                if fAllFoldRanges[iFold].FromLine = BlockBegin.Line then begin
                  fUndoList.AddChange(crDeleteCollapsedFold, StartBC, EndBC, '', SelectionMode, fAllFoldRanges[iFold], iFold);
                  fAllFoldRanges.Delete(iFold);
                end;
              Result := True;
            end;
          end else begin
            Result := True;
          end;
        end else
          //More lines selected
          Result := True;


The fUndoList really dont belong to this place, but the function, that called CanExecute... dont call LinesDeleted, if you select only one (and collapsed) line from beginning to the end. (this is the case in if-statement). So it is a little bit "dirt" in it I think.



And the last (see bug in last post)
Код
      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 begin
            Uncollapse(FoldRange1); //Uncollapse this Block
-->            CaretY := CaretY + FoldRange1.LinesCollapsed + 1; //Put Cursor to the correct line after uncollapse <--
          end;
        end else if (FoldRange1 = nil) or not FoldRange1.Collapsed then begin
          Result := True;
        end;



I send a mail.


Remaining things:
 1. Delete a block, Undo, Redo, Undo, Redo... it crashs. smile
 2. pressing enter at end of collapsed line, so it'll be no uncollapse but insert line after collapsed. If it's possible =) 
 3. Mark a collapsed line (not with Shift+END) with Shift+Down and delete, he dont delete the fold range.
 4. OnChange()-issue
 5. Rename the "new" SelCompleteText?
 6. On some cases he draw the [...]-Symbol at wrong places. Sometimes on the next line with a linebreak-sign in gutter (but on another line that is exactly as long as the error line he draw it right at the end of the text. Sometimes I see it nearly in the middle of the line (It was a short line).. Investigate this.

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


Шустрый
*


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

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



Цитата(DavidCl0nel @  14.8.2006,  15:06 Найти цитируемый пост)
Anyway, i dont got the problems like you said it.

Can you mail me compiled leak.exe?
Цитата(DavidCl0nel @  14.8.2006,  15:06 Найти цитируемый пост)
In my program I call RescanForFoldRanges in the SynMemo.OnChange()

But in SynEdit no need to do this. Look at leak.exe, when i insert space in 'begin' it removes folding range ok.
Цитата(DavidCl0nel @  14.8.2006,  15:06 Найти цитируемый пост)
So I decided to comment this OnChange - but this is also nonsense, now he never call OnChange-Event (weird...).

Yes, it was bad.
Цитата(DavidCl0nel @  14.8.2006,  15:06 Найти цитируемый пост)
If I destroy a keyword with drag and drop for example he didnt updated it too.

Never try it before =)
Цитата(DavidCl0nel @  14.8.2006,  15:06 Найти цитируемый пост)
 If he add and Undo he maybe call the OnChange

it's an idea, but needs to test!
Цитата(DavidCl0nel @  14.8.2006,  15:06 Найти цитируемый пост)
I send a mail.

I compile test prog with fully your synedit.pas but it dont copy contents of collapsed string to clipboard. =( I see that code is in place but something wrong. I'll look at this more completely when got some time.
About bugN3 : it already was done, and now again =(
Цитата(DavidCl0nel @  14.8.2006,  15:06 Найти цитируемый пост)
Rename the "new" SelCompleteText?

I think this name ok =)

Good luck in battle with bugs!
--------------------
Syn - TotalCommander lister plugin |  SynTree - coders sourcebook  
PM MAIL   Вверх
DavidCl0nel
Дата 15.8.2006, 14:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Copy collapsed text to Clipboard works good. (?) Hmm.

Bug 1 exists and only occur, if Rescan is called (see Bug4).

Bug 2 is impossible to solve, if I dont uncollapse the block and move caret, then he moves the folding range start (but it shouldnt), because he calles LinesInserted with FromLine-1. This -1 is the problem, that he update one line to early. But on other cases (return above collapsed blocks) it is needed so. So I decided to let it be. He dont destroy something yet and thats ok.

Bug 3 is solved.

Bug 4
I had to call RescanForFoldRanges... but i work with an own SyntaxHighlighter for my own language and add the folding infos in my code:
Код

  SynMemo1.CodeFolding.HighlighterFoldRegions := False; // !!!
  SynMemo1.CodeFolding.FoldRegions.Add(rtKeyWord, False, False, True, 'If', 'EndIf');
  //more Add...


Maybe I should move this into the SyntaxHighlighter-class (but I have currently no idea how to do this), that the Highlighter should care about it (the destroyed keyword isn't in the keyword-color... this he has corrected).

Issue 5 is discussed and name is ok.

Bug 6 exists. Do you have something like this? It occurs it you have comments after the line, like
Код
if a > b then begin // my comment
...
...
end;


Then he draws the [..]-Symbol in "then begin" and not after comment. I search for this....




1+4+6 is left. I send you an email with both. In leak.exe the problem "enter on beginning" dont destroy the fold, but on some other cases with this huge file in it.

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


Новичок



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

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



Код

procedure TCustomSynEdit.PaintTextLines(AClip: TRect; const aFirstRow, aLastRow,
  FirstCol, LastCol: integer);
...
  procedure PaintLines;
...
            if Gutter.ShowLineNumbers then
            //<--> nTokenPos is to short
            FoldRange.HintMarkLeft := ((nTokenPos + nTokenLen) * CharWidth)
//              FoldRange.HintMarkLeft := ((nTokenPos {+ nTokenLen} - 4) * CharWidth) //###mod pos of [...] to left
//                + Gutter.LeftOffset + (GetAutoSizeDigitCount * CharWidth)
//                + Gutter.RightOffset
            else
            FoldRange.HintMarkLeft := ((nTokenPos + nTokenLen) * CharWidth);
//              FoldRange.HintMarkLeft := ((nTokenPos {+ nTokenLen} - 4) * CharWidth)   //###mod pos of [...] to left
//                + Gutter.LeftOffset + Gutter.RightOffset;


What should the modification do? It was the Bug6. I return it to the old simple calculation and it works good. Or this also work:
Код
            if Gutter.ShowLineNumbers then
            //<--> nTokenPos is to short
//            FoldRange.HintMarkLeft := ((nTokenPos + nTokenLen) * CharWidth)
              FoldRange.HintMarkLeft := ((nTokenPos + nTokenLen - 4) * CharWidth) //###mod pos of [...] to left
                + Gutter.LeftOffset + (GetAutoSizeDigitCount * CharWidth)
                + Gutter.RightOffset
            else
//            FoldRange.HintMarkLeft := ((nTokenPos + nTokenLen) * CharWidth);
              FoldRange.HintMarkLeft := ((nTokenPos + nTokenLen - 4) * CharWidth)   //###mod pos of [...] to left
                + Gutter.LeftOffset + Gutter.RightOffset;

Why you set in nTokenLen Comments?

I dont know, what you want with Left and Right Offset of the Gutter, but it also works ok for the [...]-Signs. Maybe I take the second one.




Now I look for the Bug4-OnChange-behavior. This is the last problem I think.
PM MAIL   Вверх
Sep.
Дата 16.8.2006, 12:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(DavidCl0nel @  15.8.2006,  14:12 Найти цитируемый пост)
Copy collapsed text to Clipboard works good.

It's all ok. I forgot to use SelCompleteText instead of SelText =) But now problem with Cut. It cuts some more lines, and Undo dont work correctly. So this was more better when you use SelText. I try to cut collapsed line in your leak.exe, and there is drop of foldranges.
Цитата(DavidCl0nel @  15.8.2006,  14:12 Найти цитируемый пост)
Maybe I should move this into the SyntaxHighlighter-class (but I have currently no idea how to do this)

It's very easy to write highlighter for any language for SynUniHighlighter. There is GUI highlighter designer too. Link to beta4 is lite version. Full version with demos can be downloaded from unihighlighter.com. So your prog will be more customizable =). Off: What program are you developing? Is there any test or beta to look?
Цитата(DavidCl0nel @  15.8.2006,  14:12 Найти цитируемый пост)
Do you have something like this? It occurs it you have comments after the line, like

No, i never see this bug. In compiled leak.exe that you send for me, it works ok too =) And there is very strange that there is no bug with drop of foldranges. I'll try to find it, but think that i need Delphi5 =) I use BDS2006 now.
Цитата

What should the modification do?

It moves [...] sign inside open/close CF-token. You can see it only when CF-range use 'add closing keyword when collapsing' option set. So there will be no:
begin end [...]
but:
begin [...] end
Цитата

Why you set in nTokenLen Comments?

Because it is'n need here. Left position calculates from left corner, and no need to know length of closing token.

Next found bugs: =(
7. pressing Enter on start of line after collapsed don't move line contents to next line, only moves cursor
8. copy collapsed line and try to paste it to start of next line after collapsed, foldrange moves one line bottom. If i paste simple text block, then all ok.
--------------------
Syn - TotalCommander lister plugin |  SynTree - coders sourcebook  
PM MAIL   Вверх
DavidCl0nel
Дата 16.8.2006, 12:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



>>Off: What program are you developing? Is there any test or beta to look?

It is a editor for an own scripting language. No beta, it need to many settings and "environment" around it. And its only _one_ language, so i dont want to use the unihighlighter. Its only overhead, because i dont want to swap the language/highlighter. So i had to to Bug4 on another way.


I have also this Cut-Problem... i will look at it.



begin [...] end
Ok, i dont use it like that, but if you set the sign to another position you should check, if this end-option is on. On my cases it looks like "if a <[...] then // more comment" - In the middle of the line. Thats not right and I change it to the old one and he draw it always on the end. And for this  nTokenLen is needed.

But there I found another bug. If I set the font size to something big (ie 16 instead of 10) the folding-gutter with the [-] is cut off a little bit (12) or completely cut (16+). I dont found the exactly position at the moment, but i will look at it.


7. ... ok... smile

8. Gna! smile



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


Новичок



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

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



I changed again CanExecuteInLine. 7+8 should work now. Try it with the other problem too.
Код
function TCustomSynEdit.CanExecuteInLine(aLine: Integer; aKey: Word): Boolean;
...
      //###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 (FoldRange1 <> nil) and FoldRange1.Collapsed and not FoldRange1.ParentCollapsed then begin
            Uncollapse(FoldRange1);
          end;
        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 begin
            Uncollapse(FoldRange1); //Uncollapse this Block
            CaretY := CaretY + FoldRange1.LinesCollapsed + 1; //Put Cursor to the correct line after uncollapse
            CaretX := Length(Lines[CaretY-1]) + 1;
          end;
        end else if (FoldRange1 = nil) or 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
        Result := True;
        FoldRange2 := FoldRangeForLine(CaretY+1);
        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;

      //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


Without the -1 now:
Код
procedure TSynEditCodeFoldingPlugin.LinesInserted(FirstLine,
  Count: integer);
begin
  //<--> Update all Foldranges, if Lines inserted
  fOwner.UpdateFoldRanges(FirstLine, Count); 
{$IFNDEF VER130} //###mod delphi5
  inherited;
{$ENDIF}
end;


With <= instead of only <:
Код
procedure TSynEditCodeFoldingPlugin.LinesDeleted(FirstLine,
  Count: integer);
begin
..      if ( (Count = 1) and (fOwner.fAllFoldRanges[i].FromLine = FirstLine) ) or
           ( (Count > 1) and (fOwner.fAllFoldRanges[i].FromLine >= FirstLine) and (fOwner.fAllFoldRanges[i].FromLine <= Pred(FirstLine+Count))) then
      begin
..
end;




Actual bug list:
1. begin [...] end. I changed it to old version. It works good at all other cases. Your case (if with endings) had to catch there and take your code. But at this place you cant get to this attribute "fAddEnding". It is in class "TFoldRegionItem" and not in the FoldRange "TSynEditFoldRange". Dont know how to get the information (if fAddEnding or not) in the paint-function.

2. If I set the font size to something big (ie 16 instead of 10) the folding-gutter with the [-] is cut off a little bit (12) or completely cut (16+). I dont found the exactly position at the moment, but i will look at it.

3. Cut-Problem: It cut the right, but deletes too much.

4. OnChange()-issue.







Edit:

3:
Код
procedure TCustomSynEdit.CutToClipboard;
var
  BB, BE: TBufferCoord;
begin
  if not ReadOnly and SelAvail then
  begin
    BeginUndoBlock;
    try
      //<--> Complete (with collapsed lines) Text
      BB := BlockBegin;
      BE := BlockEnd;
      DoCopyToClipboard(SelCompleteText);
      SetBlockBegin(BB);
      SetBlockEnd(BE);
      SelText := '';
    finally
      EndUndoBlock;
    end;
  end;
end;

SelCompleteText change (no idea why at the moment) the Selection. He copy the right thing, change the selection to some more lines and delete this with more. With this torkaround he reset it to origin place. But Undo didnt work at the moment...
But the real solution should prevent the selectionchanging in SelCompleteText.

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


Новичок



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

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



Ok.. SelCompleteText changed the Selection, because it called GetUncollapsedStrings. This function called UncollapseAll and there you have changed some in last week. If you uncollapse you convert the selection. At a normal case this is ok, but on my SelCompleteText-case not.  So I moved the workaround at beginning and end to SelCompleteText.

Код
function TCustomSynEdit.GetCompleteSelText: string;
...
var
...
  BB, BE: TBufferCoord;
begin
  //Save position (GetUncollapsedStrings called UncollapseAll, which assign the Selection correctly. At this point this is dangerous
  BB := BlockBegin;
  BE := BlockEnd;
  
  if not SelAvail then
...
  end;

  //Get saved position back (GetUncollapsedStrings called UncollapseAll, which assign the Selection correctly. At this point this is dangerous
  SetBlockBegin(BB);
  SetBlockEnd(BE);
end;


Another thing is the CutToClipboard-function. He doesnt mind the SelText in Undo-Buffer, so I had it to change:
Код
procedure TCustomSynEdit.CutToClipboard;
var
  SText: String;
  BB, BE: TBufferCoord;
begin
  if not ReadOnly and SelAvail then
  begin
    BeginUndoBlock;
    try
      //<--> Complete (with collapsed lines) Text
      BB := BlockBegin;
      BE := BlockEnd;
      DoCopyToClipboard(SelCompleteText);
      SText := SelText;
      SetSelTextPrimitiveEx(fActiveSelectionMode, '', False);
      fUndoList.AddChange(crDelete, BB, BE, SText, fActiveSelectionMode);
    finally
      EndUndoBlock;
    end;
  end;
end;

For normal Undo it is necessary to Undo first the collapsed-part (add this item back into array) and then the deleted text of SelText, so I had to buffer the selection (BB/BE) and the text.



The undo-function add the stored fold to the end of the array, but this wasn't ok for most cases. If I cut the first collapsed block for example and Undo it, he add this fold range at the end of the array. He shows it at the right place, but if you want to uncollapse it, it draw wrong lines in the gutter. So I had to change it, to Insert it at the right place with the line number. Then the problem is solved.
Код
      //### Code Folding ###
      crDeleteCollapsedFold:
        begin
          //Insert at right place, not add to end
          for i := 0 to fAllFoldRanges.AllCount - 1 do begin
            if TSynEditFoldRange(Item.ChangeData).FromLine < fAllFoldRanges[i].FromLine then begin
              fAllFoldRanges.AllRanges.Insert(i, Item.ChangeData); 
              fRedoList.AddChange(Item.ChangeReason, Item.ChangeStartPos,
                Item.ChangeEndPos, '', Item.ChangeSelMode, fAllFoldRanges[i], i);
              Break;
            end;
            
            if i = fAllFoldRanges.AllCount - 1 then begin //add to end
              fAllFoldRanges.AddFold(Item.ChangeData);
              fRedoList.AddChange(Item.ChangeReason, Item.ChangeStartPos,
                Item.ChangeEndPos, '', Item.ChangeSelMode, fAllFoldRanges[fAllFoldRanges.AllCount-1], fAllFoldRanges.AllCount-1);
            end;
          end;
            
        end;
      //### End Code Folding ###    


Now it works with Cut, Undo, Redo, Undo, ...


But i found another bug. (gna!) If you collapse the last possible fold range and want to copy it, it crashs with RangeError in Array. It occurs with my RescanForFoldRanges-Call in OnKeyUp(). (In OnChange() I doesnt call it anymore, only there... but this cause this problem.

So its ok and the current bug list is:
1. begin [...] end. I changed it to old version. It works good at all other cases. Your case (if with endings) had to catch there and take your code. But at this place you cant get to this attribute "fAddEnding". It is in class "TFoldRegionItem" and not in the FoldRange "TSynEditFoldRange". Dont know how to get the information (if fAddEnding or not) in the paint-function.

2. If I set the font size to something big (ie 16 instead of 10) the folding-gutter with the [-] is cut off a little bit (12) or completely cut (16+). I dont found the exactly position at the moment, but i will look at it.

3. Cut-Problem solved.

4. OnChange()-issue.


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


Шустрый
*


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

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



Цитата(DavidCl0nel @  16.8.2006,  12:37 Найти цитируемый пост)
but if you set the sign to another position you should check, if this end-option is on.

i no need to check it =) I haven't bug you describe. In this mod there are code where added 5 spaces, so [..] sign never painted over text.
Цитата(DavidCl0nel @  16.8.2006,  12:37 Найти цитируемый пост)
If I set the font size to something big (ie 16 instead of 10)

This is known bug. You can't assign different fonts to gutter and textarea. Only few monospaced font are compatible, but need to find their size. It's because use of CharWidth variable when calculate gutter, but this variable holds charwidth of textarea.
Цитата(DavidCl0nel @  16.8.2006,  14:41 Найти цитируемый пост)
I changed again CanExecuteInLine. 7+8 should work now. Try it with the other problem too.

I test your version from 16/08. Sorry but i stll use some fixed version of synmix from 11/08 because there are a lot of new bugs. And i don't very like idea about SelCompleteText. Because there is shortcuts like Shift+Ins that copy selection with no executing CopyToClipboard. 
May be you need to return some back to version 11/08 ? =)
Found bugs that wasn't in 11/08:
- uncommenting of 
Код

if CodeFolding.Enabled then
    FreeMem(IndentGuides);

gives error 'incompatible types' for me =(
- press Enter at start of line with foldrange don't move foldrange to line below
- press BkSpace at start line with foldrange delete this foldrange
- copy collapsed string delete its collapsed text
e.t.c! 
so there very lot of critical bugs =(

In version 11/08 i edit copy collapsed string moves selection bug like you write here, and some patch needed to my prog:
MouseWhell only scroll text when cursor over textarea. I need it because in my prog need to scroll two windows by Wheel without moving focus.
Код

procedure TCustomSynEdit.WMMouseWheel(var Msg: TMessage);
...
{$ENDIF}

  p:=self.ScreenToClient(Mouse.CursorPos);
  if (p.X<0)or(p.Y<0)or(p.X>Width)or(p.Y>Height) then exit;  //###mod mouse wheel only over editarea

  if GetKeyState(VK_CONTROL) >= 0 then
  begin
{$IFDEF SYN_COMPILER_4_UP}

And there was returned 0 when asking before paint. So rows wasn't yet calculated.
Код

function TCustomSynEdit.GetDisplayLineCount: integer;
begin
  if fWordWrapPlugin = nil then
    Result := Lines.Count
  else if Lines.Count = 0 then
    Result := 0
  else begin
    //Result := fWordWrapPlugin.RowCount;
    Result := max(fWordWrapPlugin.RowCount, Lines.Count); //###mod topline before paint
  end;
end;

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


Новичок



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

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



>> no need to check it =) I haven't bug you describe. In this mod there are code where added 5 spaces, so [..] sign never painted over text
Sure it cause problems, but only in the case if you have //comment at the end of line. This token he cant see correctly and set the [...] sign in the middle of the line above the code. Thats not good and so i stay at my version, cause i didnt want this ending.



>>This is known bug
Bad, but ok.



>>May be you need to return some back to version 11/08 ? =)
Send it back to me with all your changes you made since now. But I only do it, if this was the first version with the correct Undo/Redo with copying the fold in the UndoBuffer, not set Caret and Insert the Text. This was a difficult and bad way. There are maybe many bugs, if you do it this way. But I had change some of mine things too, because some are important. SelCompleteText or not is ok, but all other (InsertLines-1..) should be ok...



>>gives error 'incompatible types' for me =(
What? Compile error or what you mean?



On my last version I couldnt see such bugs, it works on all cases, he copy and cut the right things and so on. I cant imagine what the problem is.
PM MAIL   Вверх
Sep.
Дата 18.8.2006, 09:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(DavidCl0nel @  18.8.2006,  03:45 Найти цитируемый пост)
Sure it cause problems, but only in the case if you have //comment at the end of line.

Here is screenshot with endings in CF-rule
user posted image
and without endings
user posted image

Цитата(DavidCl0nel @  18.8.2006,  03:45 Найти цитируемый пост)
 i stay at my version, cause i didnt want this ending.
 Of course, you told this in first posts in this thread. I only want to say that there no bug for me =)

Цитата(DavidCl0nel @  18.8.2006,  03:45 Найти цитируемый пост)
Send it back to me with all your changes you made since now.

No problems =) But changes aren't major. I don't have so much time to improve component, there only small fixes.
Цитата(DavidCl0nel @  18.8.2006,  03:45 Найти цитируемый пост)
What? Compile error or what you mean?

Yes, it is compile error =(
Цитата(DavidCl0nel @  18.8.2006,  03:45 Найти цитируемый пост)
I couldnt see such bugs, it works on all cases, he copy and cut the right things and so on.

I can send compiled version, if it helps... =)
--------------------
Syn - TotalCommander lister plugin |  SynTree - coders sourcebook  
PM MAIL   Вверх
DavidCl0nel
Дата 20.8.2006, 01:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



>>Here is screenshot with endings in CF-rule
I show you on Monday a screenshot with the error smile

Do you have sent the source code of 11.08. with your changes? I havent got something till now.
PM MAIL   Вверх
Sep.
Дата 20.8.2006, 08:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(DavidCl0nel @  20.8.2006,  01:18 Найти цитируемый пост)
Do you have sent the source code of 11.08. with your changes? I havent got something till now.

Yes, of course. Now i send once more. May be try to other your mail? Or you can download SynMix, there was very little changes in it since upload.

OFF:
best prog i've seen to compare sources - WinMerge, and it is free.

Это сообщение отредактировал(а) Sep. - 20.8.2006, 08:21
--------------------
Syn - TotalCommander lister plugin |  SynTree - coders sourcebook  
PM MAIL   Вверх
DavidCl0nel
Дата 21.8.2006, 11:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Your mail was catched by spam filter, i saw the second one moving in the spam-folder and could move it back. Your first mail was deleted I think, because the spam box was deleted to early (one day i think).

I had to change the workarounds a little bit
Код
  procedure SetSelectedTextEmpty;
..
    for i := fBlockBegin.Line to fBlockEnd.Line-1 do
      vSelText := vSelText + Lines[i-1] + #13#10;
    if fBlockBegin.Line = fBlockEnd.Line then //Only one Line <-->
      vSelText := TrimRight(Lines[fBlockBegin.Line-1]);
..

The other workaround in the Redo-case like this one. Check your mail with the complete source.

I hope you have now no errors like me.

PS: I merge it with TotalCommander Compare. ;)
PM MAIL   Вверх
DavidCl0nel
Дата 21.8.2006, 14:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Some other changes, please test it with these little changes.

After Pasting I had to call RescanForFoldRanges, to get the new FoldRange work. Please test it with and without this change. Maybe your control update it correctly like on destroying fold-marker (for -> f or). The OnChange-issue...
Код
procedure TCustomSynEdit.PasteFromClipboard;
...
  DoOnPaintTransient(ttAfter);                                                
  RescanForFoldRanges;
end;


Код
function TCustomSynEdit.CanExecuteInLine(aLine: Integer; aKey: Word): Boolean;
...
      if aKey = VK_RETURN then begin
        if CaretX = 1 then begin
          Result := True;
          if (FoldRange1 <> nil) and FoldRange1.Collapsed and not FoldRange1.ParentCollapsed then begin
            Uncollapse(FoldRange1);
          end;
          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 begin
            Uncollapse(FoldRange1); //Uncollapse this Block
            CaretY := CaretY + FoldRange1.LinesCollapsed + 1; //Put Cursor to the correct line after uncollapse
            CaretX := Length(Lines[CaretY-1]) + 1;
          end else begin
            CaretX := Length(TrimRight(Lines[CaretY - 1])) + 1;
          end;

        end else if (FoldRange1 = nil) or (not FoldRange1.Collapsed) then begin
          Result := True;
        end;


Delete had to changed. In older version i cant delete the line between two blocks (If-block, free-line, other-if-block. Put cursor at begin of free line and press delete - it will be ignored). So this change:
Код

      end else if (aKey = VK_DELETE) and (CaretX >= Length(TrimRight(Lines[CaretY-1])) + 1) then begin
        Result := True;
        FoldRange2 := FoldRangeForLine(CaretY+1);


        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;





And the Plugin-functions changed once again. I decided to rewrite the LinesInserted for the Return-At-Begin-On-Line-Case.
Код
procedure TSynEditCodeFoldingPlugin.LinesDeleted(FirstLine, Count: integer);

var
  i: Integer;
  StartBC, EndBC: TBufferCoord;
begin
  if Count > 0 then
  begin
    //###mod CF bugs
    for i := fOwner.fAllFoldRanges.AllCount - 1 downto 0 do
      if ( (Count = 1) and (fOwner.fAllFoldRanges[i].FromLine-1 = FirstLine) ) or
         ( (Count > 1) and (fOwner.fAllFoldRanges[i].FromLine >= FirstLine) and (fOwner.fAllFoldRanges[i].FromLine <= Pred(FirstLine+Count))) then
      begin
        fOwner.fUndoList.AddChange(crDeleteCollapsedFold, StartBC, EndBC,
          '', fOwner.SelectionMode, fOwner.fAllFoldRanges[i], i);
        fOwner.fAllFoldRanges.Delete(i);
      end;

    fOwner.UpdateFoldRanges(FirstLine-1, -Count);
    fOwner.GutterChanged(fOwner);
    //###mod CF bugs
  end;
{$IFNDEF VER130} //###mod delphi5
  inherited;
{$ENDIF}
end;
      
procedure TSynEditCodeFoldingPlugin.LinesInserted(FirstLine, Count: integer);
var
  i: Integer;
begin
  //fOwner.UpdateFoldRanges(FirstLine, Count);    
  for i := fOwner.fAllFoldRanges.AllCount - 1 downto 0 do begin //###mod Update all Foldranges, if Lines inserted
    if (fOwner.fAllFoldRanges[i].FromLine >= FirstLine) or (fOwner.fAllFoldRanges[i].ToLine >= FirstLine) then begin
      fOwner.fAllFoldRanges[i].MoveBy(Count);
    end;
  end;
{$IFNDEF VER130} //###mod delphi5
  inherited;
{$ENDIF}
end;




Edit:

And very important. The OnChange-issue:
Код

function TCustomSynEdit.IsKeywordAtCursorPos(OpenKeyWord: PBoolean): Boolean;
...
begin
  Result := False;
    
  //<-->
  if CodeFolding.HighlighterFoldRegions then begin
    if (fHighlighter <> nil) and (fHighlighter.FoldRegions.Count = 0) then
    begin
      Result := False;
      Exit;
    end
    else if (fHighlighter <> nil) then
      Result := IsKeywordAtCursorPosForFoldRegions(OpenKeyWord,
        fHighlighter.FoldRegions);
  end else begin
    if (CodeFolding.FoldRegions.Count > 0) then 
      Result := IsKeywordAtCursorPosForFoldRegions(OpenKeyWord,
        CodeFolding.FoldRegions);
  end;
end;


I have my FoldRegion-Infos in the Control, not in the Highlighter. (i set it if i create a form in my source code with all keywords for folds). And in my highlighter I dont have this information, so he dont do something and exit the function. With my change he looks also in the Control, if the Flag is set. Now it works (for -> f or). Great. smile





Last Bug I found:
 - Copy something in LineSelect-Mode. If you insert it somewhere, it overwrite the text. If you paste it in an simple text editor and recopy it and paste it in Syn it works. Something is wrong in the SpecialClipboardFormat.

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


Шустрый
*


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

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



Цитата

Please test it with and without this change

I cant test it because of bug in delphi highlighter with drop of foldranges. But i see that func is called and other foldranges don't crush =) (In php HL there one char foldranges.)
Цитата

And very important. The OnChange-issue

Viva!
Цитата

Last Bug I found:

strange =( and when i copy text in LineSelect and try to paste in NormalSelect it paste nothing

I added code from last your post to code from your mail and have now this bugs =(:
1. when select all collapsed line in NormalSelect and delete - there left [+] on gutter. And undo don't return collapsed text.
2. if select this line by click on gutter and delete - text of line deletes, but foldrange dont deletes and moves one string above
Код

procedure TSynEditCodeFoldingPlugin.LinesDeleted
...
      if ( (Count = 1) and (fOwner.fAllFoldRanges[i].FromLine{-1} = FirstLine) ) or

It because of -1 here. For what it needed?
And i still search for FreeMem(IndentGuides); error. May be i need to write freeing of array of array manually. 
Nobody to ask for, because Vitalik have no internet connection for 3 weeks =(
--------------------
Syn - TotalCommander lister plugin |  SynTree - coders sourcebook  
PM MAIL   Вверх
DavidCl0nel
Дата 22.8.2006, 11:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



My last bug is still exists. If I use NormalInsert instead of LinesInsert (there are a Case that decide this) I can insert it "correct", but LineInsert should insert it on another way. But I have some errors if i Undo this block-paste.
Edit: It occurs because Undo want to delete the pasted block and this called LinesDeleted. And LinesDeleted fill the Undo-Buffer again with the collapsed fold. After LinesDeleted he also undo this element and restore the collapsed text again. Not really what i want. ;) Dont know at the moment, how to prevent this.

One other error was with selecting a complete line next to a collapses line. There he start at wrong position and copy also the collapsed lines. I have corrected it and I send you later a mail with the corrected. Another little fix is needed in LinesInserted too.

Your problems:
1. Yes smile If I select and delete only 4 of 5 folds he can undo it correct... Hmm. I will look at it.
Solution in UndoItem: If nothing is in, he cant go through the array and cant add. Fixed.
Код
      //### Code Folding ###
      crDeleteCollapsedFold:
        begin
          if fAllFoldRanges.AllCount > 0 then begin
            //Insert at right place, not add to end
            for i := 0 to fAllFoldRanges.AllCount - 1 do begin
              if TSynEditFoldRange(Item.ChangeData).FromLine <= fAllFoldRanges[i].FromLine then begin
                fAllFoldRanges.AllRanges.Insert(i, Item.ChangeData); 
                fRedoList.AddChange(Item.ChangeReason, Item.ChangeStartPos,
                  Item.ChangeEndPos, '', Item.ChangeSelMode, fAllFoldRanges[i], i);
                Break;
              end;
            
              if i = fAllFoldRanges.AllCount - 1 then begin //add to end
                fAllFoldRanges.AddFold(Item.ChangeData);
                fRedoList.AddChange(Item.ChangeReason, Item.ChangeStartPos,
                  Item.ChangeEndPos, '', Item.ChangeSelMode, fAllFoldRanges[fAllFoldRanges.AllCount-1], fAllFoldRanges.AllCount-1);
              end;
            end;
          end else begin
            //Add
            fAllFoldRanges.AddFold(Item.ChangeData);
            fRedoList.AddChange(Item.ChangeReason, Item.ChangeStartPos,
              Item.ChangeEndPos, '', Item.ChangeSelMode, fAllFoldRanges[fAllFoldRanges.AllCount-1], fAllFoldRanges.AllCount-1);
          end;
        end;
      //### End Code Folding ###  


2. -1 was needed sometimes. There are so much cases, and for some I test it with and without -1. I cant remember for what -1 was good.
Now I dont have this -1.
PS: Click on Gutter select the line? Dont have this feature. He collapse and uncollapse the block.
Edit: If you put cursor one line above a block (collapsed or not collapsed, no matter) - its a free line - and press DEL-Key, he deletes the foldrange in this function because of no -1. This case had to catched on some way.
Solution:
Код
procedure TCustomSynEdit.ExecuteCommand(Command: TSynEditorCommand; AChar: char;
...
      ecDeleteChar:
...
              // join line with the line after
              if CaretY < Lines.Count then
              begin
                Helper := StringOfChar(#32, CaretX - 1 - Len);
                ProperSetLine(CaretY - 1, Temp + Helper + Lines[CaretY]);
                Caret.Char := 1;
                Caret.Line := CaretY + 1;
                Helper := #13#10;
                Lines.Delete(CaretY);
                DoLinesDeleted(CaretY, 1); //<-->
              end;
...

There was a CaretY+1, but i dont know, why it should added 1.

3. FreeMem compiles good. But in whole function the IndentGuides only is filled and needed in commented lines. Nobody use it and you can delete the variable.

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


Новичок



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

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



Цитата
My last bug is still exists. If I use NormalInsert instead of LinesInsert (there are a Case that decide this) I can insert it "correct", but LineInsert should insert it on another way. But I have some errors if i Undo this block-paste.
Edit: It occurs because Undo want to delete the pasted block and this called LinesDeleted. And LinesDeleted fill the Undo-Buffer again with the collapsed fold. After LinesDeleted he also undo this element and restore the collapsed text again. Not really what i want. ;) Dont know at the moment, how to prevent this.

This I could only solve with an interface change. smile I dont like it, but it is needed. This function should decide, if add to undo list or not.
Also an other -1 was wrong in this function (UpdateFoldRanges). Now it looks like:
Код
procedure TSynEditCodeFoldingPlugin.LinesDeleted(FirstLine, Count: integer; AddToUndoList: Boolean);
var
  i: Integer;
  StartBC, EndBC: TBufferCoord;
begin
  if Count > 0 then
  begin
    //###mod CF bugs
    for i := fOwner.fAllFoldRanges.AllCount - 1 downto 0 do
      if ( (Count = 1) and (fOwner.fAllFoldRanges[i].FromLine = FirstLine) ) or
         ( (Count > 1) and (fOwner.fAllFoldRanges[i].FromLine >= FirstLine) and (fOwner.fAllFoldRanges[i].FromLine <= Pred(FirstLine+Count))) then
      begin
        if AddToUndoList then
          fOwner.fUndoList.AddChange(crDeleteCollapsedFold, StartBC, EndBC,
            '', fOwner.SelectionMode, fOwner.fAllFoldRanges[i], i);
        
        fOwner.fAllFoldRanges.Delete(i);
      end;

    fOwner.UpdateFoldRanges(FirstLine, -Count);
    fOwner.GutterChanged(fOwner);
    //###mod CF bugs
  end;
{$IFNDEF VER130} //###mod delphi5
  inherited;
{$ENDIF}
end;

Following functions had to change. The "upper" functions dont need it, but had to pipe it to the last function, where it is needed.
TCustomSynEdit.DoLinesDeleted(FirstLine, Count: integer; AddToUndoList: Boolean);
TSynEditPlugin.LinesDeleted(FirstLine, Count: integer; AddToUndoList: Boolean); virtual; abstract;
TSynEditCodeFoldingPlugin.LinesDeleted(FirstLine, Count: integer; AddToUndoList: Boolean); override;


LinesInserted was changed a little bit. New is the Collapsed-Check.
Код
procedure TSynEditCodeFoldingPlugin.LinesInserted(FirstLine, Count: integer);
var
  i: Integer;
begin
  //fOwner.UpdateFoldRanges(FirstLine, Count);    
  for i := fOwner.fAllFoldRanges.AllCount - 1 downto 0 do begin //###mod Update all Foldranges, if Lines inserted
    if (fOwner.fAllFoldRanges[i].FromLine >= FirstLine) or (not fOwner.fAllFoldRanges[i].Collapsed and (fOwner.fAllFoldRanges[i].ToLine >= FirstLine)) then begin
      fOwner.fAllFoldRanges[i].MoveBy(Count);
    end;
  end;
{$IFNDEF VER130} //###mod delphi5
  inherited;
{$ENDIF}
end;


GetSelText copy a line to early. Fix is in For-loop with First+1:
Код
    case fActiveSelectionMode of
      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+1)-1])));
          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+1)-1]), 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
      smColumn:
...
      smLine:
        //###mod copy collapsed line
        begin
          ts:=GetUncollapsedStrings;
          // 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+1)-1 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+1)-1 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
    end;




Another bug is in the workaround for GetSelText. This workaround should copy the right parts of course. So it had to make different things in all 3 selection modes.

In ExecuteCommand it is now much more difficult:
Код
    //Copy only the lines around the collapsed line (the "real" lines), SelText give also the collapsed lines back
    vSelText := '';
    Case fActiveSelectionMode of
      smNormal:
        begin
          if fBlockBegin.Line = fBlockBegin.Line then begin // One in Line
            vSelText := Copy(Lines[fBlockBegin.Line-1], fBlockBegin.Char, fBlockEnd.Char-fBlockBegin.Char);
          end else begin
            vSelText := Copy(Lines[fBlockBegin.Line-1], fBlockBegin.Char, MaxInt) + #13#10;
            for i := fBlockBegin.Line+1 to fBlockEnd.Line-1 do
              vSelText := vSelText + Lines[i-1] + #13#10;
            vSelText := vSelText + Copy(Lines[fBlockEnd.Line-1], 1, fBlockEnd.Char-1);
          end;
        end;
      smColumn:
        begin
          for i := fBlockBegin.Line to fBlockEnd.Line do
            vSelText := vSelText + Copy(Lines[i-1], fBlockBegin.Char, fBlockEnd.Char-fBlockBegin.Char) + #13#10;
        end;
      smLine:
        begin
          for i := fBlockBegin.Line to fBlockEnd.Line do
            vSelText := vSelText + Lines[i-1] + #13#10;
        end;
    end;


In SetSelTextExternal it is the same. (Copy this block and rename the variable from sText to it)



That is why i original think of SetCompleteText..... So it is a little bit difficult, but it works now. But i dont like it.


I send a mail with complete source.


I think I now have found and fix the most common problems. I hope it... It must have an end sometime....

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


Шустрый
*


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

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



Цитата
PS: Click on Gutter select the line? Dont have this feature. He collapse and uncollapse the block.

You need click and drag mouse down or up to select lines
Цитата
If you put cursor one line above a block (collapsed or not collapsed, no matter) - its a free line - and press DEL-Key, he deletes the foldrange in this function because of no -1. This case had to catched on some way.
Solution:

It's need to edit another DoLinesDeleted(CaretY{+1}, 1); too in ecDeleteLastChar: to prevent drop of foldrange when press BkSpace on start of line with foldrange.
[quote]IndentGuides. Nobody use it and you can delete the variable.[/qoute]
Heh=) And you may comment out 'SynRegExpr' in uses clause, it not used too.
Цитата
I send a mail with complete source.

Ok, but mail differs from your last post =). I added code in last post and test it.
Цитата
I think I now have found and fix the most common problems. I hope it... It must have an end sometime....

Great! Bug with column select , delete and undo deleteion fixed! I found small bugs:
1. Bug when cursor at end of line with foldrange and press BkSpace - drop of current foldrange
2. When delete line before last string of foldrange then start of foldrange moves one line down

There are bug with keystrokes. If i assign to any of it shortcut:=0 (none) Then it thinks that key=0 toggles it. But in onKeyDown assigment of key=0 (i cant assign to it -1) is stops processing key. Need to edit SynKeyCmds.pas
Код
function TSynEditKeyStrokes.FindKeycode(Code: word; SS: TShiftState): integer;
var
  x: integer;
begin
  Result := -1;
  if (Code=0)and(SS=[]) then exit; //###mod key(0)=ecNone

and
Код
function TSynEditKeyStrokes.FindKeycode2(Code1: word; SS1: TShiftState;
  Code2: word; SS2: TShiftState): integer;
var
  x: integer;
begin
  Result := -1;
  if (Code1=0)and(Code2=0)and(SS1=[])and(SS2=[]) then exit;  //###mod key(0)=ecNone

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


Шустрый
*


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

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



Цитата

In ExecuteCommand it is now much more difficult:

Heh, some error =): you write 
Код

if fBlockBegin.Line = fBlockBegin.Line then begin // One in Line
may be you mean
if fBlockBegin.Line = fBlockEnd.Line then begin // One in Line

There another error
3.  Press Ctrl-A and then any letter - will get AV. If there not full text selected - then all ok. Looks like bug in SetSelTextPrimitiveEx but i cant find it =(
--------------------
Syn - TotalCommander lister plugin |  SynTree - coders sourcebook  
PM MAIL   Вверх
DavidCl0nel
Дата 23.8.2006, 12:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



>>It's need to edit another DoLinesDeleted(CaretY{+1}, 1); too in ecDeleteLastChar: to prevent drop of foldrange when press BkSpace on start of line with foldrange.

Ok



>>There are bug with keystrokes

I dont know, what you do with keystrokes, but ok. ;)

>>1. Bug when cursor at end of line with foldrange and press BkSpace - drop of current foldrange
I cant press BkSpace there. It is ignored.

>>2. When delete line before last string of foldrange then start of foldrange moves one line down
Yes. It was CanExecuteInline.
Код
      if aKey = VK_RETURN then begin
        if CaretX = 1 then begin
          Result := True;
          if (FoldRange1 <> nil) and FoldRange1.Collapsed and not FoldRange1.ParentCollapsed then begin
            Uncollapse(FoldRange1);
          end;

There was a CaretY+1.

>>Heh, some error =): you write 
Yes i found it today. It should be on both BlockEnd.

Another change with Undo for Clipboard:
Код
procedure TCustomSynEdit.CutToClipboard;
begin
  if not ReadOnly and SelAvail then
  begin
    BeginUndoBlock;
    try
      DoCopyToClipboard(SelText);
      SetSelTextExternal('');
    finally
      EndUndoBlock;
    end;
  end;
end;


And in SetSelTextExternal..
Код
    //<--> Undo the delete of "real" lines after the collapsed Block
    if vSelText <> '' then
      fUndoList.AddChange(crDelete, StartOfBlock, EndOfBlock, vSelText, fActiveSelectionMode);
 The StartOfBlock and EndOfBlock.


In RedoItem is the third place for the case (i dont like it - really)
Код
      crDelete, crSilentDelete:
        begin
          SetCaretAndSelection(Item.ChangeStartPos, Item.ChangeStartPos,
            Item.ChangeEndPos);

          //Copy only the lines around the collapsed line (the "real" lines), SelText give also the collapsed lines back
          Case Item.ChangeSelMode of
            smNormal:
              begin
                if Item.ChangeStartPos.Line = Item.ChangeEndPos.Line then begin // One in Line
                  TempString := Copy(Lines[Item.ChangeStartPos.Line-1], Item.ChangeStartPos.Char, Item.ChangeEndPos.Char-Item.ChangeStartPos.Char);
                end else begin
                  TempString := Copy(Lines[Item.ChangeStartPos.Line-1], Item.ChangeStartPos.Char, MaxInt) + #13#10;
                  for i := Item.ChangeStartPos.Line+1 to Item.ChangeEndPos.Line-1 do
                    TempString := TempString + Lines[i-1] + #13#10;
                  TempString := TempString + Copy(Lines[Item.ChangeEndPos.Line-1], 1, Item.ChangeEndPos.Char-1);
                end;
              end;
            smColumn:
              begin
                for i := Item.ChangeStartPos.Line to Item.ChangeEndPos.Line do
                  TempString := TempString + Copy(Lines[i-1], Item.ChangeStartPos.Char, Item.ChangeEndPos.Char-Item.ChangeStartPos.Char) + #13#10;
              end;
            smLine:
              begin
                for i := Item.ChangeStartPos.Line to Item.ChangeEndPos.Line do
                  TempString := TempString + Lines[i-1] + #13#10;
              end;
          end;

          fUndoList.AddChange(Item.ChangeReason, Item.ChangeStartPos,
            Item.ChangeEndPos, TempString, Item.ChangeSelMode);
          SetSelTextPrimitiveEx( Item.ChangeSelMode, PChar(Item.ChangeStr),
            False );
          InternalCaretXY := Item.ChangeStartPos;
        end;

Then Undo-Redo-Undo works for Cut and Delete a fold.


>>3.  Press Ctrl-A and then any letter - will get AV. If there not full text selected - then all ok. Looks like bug in SetSelTextPrimitiveEx but i cant find it =( 

No. But maybe it is solved with upper changes.




Other question:
On PaintLines for Drawing the indentGuides for non collapsed folds, why you have this:
Код
                if Canvas.Pen.Color<>clGray then begin                      //###mod IndentGiudes change highlight
                  Canvas.Pen.Color := clGray;                               //
                  Canvas.MoveTo(X, Y);                                      //
                  Canvas.LineTo(X, rcLine.Bottom);                          //
                  Canvas.Pen.Color := clBlack;                              //
                end;                                                        //###mod IndentGiudes change highlight

I like it, if it is the current fold of cursor, that he draw the line in Red. Why you set it here to other things and draw it gray?






Edit: I found a very tiny bug with the IndentGuides on one situation. If you have a Keyword for FoldEnd similar to FoldStart (for example IF-ENDIF) he found after END (if you set the cursor there) the new IF and think he found a new Fold and dont draw the IndentGuides correctly in red.

Fix is:
Код
function TCustomSynEdit.IsKeywordAtCursorPos(OpenKeyWord: PBoolean): Boolean;
...
      Keyword := FoldRegions[i].Open;
  
      repeat
        P := Pos(Keyword, Line);
        if Pos(FoldRegions[i].Close, Line) <> 0 then P := 0; //If KeyWordClose
  
        if (P > 0) and ((CaretX >= P)
        and (CaretX <= P + Integer( StrLen(Keyword) ))) then // Cast to Integer type to shut up the compiler

With this new if Pos he dont make this little failure and draw the IndentGuides in whole keyword.



Last Edit:
LinesInserted was wrong, if you insert a line in a block. Then he moves the complete foldrange, with start... Not right. It is now:
Код
procedure TSynEditCodeFoldingPlugin.LinesInserted(FirstLine, Count: integer);
var
  i: Integer;
begin
  //fOwner.UpdateFoldRanges(FirstLine, Count);    
  for i := fOwner.fAllFoldRanges.AllCount - 1 downto 0 do begin //###mod Update all Foldranges, if Lines inserted
    if (fOwner.fAllFoldRanges[i].FromLine >= FirstLine) then 
      fOwner.fAllFoldRanges[i].FromLine := fOwner.fAllFoldRanges[i].FromLine + Count;

    if (not fOwner.fAllFoldRanges[i].Collapsed and (fOwner.fAllFoldRanges[i].ToLine >= FirstLine)) then 
      fOwner.fAllFoldRanges[i].ToLine := fOwner.fAllFoldRanges[i].ToLine + Count;
  end;
{$IFNDEF VER130} //###mod delphi5
  inherited;
{$ENDIF}
end;



And now I send a email.

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


Новичок



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

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



Today fixes: 

Код
function TCustomSynEdit.CanExecuteInLine(aLine: Integer; aKey: Word): Boolean;
    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
        FoldRange1 := CollapsableFoldRangeForLine(BlockBegin.Line);
        if BlockBegin.Line = BlockEnd.Line then begin
          //One Line selected
          if (FoldRange1 <> nil) and (FoldRange1.Collapsed) and (not FoldRange1.ParentCollapsed) then begin
            Result := False;
            //Direction
            if fBlockBegin.Char > fBlockEnd.Char then begin //swap it
              StartBC := fBlockBegin;
              fBlockBegin := fBlockEnd;
              fBlockEnd := StartBC;
            end;
            
            //Allow only delete complete line, if collapsed
            if ((fBlockBegin.Char = 1) and (fBlockEnd.Char >= Length(TrimRight(Lines[fBlockEnd.Line - 1])) + 1)) then begin
              //Search and delete complete fold range
              for iFold := fAllFoldRanges.AllCount - 1 downto 0 do
                if fAllFoldRanges[iFold].FromLine = fBlockBegin.Line then begin
                  fUndoList.AddChange(crDeleteCollapsedFold, StartBC, EndBC, '', SelectionMode, fAllFoldRanges[iFold], iFold);
                  fAllFoldRanges.Delete(iFold);
                end;
              Result := True;
            end;
          end else begin
            Result := True;
          end;
        end else begin
          //More lines selected
          //Direction
          if fBlockBegin.Line > fBlockEnd.Line then begin //swap it
            StartBC := fBlockBegin;
            fBlockBegin := fBlockEnd;
            fBlockEnd := StartBC;
          end;
          Result := True;
        end;
      end; // if aKey-else

If you select from back to end a word or more lines and delete it, the UndoBuffer (in one of this workarounds) isnt filled correctly, because of the wrong "direction". This fix always set BlockEnd after BlockBegin.





Maybe I edit some other changes in this post later, but it looks good yet. smile
PM MAIL   Вверх
Sep.
Дата 24.8.2006, 21:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Looks more stable than ever!
 Now we can update SynMix. Next step to excelence =)
 
 SynMix update 24/08/06 great thanx to DavidCl0nel
 download 400kb
 
 
Цитата
On PaintLines for Drawing the indentGuides for non collapsed folds, why you have this:

 I have this only for more bolder visual appearance of highlighted indent guide. It draws only even dots in normal state. I did that it first draw line under these even dots - so looks more bolder.
 
 
Цитата
>>3.  Press Ctrl-A and then any letter - will get AV. If there not full text selected - then all ok. Looks like bug in SetSelTextPrimitiveEx but i cant find it =( 
 No. But maybe it is solved with upper changes.

 Seems like it is bug of Syn, because work good in LeakTest =( Strange...
 
 Some non-common bug of original CF left. May be now its time for it? =)
 1. Select collapsed line from start to end by mouse in NormalSelect. Then paste above collapsed line - it'll paste without colapsed text and drop of foldrange of collapsed line.
--------------------
Syn - TotalCommander lister plugin |  SynTree - coders sourcebook  
PM MAIL   Вверх
DavidCl0nel
Дата 28.8.2006, 10:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



>>I have this only for more bolder visual appearance of highlighted indent guide. It draws only even dots in normal state. I did that it first draw line under these even dots - so looks more bolder

Ok, but then you have to reset the color to the original (in this case red), not in all cases back to black. You should buffer the color in a variable or make the decision after your extra bold line.


>>1. Select collapsed line from start to end by mouse in NormalSelect. Then paste above collapsed line - it'll paste without colapsed text and drop of foldrange of collapsed line. 

Hmm, a little bit yes. Paste without collapsed text is true, but he don't drop the fold. I had to catch this case in CopyToClipboard (CutToClipboard the same). But I don't know, if I have time for it today.
PM MAIL   Вверх
Sep.
Дата 3.9.2006, 14:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата
Ok, but then you have to reset the color to the original (in this case red), not in all cases back to black. You should buffer the color in a variable or make the decision after your extra bold line.

But color already backuped above:
OldColor := Canvas.Brush.Color;
and restored after.
Цитата
Hmm, a little bit yes. Paste without collapsed text is true, but he don't drop the fold. I had to catch this case in CopyToClipboard (CutToClipboard the same). But I don't know, if I have time for it today.

It will be great, if there willn't be workaround in CopyToClipboard. Because it don't called when Ctrl-V / Ctrl-C. It only called by program. Strange that i have drop of foldrange. May be again Delphi5 =)

Ok, there some small fixes.
Wrong working if you select text by mouse from right to left (BlockBegin greater than BlockEnd)
Код

  procedure SetSelectedTextEmpty;
  var
    vSelText: string;
    vUndoBegin, vUndoEnd, BB, BE: TBufferCoord;
    i: Integer;
  begin
    vUndoBegin := fBlockBegin;
    vUndoEnd := fBlockEnd;
    //vSelText := SelText;
    //###mod copy CF  
    //Copy only the lines around the collapsed line (the "real" lines), SelText give also the collapsed lines back
    vSelText := '';
    BB:=GetBlockBegin;
    BE:=GetBlockEnd;
    Case fActiveSelectionMode of
      smNormal:
        begin
          if BB.Line = BE.Line then begin // One in Line
            vSelText := Copy(Lines[BB.Line-1], BB.Char, BE.Char-BB.Char);
          end else begin
            vSelText := Copy(Lines[BB.Line-1], BB.Char, MaxInt) + #13#10;
            for i := BB.Line+1 to BE.Line-1 do
              vSelText := vSelText + Lines[i-1] + #13#10;
            vSelText := vSelText + Copy(Lines[BE.Line-1], 1, BE.Char-1);
          end;
        end;
      smColumn:
        begin
          for i := BB.Line to BE.Line do
            vSelText := vSelText + Copy(Lines[i-1], BB.Char, BE.Char-BB.Char) + #13#10;
        end;
      smLine:
        begin
          for i := BB.Line to BE.Line do
            vSelText := vSelText + Lines[i-1] + #13#10;
        end;
    end;
    //###mod copy CF 
    SetSelTextPrimitive('');
...

and
Код

procedure TCustomSynEdit.SetSelTextExternal(const Value: string);
var
  StartOfBlock, EndOfBlock, BB, BE: TBufferCoord;
  i: Integer;
  sText: String;
begin
  BeginUndoBlock;
  try
    if SelAvail then
    begin
      //fUndoList.AddChange(crDelete, fBlockBegin, fBlockEnd,SelText, fActiveSelectionMode);
      //###mod
      BB:=GetBlockBegin;
      BE:=GetBlockEnd;
      Case fActiveSelectionMode of
        smNormal:
          begin
            if BB.Line = BE.Line then begin // One in Line
              sText := Copy(Lines[BB.Line-1], BB.Char, BE.Char-BB.Char);
            end else begin
              sText := Copy(Lines[BB.Line-1], BB.Char, MaxInt) + #13#10;
              for i := BB.Line+1 to BE.Line-1 do
                sText := sText + Lines[i-1] + #13#10;
              sText := sText + Copy(Lines[BE.Line-1], 1, BE.Char-1);
            end;
          end;
        smColumn:
          begin
            for i := BB.Line to BE.Line do
              sText := sText + Copy(Lines[i-1], BB.Char, BE.Char-BB.Char) + #13#10;
          end;
        smLine:
          begin
            for i := BB.Line to BE.Line do
              sText := sText + Lines[i-1] + #13#10;
          end;
      end;
      //###mod
...

Sometimes dont called OnGutterClick method when WordWrap enabled. Need to edit TCustomSynEdit.DoOnGutterClick
Код

...
  if Assigned(fOnGutterClick) then
  begin
    line := PixelsToRowColumn(X,Y).Row;
    line:=RowToLine(line); //###mod bug with onGutterClick
    if line <= Lines.Count then
    begin
...

and allways copy to clipboard in unicode if possible. It usefull only for russian locale i think.
Код

procedure TCustomSynEdit.DoCopyToClipboard(const SText: string);
{$IFDEF SYN_CLX}
begin
  Clipboard.AsText := SText;
end;
{$ELSE}
var
  Mem: HGLOBAL;
  P: PChar;
  SLen: integer;
  Failed: boolean;
  //###mod Copy to Clipboard as unicode
  Ptr: Pointer;
  W: WideString;
begin
  if SText <> '' then begin
    Failed := TRUE; // assume the worst.
    // Open and Close are the only TClipboard methods we use because TClipboard
    // is very hard (impossible) to work with if you want to put more than one
    // format on it at a time.
    Clipboard.Open;
    try
      // Clear anything already on the clipboard.
      EmptyClipboard;
      //###mod Copy to Clipboard as unicode
      // Put it on the clipboard as normal text format so it can be pasted into
      // things like notepad or Delphi.
      if Win32Platform = VER_PLATFORM_WIN32_NT then begin
        W:=SText;
        SLen := (Length(W) + 1) * 2;
        Mem := GlobalAlloc(GMEM_MOVEABLE+GMEM_DDESHARE, SLen);
        Ptr := GlobalLock(Mem);
        Move(PWideChar(W)^, Ptr^, SLen);
        GlobalUnlock(Mem);
        Failed :=  SetClipboardData(CF_UNICODETEXT, Mem) = 0;
      end
      else begin
        SLen := Length(SText);
        Mem := GlobalAlloc(GMEM_MOVEABLE or GMEM_DDESHARE, SLen + 1);
        if Mem <> 0 then begin
          P := GlobalLock(Mem);
          try
            if P <> nil then begin
              Move(PChar(SText)^, P^, SLen + 1);
              // Put it on the clipboard in text format
              Failed := SetClipboardData(CF_TEXT, Mem) = 0;
            end;
          finally
            GlobalUnlock(Mem);
          end;
        end;
      end;
      //###mod Copy to Clipboard as unicode
      // Don't free Mem!  It belongs to the clipboard now, and it will free it
      // when it is done with it.
      if not Failed then begin
...

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


Новичок



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

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



The Paint Problem with IndentGuides:
This is no fixed Code, only with my comments (<-->), that you see the problem:

Код
              OldColor := Canvas.Pen.Color; //<--> Yes you save the old Color
      
              if fHighlightedFoldRange <> fAllFoldRanges[i] then
                Canvas.Pen.Color := clGray
              else
                Canvas.Pen.Color := clRed; // <--> Here the color is set to red, if it is the current foldrange

              if X - ScrolledXBy > 0 then
              begin
                X := Gutter.RealGutterWidth(CharWidth) + X - ScrolledXBy;

                if Canvas.Pen.Color<>clGray then begin                      //###mod IndentGiudes change highlight
                  Canvas.Pen.Color := clGray;                               // <--> now you draw your "bold" line
                  Canvas.MoveTo(X, Y);                                      //
                  Canvas.LineTo(X, rcLine.Bottom);                          //
                  Canvas.Pen.Color := clBlack;                              // <--> and HERE is the mistake: you always set the color back to black, the decision of red or not red is destroyed
                end;                                                        //###mod IndentGiudes change highlight

                if LineHeight mod 2 = 0 then
                  while Y < rcLine.Bottom do
                  begin
                    Canvas.MoveTo(X, Y); //<--> now here draw all dotted lines, but in the current color, black instead of red or gray..
                    Inc(Y);
                    Canvas.LineTo(X, Y);
                    Inc(Y);
                  end
                else
                begin
                  if nLine mod 2 = 1 then
                    Inc(Y);
      
                  while Y < rcLine.Bottom do
                  begin
                    Canvas.MoveTo(X, Y); // <--> same
                    Inc(Y);
                    Canvas.LineTo(X, Y);
                    Inc(Y);
                  end;
                end;
              end;
      
              Canvas.Pen.Color := OldColor; // <--> Yes NOW you reset the oldcolor, but its only for code behind it, all IndentGuides are already drawed.


Solution would be, that you make the decision Red or not Red after your bold line.



And the fix for missing Update of foldranges, if keywords are case-sensitive:
Код
function TCustomSynEdit.IsKeywordAtCursorPos(OpenKeyWord: PBoolean): Boolean;
  function IsKeywordAtCursorPosForFoldRegions(OpenKeyWord: PBoolean;
...
      if not CodeFolding.CaseSensitive then
        Line := UpperCase(LineText)
      else
        Line := LineText; //<-->
...

Thats all.



Now i try to search the Copy/Cut-Problem.
PM MAIL   Вверх
Sep.
Дата 4.9.2006, 10:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата
Solution would be, that you make the decision Red or not Red after your bold line.

 Now i understand about what you say. =) I think that mod named "IndentGiudes change highlight" can change color too. =) Of course there can be backup of color done. But i use Black, if you need Red, you can change this in mod. If mod not instaleed then all by default. If there made backup of color, then mod need to rename to "IndentGiudes change highlight style" =) You think it's important? Then i will do it.
 
Цитата
fix for missing Update of foldranges, if keywords are case-sensitive

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


Новичок



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

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



Write your mod like this:

Canvas.Pen.Color := clGray || clRed; // if...
OldColor := Canvas.Pen.Color;
Canvas.Pen.Color := clGray;                               // mod..
Canvas.MoveTo(X, Y);                                      //
Canvas.LineTo(X, rcLine.Bottom);                          //
Canvas.Pen.Color := OldColor;                              //
...//draw guides


Then it should be what you want - a gray line behind the indent guide line.
I dont use the mod anyway. But you should do this in SynMix.






Copy-Problem:
Код
function TCustomSynEdit.GetSelText: string;
...
    case fActiveSelectionMode of
      smNormal:
        if (First = Last) then begin                                      
          ts := GetUncollapsedStrings;
          // step1: calculate total length of result string
          Inc(TotalLen, ColTo - ColFrom);
          if Length(ts[GetRealLineNumber(First+1)-1]) < ColTo then begin // Selection until line end -> Also get text from foldrange
            iLineCount := 1;
            for i := GetRealLineNumber(First+1) to GetRealLineNumber(Last+2)-2 do begin
              Inc(TotalLen, Length(TrimRight(ts[i])));
              Inc(iLineCount);
            end;
            Inc(TotalLen, Length(sLineBreak) * iLineCount);
          end;

          // step2: build up result string
          SetLength(Result, TotalLen);
          P := PChar(Result);
          CopyAndForward(TrimRight(ts[GetRealLineNumber(First+1)-1]), ColFrom, ColTo - ColFrom, P);
          if Length(ts[GetRealLineNumber(First+1)-1]) < ColTo then begin // Selection until line end -> Also get text from foldrange
            CopyAndForward(sLineBreak, 1, MaxInt, P);
            for i := GetRealLineNumber(First+1) to GetRealLineNumber(Last+2)-2 do begin
              CopyAndForward(TrimRight(ts[i]), 1, MaxInt, P);
              CopyAndForward(sLineBreak, 1, MaxInt, P);
            end;
          end;
          ts.Free;
        end else begin
...

Now he copy the foldrange, if you select until the last character of fold line (only then).


And also CutToClipboard copies the right text in clipboard, but dont delete fold range. I will fix this now.
Edit: One problem is, that Cut dont call CanExecuteInLine, so you can cut a hald line of collapsed fold range...




PS: I have problems with login in forum now. (logout every post) Is this my cookie-problem or is it a failure with the forum?




Edit: Cut-Problem solved with:

Код
procedure TSynEditCodeFoldingPlugin.LinesDeleted(FirstLine, Count: integer; AddToUndoList: Boolean);
var
  i: Integer;
  StartBC, EndBC: TBufferCoord;
begin
  if Count >= 0 then begin
    //###mod CF bugs
    StartBC.Line := 0; StartBC.Char := 0;
    EndBC.Line := 0; EndBC.Char := 0;
    for i := fOwner.fAllFoldRanges.AllCount - 1 downto 0 do
      if ( (Count <= 1) and (fOwner.fAllFoldRanges[i].FromLine = FirstLine) ) or
         ( (Count > 1) and (fOwner.fAllFoldRanges[i].FromLine >= FirstLine) and (fOwner.fAllFoldRanges[i].FromLine <= Pred(FirstLine+Count))) then
      begin
        if AddToUndoList then
          fOwner.fUndoList.AddChange(crDeleteCollapsedFold, StartBC, EndBC,
            '', fOwner.SelectionMode, fOwner.fAllFoldRanges[i], i);
        
        fOwner.fAllFoldRanges.Delete(i);
      end;

    fOwner.UpdateFoldRanges(FirstLine, -Count);
    fOwner.GutterChanged(fOwner);
    //###mod CF bugs
  end;
{$IFNDEF VER130} //###mod delphi5
  inherited;
{$ENDIF}
end;

He called the function, but didnt do something, because Count was 0 (sure if you select only from beginning to end of line). Now he deletes the fold correctly.

Remaining thing is that you are allowed to Cut something in a collapsed line. Delete is forbidden there, but cut works... Mmh.


Fix:
Код
procedure TCustomSynEdit.CutToClipboard;
begin
  if not ReadOnly and CanExecuteInLine(0) and SelAvail then
  begin
    BeginUndoBlock;
    try
      DoCopyToClipboard(SelText);
      SetSelTextExternal('');
    finally
      EndUndoBlock;
    end;
  end;
end;

But the call of CanExecute is maybe not really good there, if you call Cut on another way. But I have no idea where. Sure I can forbid it in SetSelTextExternal, but then the text was already copied, so i only forbid the half thing. 

PS: I had again login into forum, what is the problem.

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


Шустрый
*


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

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



Цитата
Write your mod like this:

I can't reuse OldColor because it already holds color. I rewrite with other variable.
Цитата
 guide

One more bug fixed =)

When i press hotkey, it converts it to ComandProcessor word and then there is case:
Код
      ecCut:
        begin
          if (not ReadOnly) and SelAvail then
            CutToClipboard;
        end;
      ecCopy:
        begin
          CopyToClipboard;
        end;
      ecPaste:
        begin
          if not ReadOnly then PasteFromClipboard;
        end;

So it run CopyToClipboard from everywhere. This all ok, i miss it. 
But there some bug in your new code that you mail me: =(
When i select string from start to end and press Ctrl-C then i have drop of current foldrange. It copyes to buffer ok, and i can press Ctrl-Z to return it back.
Ctrl-X works ok in that case.
I can send compiled version to you. Again Delphi5 case?

OFF:
Цитата
I have problems with login in forum now

What browser do you use? I have problems with post messages under Opera9, it have no button 'Send' for me. Under IE all ok. There many users have this bug, it posted in support topic on this forum. But i cant see topic about login problems. May be some cookie problem, untrusted site e.t.c.
--------------------
Syn - TotalCommander lister plugin |  SynTree - coders sourcebook  
PM MAIL   Вверх
DavidCl0nel
Дата 5.9.2006, 09:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Good, now I changed the Case as like the other:
Код

      ecCut:
        begin
          if (not ReadOnly) and (CanExecuteInLine(0)) and SelAvail then
            CutToClipboard;
        end;

Maybe he called CanExecuteInLine now 2 times, here and after that in CutToClipboard, but there are the two ways to get there - i cant remove one i think.

The same here:
Код

procedure TCustomSynEdit.WMCut(var Message: TMessage);
begin
  if not ReadOnly and CanExecuteInLine(0) then
    CutToClipboard;
  Message.Result := ord(True);
end;


I dont know, when this is called with Windows-message, but it had to check this CanExecuteInLine first, that I can only cut a foldrange if I select it from begin to end of line, not half text. For safety. ;)


>>When i select string from start to end and press Ctrl-C then i have drop of current foldrange. It copyes to buffer ok, and i can press Ctrl-Z to return it back.
It works perfectly here. I dont know what the problem is... Can you debug the case, where he update the foldrange? Breakpoints on LinesDeleted(), UpdateFoldRanges(), etc... He shouldn't call this functions, if it isn't needed...
Is this the last bug or do you have something else I dont have. I dont know, if you have solved the other ore if they disappear silently with other updates?


>>What browser do you use? 
Maxthon, but it is only a kind of browser enhancement (tabbing and such things), the main (parsing, drawing...) is IE6 in there. He 2 times delete or dont accept my login-cookie (only on this site here!) and i lost 2 posts with a error-message (russian, i cant read - but i think it was "you had to logon first, you idiot"). Back and my post text was away, but i have saved it in clipboard.
Now, one day after last login, i am already logged in, so the problem is away.



Edit: Found a new Bug smile
If you delete a line with Ctrl+Y (Standard Keystroke), he don't update foldranges and Undobuffer.... Grmpf.

EditEdit:
Not exactly, Ctrl+Y was assigned in my MainMenu that called SynMemo.Lines.Delete(...). If I use the Ctrl+Y from Keystroke he delete also correctly, updates the Undobuffer but move only the foldrange (i have destroyed it really with my delete). But i will look at it now.

EditEditEdit:

Код

procedure TCustomSynEdit.DoOnCommandProcessed(Command: TSynEditorCommand;
  AChar: char; Data: pointer);
begin
  //### Code Folding ###
  if CodeFolding.Enabled then
    if (fNeedToReScan)
    or (Command = ecCut)
    or (Command = ecPaste)
    or (Command = ecUndo)
    or (Command = ecRedo)
    or (((Command = ecChar) or (Command = ecDeleteLastChar)) and (IsKeywordAtCursorPos))
    or (Command = ecDeleteLine) then begin
      ReScanForFoldRanges;
      if CodeFolding.IndentGuides then Repaint;
    end;


Now it updates all ok. A little thing left: I have in my Editor MainMenu an Undo, that you can click it there or see the ShortCut for Undo. If I call Undo on this way he dont restore the foldrange, if I delete the line with keyword like above. If I dont assign the ShortCut in MainMenu, the pressed shortcut goes to SynMemo directly and then he restore the foldrange.
There I had to think about it. An user of the Editor should see the ShortCuts he dont know and had to call the function by clicking in the Menu.... Hmm.

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


Шустрый
*


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

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



Цитата
Maybe he called CanExecuteInLine now 2 times, here and after that in CutToClipboard, but there are the two ways to get there - i cant remove one i think.

Why do you think so? Case executing CutToClipboard and there you check CanExecuteInLine. No need to change ecCut case and WMCut. You allway go to CutToClipboard. There is already two checks for ReadOnly.
Цитата
Breakpoints on LinesDeleted(), UpdateFoldRanges(), 

Checked, it don't run this functions. Drop is somewhere else, i'll try to get D7 and check under it. Can you say what difference beetwen D5 and BDS2006? So i know what to check first.
Цитата
Ctrl+Y was assigned in my MainMenu that called SynMemo.Lines.Delete(...)

you need to make assigns to SynEdit.Keystrokes, and read them as hotkeys in menu. I already do this in my prog, and make patch when Key:=0. =)
Цитата
TCustomSynEdit.DoOnCommandProcessed

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


Новичок



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

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



>>You allway go to CutToClipboard
Ok, then I will remove the extra check.

>>Can you say what difference beetwen D5 and BDS2006?
Delphi5 is very old, i know - but it is an stable release. I dont work with BD2006 very good (i test it short - i dont find the things like i want. Placing components, where are the windows etc ;) Its difficult to go to the new gui). With Delphi7 Borland decided to make Pascal more innocent from operating system - so the whole Q-thing (QSynEdit.pas and all common delphi functions in QForm, Q..) for Kylix is new under Delphi7. Also the quite common internet-controls from Indy was first built in Delphi7 I think. And many little things are different (do you remember my TList.Assign? Delphi5 hasnt it... and i think there are a lot of more such things). So it isnt very simple to say that. ;) I dont know what is the matter with your folddrops that i dont have...



>>you need to make assigns to SynEdit.Keystrokes, and read them as hotkeys in menu. I already do this in my prog, and make patch when Key:=0
Ctrl+Y is the default keystroke for Delete-Line, if i dont assign my shortcut to mainmenu he automatically call it in syn and it works. But i want to show the shortcut and give the possibility to call the function via mainmenu so i had to set a shortcut there. Or how is it possible to call the keystroke-function in my mainmenu.onclick-procedure?
PM MAIL   Вверх
Sep.
Дата 7.9.2006, 09:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата

how is it possible to call the keystroke-function in my mainmenu.onclick-procedure?

See code for TCustomSynEdit.TranslateKeyCode that executes from TCustomSynEdit.KeyDown. It converts key to CommandProcessor word. So you have two ways:
1. call KeyDown with hotkey for this command: KeyDown(ord('Z'), [ssCtrl]); for example for undo
2. direct call needed command for this menu item : synedit.CommandProcessor(ecUndo, #0, nil);

Left bugs in synMix:
1. Wrong gutter calculation when gutter font differs from text font (CharWidth var)
2. Wrong gutter width calculation when gutter.AutoSize enabled and you fold some text. (End line has number >100 but gutter has width for 2 digits only)
3. Codefolding ranges searched in comments and "strings". Need to make workaround like in MatchBracket, but it'll work only for SynUniHL. I tryed, but can't =(

Added:
Ok bug 2 fixed:
SynEditMiscClasses.pas
Код

fAutoSizeDigitCount: integer; // need move to public section

SynEdit.pas
Код

function TCustomSynEdit.GetAutoSizeDigitCount: Integer;
begin
    Result := gutter.fAutoSizeDigitCount; //Length(IntToStr(Lines.Count)); //###mod GutterAutoSize calc

  if Result < 2 then
    Result := 2;
end;

Код

procedure TCustomSynEdit.LinesChanged(Sender: TObject);
var
  vOldMode: TSynSelectionMode;
  i, j: integer;     //###mod GutterAutoSize calc
begin
  Exclude(fStateFlags, sfLinesChanging);
  if HandleAllocated then
  begin
    UpdateScrollBars;
    vOldMode := fActiveSelectionMode;
    SetBlockBegin(CaretXY);
    fActiveSelectionMode := vOldMode;
    InvalidateRect(fInvalidateRect, False);
    FillChar(fInvalidateRect, SizeOf(TRect), 0);
    if fGutter.ShowLineNumbers and fGutter.AutoSize then begin                       //###mod GutterAutoSize calc
      j:=Lines.Count;                                                                //
      for i:=0 to fAllFoldRanges.allCount-1 do                                       //
      if fAllFoldRanges[i].Collapsed then inc(j, fAllFoldRanges[i].LinesCollapsed+1);//
      fGutter.AutoSizeDigitCount(j);                                                 //###mod GutterAutoSize calc
      //fGutter.AutoSizeDigitCount(Lines.Count);
    end;
    if not (eoScrollPastEof in Options) then
      TopLine := TopLine;
    if WordWrap then fWordWrapPlugin.Reset; //###mod wordwrap
  end;
end;

Код

procedure TCustomSynEdit.GutterChanged(Sender: TObject);
var
  nW: integer;
  i,j: integer;    //###mod GutterAutoSize calc
begin
  if not (csLoading in ComponentState) then
  begin
    if fGutter.ShowLineNumbers and fGutter.AutoSize then begin                       //###mod GutterAutoSize calc
      j:=Lines.Count;                                                                //
      for i:=0 to fAllFoldRanges.allCount-1 do                                       //
      if fAllFoldRanges[i].Collapsed then inc(j, fAllFoldRanges[i].LinesCollapsed+1);//
      fGutter.AutoSizeDigitCount(j);                                                 //###mod GutterAutoSize calc
 //     fGutter.AutoSizeDigitCount(Lines.Count);
    end;
    if fGutter.UseFontStyle then
...

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


Шустрый
*


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

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



Now i fixed bug 1 ! =)
But there too many small changes in code to post on forum. I'll release it next SynMix, or can mail to you if you wish to test.

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


Новичок



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

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



>>direct call needed command for this menu item : synedit.CommandProcessor(ecUndo, #0, nil);
Thats a good idea. Now I use it that way. First possibility is bad, because you need an extra assignment for your shortcut. (If you change it, ...)

>>Left bugs in synMix:
>>1. Wrong gutter calculation when gutter font differs from text font (CharWidth var)
>>2. Wrong gutter width calculation when gutter.AutoSize enabled and you fold some text. (End line has number >100 but gutter has width for 2 digits only)
>>3. Codefolding ranges searched in comments and "strings". Need to make workaround like in MatchBracket, but it'll work only for SynUniHL. I tryed, but can't =(


-> 1.) Ok, but i think a very low priority. My first tries to do that shows, that it isnt as simple as it looks like.

-> 2.) Ok.

-> 3.) Hmm yes, but so you had to know, what a String or a Comment is. So you had to work with your highlighter... But the type for "String" or "Comment" can be named like you want in Highlighter... It looks very difficult.



4. I found an other little thing, try to check, if you have the same. If you select the first line of a fold (with the keyword) and delete the line, the foldrange isnt remove. If you select 2 lines, it works. It looks like the problem, that he dont call LinesDeleted now. I search for it, if I have time for it.

Edit: It had fixed, that he dont call UpdateFoldRanges with zero lines. This If consists the GutterChanged-Call, so he delete it correctly, but dont redraw the gutter, so the end-marker of fold range was visible.
Complete function is now:
Код
procedure TSynEditCodeFoldingPlugin.LinesDeleted(FirstLine, Count: integer; AddToUndoList: Boolean);
var
  i: Integer;
  StartBC, EndBC: TBufferCoord;
begin
  if Count >= 0 then begin
    //###mod CF bugs
    StartBC.Line := 0; StartBC.Char := 0;
    EndBC.Line := 0; EndBC.Char := 0;
    for i := fOwner.fAllFoldRanges.AllCount - 1 downto 0 do
      if ( (Count <= 1) and (fOwner.fAllFoldRanges[i].FromLine = FirstLine) ) or
         ( (Count > 1) and (fOwner.fAllFoldRanges[i].FromLine >= FirstLine) and (fOwner.fAllFoldRanges[i].FromLine <= Pred(FirstLine+Count))) then
      begin
        if AddToUndoList then
          fOwner.fUndoList.AddChange(crDeleteCollapsedFold, StartBC, EndBC,
            '', fOwner.SelectionMode, fOwner.fAllFoldRanges[i], i);
        
        fOwner.fAllFoldRanges.Delete(i);
      end;
    //###mod CF bugs
  end;
  
  if Count > 0 then fOwner.UpdateFoldRanges(FirstLine, -Count);
  fOwner.GutterChanged(fOwner);
{$IFNDEF VER130} //###mod delphi5
  inherited;
{$ENDIF}
end;

Now also the Variable for Undo position (they arent needed..) set to zero insted of put random numbers in this array. If you debug later, you aren't confused by that.

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


Шустрый
*


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

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



Mail from Guru Kathiresan:
Цитата

Hi,
I found a bug in latest synMix code.

In synedit.pas (Line : 10871)( function TCustomSynEdit.GetWordAtRowCol(XY:
TBufferCoord): string;):

if (XY.Char >= 1) and (XY.Char <= Len + 1) and (Line[XY.Char] in IdChars)
then

We check if XY.Char is <= (Len +1) and Len is the Max number of chars in
length of the Lines[XY.Line - 1]; Since we check XY.Char for Len +1 this
value can be 1 char more than the length of the line and when used in
Line[XY.Char] will throw array out of bound exception.

I couldn't understand the Russian language to register myself in the board
to post this patch. That's the reason I'm sending this mail.

-regards,
Guru

ok, but i never see this exception
--------------------
Syn - TotalCommander lister plugin |  SynTree - coders sourcebook  
PM MAIL   Вверх
DavidCl0nel
Дата 7.9.2006, 13:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Normally this Code isnt executed.

I call this Function now with an extra button for an character at end of line. If I set the correct position, he copy it correctly, if i set the position to one behind, he crashs with exception. So he is right.
Fix is the +1
Код
    if (XY.Char >= 1) and (XY.Char <= Len) and (Line[XY.Char] in IdChars) then




I try 3. now, but i have a question. You have your keywords for foldranges in your Highlighter. Where and how you set it in your Highlighter-component? In constructor TSynYourHighlighterNameSyn.Create(AOwner: TComponent)? Or where? I set my foldranges in my program, not in the highlighter, but if it possible, i would move it in Highlighter. In the Highlighter you have the information about Strings and Comments, so it is more easy.
There is a possibility to define SkipRegions for FoldRanges, maybe we should write something in there, that he dont look for skipregions in comments.


Edit:
After my keywords for CodeFolding i do that:
Код
    FoldRegions.Add(rtKeyWord, False, False, True, 'If', 'EndIf');
    FoldRegions.SkipRegions.Add('/*', '*/', '', itMultiLineComment);
    FoldRegions.SkipRegions.Add('"', '"', '', itString);
    FoldRegions.SkipRegions.Add('//', '', '', itSingleLineComment);

So now I can comment a keyword, but i had to force Update of CodeFolding (destroy another keyword, that he knows he must update). After this update he removed the commented foldregion.

But with this I got an exception after closing the program in SynTextDrawe.pas: TheFontsInfoManager.ReleaseFontsInfo().
Dont know what and why.




Some other little thing. I fall back to the old one:
Код
function TCustomSynEdit.IsKeywordAtCursorPos(OpenKeyWord: PBoolean): Boolean;
...
      Keyword := FoldRegions[i].Open;
  
      repeat
        P := Pos(Keyword, Line);
  
        if (P > 0) and ((CaretX >= P)
        and (CaretX <= P + Integer( StrLen(Keyword) ))) then // Cast to Integer type to shut up the compiler
...

Earlier P was changed, if KeyWordClose is in there. It was needed for Drawing the IndentGuides in the other color. This isnt work correctly, so i return it to the old behavior.

Код
procedure TCustomSynEdit.DoOnCommandProcessed(Command: TSynEditorCommand;
...
  if CodeFolding.IndentGuides then begin
    case Command of
      ecCut, ecPaste, ecUndo, ecRedo, ecDeleteLastChar, ecDeleteChar:
        CheckIfAtMatchingKeywords;
    end;
    Repaint; //Repaint because IndentGuides-Color can be changed with cursor position
  end;
...


And the main change is in Paint-procedure.
Код

  procedure PaintLines;
...
              if not((BlockBegin.Line >= fAllFoldRanges[i].FromLine) and (BlockBegin.Line <= fAllFoldRanges[i].ToLine)) then
                Canvas.Pen.Color := clGray
              else
                Canvas.Pen.Color := clRed;
...

Now it checks the lines, not the other Variable, that wasnt set correctly by IsKeywordAtCursorPos(). Now I can move the cursor through the text and got, if the cursor is between a open and a close keyword, the right color line.



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


Шустрый
*


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

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



Цитата
Where and how you set it in your Highlighter-component?

I don't know, i simply use SynUniHL and it has support of CodeFoldingRanges. Vitalik is developer of component, he can say more. There is rule for naming styles in *.hgl files, Comment styles must start from 'comment' or 'remark' (For example 'Comment /*...*/') String styles must have names starting as 'string'. So i need do GetHighlighterAttriAtRowCol and check attri.Name. This is temporaly, we want to make normal string/comment check for styles. It need to some update SynUniHL for that.
I make same workaround for bug3 as in MatchBracket. It works ok for rtChar, but very slow for rtKeyWord type foldranges. Now i comment code for rtKeyWord, only left rtChar (php, C, java : {}) Need to make needed changes in SynUniHL first...
Цитата
There is a possibility to define SkipRegions for FoldRanges

Yes i try to use it, but there no support of it in SynUniHL. I can't use hadcoded skipregions now. Error is because of wrong memory free in TSkipRegionItem.Destroy() i think
Цитата
but i had to force Update of CodeFolding 

Yes, i need to do it too, in my workaround. Need to think how to run auto-updating in this case.
Цитата
Some other little thing.

ok
Цитата
DoOnCommandProcessed

But there is already 
Код

      ReScanForFoldRanges;
      if CodeFolding.IndentGuides then Repaint;
 in couple of lines before. What your full version of DoOnCommandProcessed?
Цитата
And the main change is in Paint-procedure.

Cool! But don't work fully as expected. It need to do many invalidateLines. When i move cursor inside foldrange, it paint highlighted indentguide only for line at cursor. If cursor near foldrange keyword - then it paints full current indentguide correctly, but if move cursor to other foldrange - it don't repaint old indentguide as non-highlighted =(
--------------------
Syn - TotalCommander lister plugin |  SynTree - coders sourcebook  
PM MAIL   Вверх
DavidCl0nel
Дата 7.9.2006, 19:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



>>I make same workaround 
Show me, if it looks good.

>>in couple of lines before
Yes, but only for ecDeleteLine. But it isnt needed then, you are right. And if you move cursor you dont DeleteLine, but you had to repaint it, so i repaint it every time. Try it and say me, if your "But don't work fully as expected" still exists. ;)

Hmm, it doesnt work for clicks correctly, maybe you mean this. If you move cursor with up/down/pageup/etc it repaint it every key and works good.


Код
procedure TCustomSynEdit.DoOnCommandProcessed(Command: TSynEditorCommand;
  AChar: char; Data: pointer);
begin
  //### Code Folding ###
  if CodeFolding.Enabled then
    if (fNeedToReScan)
    or (Command = ecCut)
    or (Command = ecPaste)
    or (Command = ecUndo)
    or (Command = ecRedo)
    or (((Command = ecChar) or (Command = ecDeleteLastChar)) and (IsKeywordAtCursorPos))
    or (Command = ecDeleteLine) then begin
      ReScanForFoldRanges;
    end;
      
  if CodeFolding.IndentGuides then begin
    case Command of
      ecCut, ecPaste, ecUndo, ecRedo, ecDeleteLastChar, ecDeleteChar:
        CheckIfAtMatchingKeywords;
    end;
    Repaint; //Repaint because IndentGuides-Color can be changed with cursor position
  end;
  //### End Code Folding ###
 
  if Assigned(fOnCommandProcessed) then
    fOnCommandProcessed(Self, Command, AChar, Data);
end;


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


Шустрый
*


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

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



Цитата
Show me, if it looks good.

 ok, time to some synchronize changes.
 SinMix update 7/09/06
 
  • //###mod bug with onGutterClick
     Sometimes onGutterClick doesn't been called
     
  • //###mod Copy to Clipboard as unicode
     Will copy text as unicode if possible.
     
  • //###mod IndentGuides change highlight style
     Don't forget selected highlight color now
     
  • //###mod missed for CaseSensitive
     missed code for work with CaseSesitive CF-ranges
     
  • //###mod GutterAutoSize calc
     Wrong calc of GutterWidth when collapse lines
     
  • //###mod gutter font
     Wrong calculations of gutter when gutter font differs from text font
     
  • //###mod access violation
     Sometimes AV in GetWordAtRowCol
     
  • //###mod CF-range in comments
     Don't search foldranges in strings/comments. This mod is slow now and commented by default. Works only with SynUniHL and proper hgl file.
     
  • //###mod highlight current IndentGuide
     Highlight indentguide when cursor inside it.
     
  • small fixes when Copy/Cut/Undo/Redo collapsed lines
     
  • small fixes in //###mod wrong place of hint over [...]
 
 I've some update 'mod highlight current IndentGuide' so it works with mouse clicks too. It will be great if it highlights only most deeper indentguide, when there are couple of foldranges one inside other.
 For 'mod CF-range in comments' you can use SkipRegions, I'll wait SynUniHL update. For write more faster mod. Need to think how auto-update foldregions when write comment.
--------------------
Syn - TotalCommander lister plugin |  SynTree - coders sourcebook  
PM MAIL   Вверх
Sep.
Дата 8.9.2006, 18:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Mod for highlighting current foldrange looks good, but there too many Repaint calls. If i typing quick, CPU load go up to 40%, and there visual flashing, when press Up or Down. So i decided to write new function, that will repaint only IndentGuides. Now i have 20% load (including statusbar update) and no flashing. And i implement highlighting only for deepest indentguide too.
But there is problem - when i close window, i get AV. I think it because of calling to RepaintGuides when component already destoyed. Is there any standart way to know about destroying?
There is the mod, changes temporary marked as //sepa:
SynEdit.pas
Код

    procedure PaintTextLines(AClip: TRect; const aFirstRow, aLastRow,
      FirstCol, LastCol: integer); virtual;
    procedure PaintGuides(nLine,cRow,ScrolledXBy: integer; rcLine: TRect); //sepa
    procedure RepaintGuides; //sepa
    procedure RecalcCharExtent;

PaintLines
Код

...
        //### Code Folding ###
        // Indent guides painting
        PaintGuides(nLine, cRow, ScrolledXBy, rcLine);//sepa

        {if Length(IndentGuides[nLine - 1]) > 0 then
          begin
...

add to any part of file
Код

procedure TCustomSynEdit.PaintGuides(nLine,cRow,ScrolledXBy: integer; rcLine: TRect);
var
  OldColor,tmpColor: TColor;
  i,j,X,Y,L: integer;
begin
  OldColor := Canvas.Pen.Color;
  L:=0;
  if (CodeFolding.Enabled) and (CodeFolding.IndentGuides) and ((cRow = 1)
  or (RowToLine(cRow) <> RowToLine(cRow - 1))) then begin
    //search deepest foldrange
    for i := fAllFoldRanges.AllCount - 1 downto 0 do
    if (fAllFoldRanges[i].Level > L)and
       (CaretY >= fAllFoldRanges[i].FromLine)and
       (CaretY <= fAllFoldRanges[i].ToLine)
    then
       L:=fAllFoldRanges[i].Level;

    //paint loop
    for i := 0 to fAllFoldRanges.AllCount - 1 do
    with fAllFoldRanges[i] do
      if (not Collapsed) and (not ParentCollapsed)
      and (FromLine < nLine) and (ToLine > nLine) then
      begin
        Y := rcLine.Top;
        X := GetLineIndentChars(Self.Lines, FromLine-1)* CharWidth; //Level * CharWidth * TabWidth;  //###mod IndentGuides calculation fix

        //if fHighlightedFoldRange <> fAllFoldRanges[i] then
        //###mod highlight current IndentGuide
        if (L=Level)and
           (CaretY >= FromLine)and
           (CaretY <= ToLine)
        then Canvas.Pen.Color := clBlack //higlighted
        else Canvas.Pen.Color := clGray;
        //###mod highlight current IndentGuide

        if X - ScrolledXBy > 0 then
        begin
          X := Gutter.RealGutterWidth(Gutter.CharWidth) + X - ScrolledXBy;

          tmpColor := Canvas.Pen.Color;
          if Canvas.Pen.Color=clGray then Canvas.Pen.Color := clWindow
          else Canvas.Pen.Color := rgb(160,160,255); //highlighted color
          Canvas.MoveTo(X, Y);
          Canvas.LineTo(X, rcLine.Bottom);
          Canvas.Pen.Color := tmpColor;

          if LineHeight mod 2 = 0 then
            while Y < rcLine.Bottom do
            begin
              Canvas.MoveTo(X, Y);
              Inc(Y);
              Canvas.LineTo(X, Y);
              Inc(Y);
            end
          else
          begin
            if nLine mod 2 = 1 then
              Inc(Y);

            while Y < rcLine.Bottom do
            begin
              Canvas.MoveTo(X, Y);
              Inc(Y);
              Canvas.LineTo(X, Y);
              Inc(Y);
            end;
          end;
        end;

      end; //paint loop
  end;//if codefolding
  Canvas.Pen.Color := OldColor;
end;

procedure TCustomSynEdit.RepaintGuides;
var
  nLine,cRow,ScrolledXBy: integer;
  rcLine: TRect;
begin
   try
    HideCaret;
    rcLine.Left:=Gutter.RealGutterWidth(Gutter.CharWidth);
    rcLine.Right:=rcLine.Left+CharsInWindow*CharWidth;
    rcLine.Top:=0;
    rcLine.Bottom:=fTextHeight;
    ScrolledXBy:=(LeftChar-1)*CharWidth;
    for nLine:=RowToLine(TopLine) to RowToLine(TopLine)+LinesInWindow do begin
      for cRow := LineToRow(nLine) to LineToRow(nLine+1) -1 do begin
        PaintGuides(nLine,cRow,ScrolledXBy,rcLine);
        rcLine.Top:=rcLine.Bottom;
        inc(rcLine.Bottom, fTextHeight);
      end;
    end;
   finally
     UpdateCaret;
   end;
end;

and change calls to new procedure
TCustomSynEdit.MouseDown
Код

...
    DoOnGutterClick(Button, X, Y)
  end
  else RepaintGuides; //###mod highlight current IndentGuide
  SetFocus;
{$IFNDEF SYN_CLX}
...

DoOnCommandProcessed
Код

...
  if CodeFolding.IndentGuides then begin
    case Command of
      ecCut, ecPaste, ecUndo, ecRedo, ecDeleteLastChar, ecDeleteChar:
        CheckIfAtMatchingKeywords;
    end;
    RepaintGuides; //###mod highlight current IndentGuide
  end;
  //### End Code Folding ###
...

Have you such bug here? If i add exit; to start of TCustomSynEdit.RepaintGuides; then bug moves away.
--------------------
Syn - TotalCommander lister plugin |  SynTree - coders sourcebook  
PM MAIL   Вверх
Seldon
Дата 8.9.2006, 20:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(Sep. @  8.9.2006,  18:27 Найти цитируемый пост)
Is there any standart way to know about destroying?

Код

if csDestroying in ComponentState then

--------------------
MiBEditor v2.Alpha 10 - Программерский редактор
PM MAIL WWW   Вверх
Sep.
Дата 8.9.2006, 20:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



2Seldon
Thanx! Works ok now if i use
Код

procedure TCustomSynEdit.RepaintGuides;
var
  nLine,cRow,ScrolledXBy: integer;
  rcLine: TRect;
begin
   if csDestroying in ComponentState then exit;
   try
    HideCaret;
...

But i found other way =)
TCustomSynEdit.DoOnCommandProcessed
Код

  if CodeFolding.IndentGuides then begin
    case Command of
      ecCut, ecPaste, ecUndo, ecRedo, ecDeleteLastChar, ecDeleteChar:
        CheckIfAtMatchingKeywords;
      ecUp, ecDown, ecPageUp, ecPageDown, ecPageTop, ecPageBottom,
      ecEditorTop, ecEditorBottom, ecGotoXY:
        RepaintGuides;  //###mod highlight current IndentGuide
    end;
  end;
  //### End Code Folding ###

So it repaint indent guides only when needed. I think it more optimized version.
--------------------
Syn - TotalCommander lister plugin |  SynTree - coders sourcebook  
PM MAIL   Вверх
DavidCl0nel
Дата 10.9.2006, 12:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



>>ecUp, ecDown, ecPageUp, ecPageDown, ecPageTop, ecPageBottom,
>>ecEditorTop, ecEditorBottom, ecGotoXY:
>>   RepaintGuides; 

Then you should have problems, if you move the cursor by clicking somewhere.... Then it isnt Updated. Or is ecGotoXY used, if you click?

I test your PaintGuides Monday. smile


Код
tmpColor := Canvas.Pen.Color;
          if Canvas.Pen.Color=clGray then Canvas.Pen.Color := clWindow
          else Canvas.Pen.Color := rgb(160,160,255); //highlighted color
          Canvas.MoveTo(X, Y);
          Canvas.LineTo(X, rcLine.Bottom);
          Canvas.Pen.Color := tmpColor;

This is your new "bold" guide-code? Why you set it to clWindow? You draw it then white? Why? 
PM MAIL   Вверх
Sep.
Дата 11.9.2006, 06:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата
Then you should have problems, if you move the cursor by clicking somewhere

Why? I use call to RepaintGuide from TCustomSynEdit.MouseDown, so all clicks are hooked.
Цитата
This is your new "bold" guide-code? Why you set it to clWindow? You draw it then white? Why? 

Now i repaint guides without repainting window. So if i use BG color when paint highlight line, then i need use BG color when i paint non-highlighted line or there will left non-repainted pixels. I select for highlighting - clBlack dots on light-blue BG, for normal - clGray dots on clWindow BG. You can disable this part of code, and only dots left, without any BG.
--------------------
Syn - TotalCommander lister plugin |  SynTree - coders sourcebook  
PM MAIL   Вверх
DavidCl0nel
Дата 11.9.2006, 10:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Ah, I see. I try your code, but have a problem now

Код
X := Gutter.RealGutterWidth(Gutter.CharWidth) + X - ScrolledXBy;

In both new functions he don't know Gutter.CharWidth.

I replaced it with only CharWidth
Код
X := Gutter.RealGutterWidth(CharWidth) + X - ScrolledXBy;

and this works.

Edit: While merging the source with SynMix I see your changes in SynEditMiscClasses. Now it works.

And I changed the code to my own style (red=highlightet, other=grey dots). But it is a better way to redraw now, even tough I dont have such cpu loads while typing. Do you have an old computer? Never mind, it works good now.




Last problem is the Gutter hiding the folding marks if you have a really big font size.
Edit: No you solved it, but the problem with folding keywords in strings and comments is unsolved yet.


Some other things while Merging:
- I dont use it, but what are your changes with SynRegExpr?
- I see your changes in comments in ScanForFoldRanges. It doesn't work yet, right? Uncommenting looks like no change in this behaviour.
- I have definitely delete some code in comments. It is very old sometimes (like the IndentGuides-thing with FreeMem at the end with your AV, you remember). Or my complete new GetSelText has in your code the old version in comments. Or the Bitmap-function that isnt needed or called somewhere. All these things shouldnt work, even if you try to uncomment it. This only confusing a other programmer now. At the end of day i send my source and it should be nearly the same (only my little other wishes "red guides" and my problem with the [...]-sign) should be the difference. It makes it more easy to merge in later versions, if we dont stumble every time over this things.




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


Шустрый
*


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

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



can I with current codefolding engine do such thing:
user select text, launch some command and selected text become folding region?
--------------------
MiBEditor v2.Alpha 10 - Программерский редактор
PM MAIL WWW   Вверх
DavidCl0nel
Дата 12.9.2006, 10:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Answer from mail:

>>I've found that you have:
>>i mean that:
>>look at ending comments.

Right, i have changed it. But for my case it was not important, because i have fold ranges in Keywords, so he is only in the second case-branch.

>>Your solution for KeyDown better than nothing. Post it on forum and we
>>all will think about it =)

It was
Код

procedure TCustomSynEdit.KeyDown(var Key: Word; Shift: TShiftState);
...
  if (ssShift in Shift) and ((Key = 50 {2}) or (Key = 55 {7})) then
    ScanForFoldRanges(fAllFoldRanges, Lines);  
end;

...and it didn't work correctly. It was at the end of the KeyDown, so CommandProcessor has add the character to memo, and I can see it in DebugMode in Lines, but he didn't scan correctly and delete the fold range smile. And the if clause is region-specific, my " is on Shift+2 and / on Shift+7. On other keyboard layouts this wouldn't work. It was only a "hard" try and it didnt work, so we need a better check.

The real procedure from you that he ignore keywords in " or / works, but you have to force the update (like destroy and restore an other keyword), that he handle the other keywords.
Maybe the "CheckIfAtMatchingKeywords" should be changed to work vor whole lines, but it wouldn't work for multiline comments then. Hmm Hmm.



>>And good news for you and other non-russian ppl. Administration are
>>working on translate forum to english. There new sub-forum for SynEdit
>>& SynUniHL on english. Look here if you can't find our thread.
>>http://forum.vingrad.ru/index.php?showforum=255
>>And you can switch language of forum in your user panel, i can say
>>where you need to press. Or look thru online translator.

Weeeh smile It works good now, some of my profile i could change, but there are some other russian words on some places, but it is more easy to handle it now. So I dont need Babylon as much as before. ;)




>>user select text, launch some command and selected text become folding region?
That is no part of the code folding. But I think you can solve it with the other SynMemo-Helper-Controls. Syn has the possibility to AutoComplete text. In Delphi IDE you can for example type "cases" and press Ctrl+J and he replace the word with
Код
    case  of
      : ;
      : ;
    end;

This is also possible to do this with Syn. I haven't work with this, so I have no idea how to exactly do this, but you can download the "real" SynEdit-source code. There are many examples and one is for this AutoComplete. I have tried it only as an user, I haven't engaged how to do this.

But with this you can create such regions by adding the second keyword (and the other part of the code block) with AutoComplete. Then he had to reparse the content and automatically draw foldregions.


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


Шустрый
*


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

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



no-no smile
user selects text, and he wants it as folding region, i.e. he wants collapse\uncollapse lines that he selected.
Sorry for my bad English  smile Maybe Sep write my question smile I describe him  in Russian what I whant.
--------------------
MiBEditor v2.Alpha 10 - Программерский редактор
PM MAIL WWW   Вверх
DavidCl0nel
Дата 12.9.2006, 13:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



My english isn't very good too. ;)

Hmm, you want to fold your current selection (independent from all code folding keywords)? That wouldn't be easy.

I could imagine, that you can add the selection text as an foldregion, so he can parse and find this, so you can fold it.
But what the Memo should do, if your selection isn't unique? If you select a block what occur also later in the text? Should it be also possible to fold this? If you add the region he will find this block also.
What is, if you dont want to fold this block or if you edit it, so he can't find the text for foldrange? Maybe then you have add another time the similar (edited) block.
And this foldranges (that he should fold exactly this text) can't saved somewhere.

It's difficult..





Edit: The / " forced rescan can be (needs much cpu i know, but it works...) done in KeyPress.
Код
procedure TCustomSynEdit.KeyPress(var Key: Char);
...
  Rescanforfoldranges;
end;


It is very bad to scan every character you type, but it works to see, that your other procedure works good. But If you remove a charakter with backspace he don't call this procedure, so you had to type an other character to restore the foldrange.
Now we need a little bit more intelligence there...

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


Шустрый
*


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

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



Цитата

user selects text, and he wants it as folding region, i.e. he wants collapse\uncollapse lines that he selected.

I think it need to write new procedure in TSynEdit, which simply adds selected text in fFoldRanges but this text will be deleted on next RescanForFoldRanges. So may be it need to add new UserFoldRanges array and add it on each Rescan. I think it isn't so difficult to implement, but have no free time those couple of days =( I'll look for it when have some time, but may be someone implement it faster and better than i =)
Цитата

but there are some other russian words on some places,

Administaration working on this, they wants totally reorganize forum =)

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


Новичок



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

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



2 things...


>>but this text will be deleted on next RescanForFoldRanges

At the moment I call it every time in TCustomSynEdit.LinesChanged at the end of procedure. All other KeyDown/KeyPress or such things aren't called everytime. The Delete-Key (not Backspace) wasn't handled by KeyPress... It make some cpu usage, if now always rescan, but if I hold a key down and he adds permanently characters into the memo i got only cpu usage < 10%, and that is not a problem I think.

But I have found a little problem with your Scan-workaround that i use. It has a problem, if you collapse a block above. Some other foldranges after the collapsed foldrange (i have no idea what and why this foldranges) were removed. Do you have this problem too?





>> So may be it need to add new UserFoldRanges array and add it on each Rescan
I wouldn't do that in a new array, because then you have always look in both arrays in all parts of source code.
And I wouldn't add the range as such ("hey there are a part of code from line 12 to 20 that you can fold"), i would add the selected text as a keyword, so the common parse procedure will find it. This was my first idea. So you don't engange "in the middle" of all procedures - you define a new keyword. Reason->Action. That was my idea.
But my version is invalid if you change any character of the foldrange.

Maybe with your idea it is better to handle after editing inside the text. But what is, if you add some lines above it. If the foldranges are updated by the little procedure, that only add or subtract the number of new lines, then it would work. But what is, when he decided to rescan the complete text? Then you can collapse lines 12 to 20, but the text is now from 13 to 21....

Hmm Hmm Hmm.



>>Administaration working on this, they wants totally reorganize forum =)
I have read translated parts of it, but I think now its ok. If I have the complete GUI in english I can navigate good. Elsewhise I never had found the nice bird. ;) So the forumnames maybe had to changed into english. The threads can stay be in russian, and if somebody decided to write it in english like me, than he can do that. I have read something about more than this both languages... even german. That isnt needed....

Это сообщение отредактировал(а) DavidCl0nel - 13.9.2006, 14:54
PM MAIL   Вверх
llutti
Дата 27.9.2006, 02:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 21.9.2006
Где: Blumenau, Brazil

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



Hi,

  I found a minor bug in the procedure TCustomSynEdit.PaintGutter. When I use the codefolding, the display the number of line in gutter don't work ok.


  The original code:

...
        s := fGutter.FormatLineNumber( cLine );

        //### Code Folding ###
        // Calculate the number to show on gutter
        if CodeFolding.Enabled then
          s := IntToStr(GetRealLineNumber(cLine));  // Problem I found
        //### End Code Folding ###
....

  The new code
...
        s := fGutter.FormatLineNumber( cLine );

        //### Code Folding ###
        // Calculate the number to show on gutter
        if CodeFolding.Enabled then
          s := fGutter.FormatLineNumber(GetRealLineNumber(cLine));  // Problem I found
        //### End Code Folding ###
....



   The best regards,

Luciano
PM MAIL   Вверх
PaulIsh
Дата 1.10.2006, 09:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Yearstarday I tried your modified SynEdit. 
I found some bugs:
1. If I paste code from clipboard with enabled codefilding synedit does not show folding images for this code.
  Example for Delphi syntax highlighter:
Код

  begin
    try
      for i := 0 to 10 do
        a := a + 1;
    except
    end;
  end.

2. Second problem for this code, is that folding rule "begin end" works as it defined and fold first begin and first and. But first end in this example finish try except block. Of cource I can define one more folding rule "try end", but I don't need it. So, how can I define block rule, that should not folding?

Если кому надо, могу повторить сообшение по русски smile

Это сообщение отредактировал(а) PaulIsh - 1.10.2006, 10:00
PM MAIL   Вверх
DavidCl0nel
Дата 2.10.2006, 11:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



@llutti: OK.

@PaulIsh:
1. I dont have this problem with my own folding ranges. Do you your SynUniHighlighter-Way (only use the component) or do you add your own folding ranges like me with SynMemo.CodeFolding.FoldRegions.Add(rtKeyWord....) ?


2. Yes it is a problem. But how he can ignore the first end, if he dont know, that this belongs to try?  So he found the first end, but it is the wrong. If you add the try-end-folding it should works. But you can try to use SynMemo.CodeFolding.FoldRegions.SkipRegions.Add().
PM MAIL   Вверх
llutti
Дата 6.10.2006, 15:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 21.9.2006
Где: Blumenau, Brazil

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



Hi,

  When I copy or cut a text at the end of line, every time the #13#10 is copied too. In original synEdit this don't happend.

  In my tests, the problem it's in GetSelText,  I couldn't the exact point.

  In yours test this exists? smile 


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


Новичок



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

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



Sorry for the late answer, but i went to holiday and have now not as much time like before for Syn.

Yes you are right, and also right with TCustomSynEdit.GetSelText.

Fix is
Код

      smNormal:
        //###mod copy collapsed line
        if (First = Last) then begin                                      
          ts := GetUncollapsedStrings;
          // step1: calculate total length of result string
          Inc(TotalLen, ColTo - ColFrom);
          if (Length(ts[GetRealLineNumber(First+1)-1]) < ColTo) and (FoldRangeForLine(First) <> nil) and FoldRangeForLine(First).Collapsed then begin // Selection until line end -> Also get text from foldrange
            iLineCount := 1;
            for i := GetRealLineNumber(First+1) to GetRealLineNumber(Last+2)-2 do begin
              Inc(TotalLen, Length(TrimRight(ts[i])));
              Inc(iLineCount);
            end;
            Inc(TotalLen, Length(sLineBreak) * iLineCount);
          end;

          // step2: build up result string
          SetLength(Result, TotalLen);
          P := PChar(Result);
          CopyAndForward(TrimRight(ts[GetRealLineNumber(First+1)-1]), ColFrom, ColTo - ColFrom, P);
          if (Length(ts[GetRealLineNumber(First+1)-1]) < ColTo) and (FoldRangeForLine(First) <> nil) and FoldRangeForLine(First).Collapsed then begin // Selection until line end -> Also get text from foldrange
            CopyAndForward(sLineBreak, 1, MaxInt, P);
            for i := GetRealLineNumber(First+1) to GetRealLineNumber(Last+2)-2 do begin
              CopyAndForward(TrimRight(ts[i]), 1, MaxInt, P);
              CopyAndForward(sLineBreak, 1, MaxInt, P);
            end;
          end;
          ts.Free;


The big IF-check-line had to replaced, the rest is identical. He shouldnt copy the lines (and only CRLF here) in the collapsed block, if it isnt folded in.
PM MAIL   Вверх
DavidCl0nel
Дата 7.11.2006, 13:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Add the Commands for Collapsing. Then you can call anywhere (i.e. MenuItem) SynMemo.CommandProcessor(ecCollapseCurrent, #0, nil);

Код
procedure TCustomSynEdit.DoOnCommandProcessed(Command: TSynEditorCommand;
  AChar: char; Data: pointer);
var
  FoldRange: TSynEditFoldRange;
  i: Integer;
begin
  //### Code Folding ###
  if CodeFolding.Enabled then
    if (fNeedToReScan)
    or (Command = ecCut)
    or (Command = ecPaste)
    or (Command = ecUndo)
    or (Command = ecRedo)
    or (((Command = ecChar) or (Command = ecDeleteLastChar)) and (IsKeywordAtCursorPos))
    or (Command = ecDeleteLine) then ReScanForFoldRanges;

    //<-->
    if FoldRange <> nil then begin
      case Command of
        ecCollapse:
          begin
            if (FoldRange <> nil) and not FoldRange.Collapsed then Collapse(FoldRange);
            CaretY := FoldRange.FromLine; //Move Cursor to begin of block
          end;

        ecUncollapse:
          begin
            if (FoldRange <> nil) and FoldRange.Collapsed then Uncollapse(FoldRange);
            CaretY := FoldRange.FromLine; //Move Cursor to begin of block
          end;

        ecCollapseAll: 
          CollapseAll;
        
        ecUncollapseAll:
          UncollapseAll;
        
        ecCollapseLevel: ;//ToDo
        ecUncollapseLevel: ;//ToDo
      
        ecCollapseCurrent: 
          begin
            if FoldRange <> nil then
              if FoldRange.Collapsed then Uncollapse(FoldRange) else Collapse(FoldRange);
            CaretY := FoldRange.FromLine; //Move Cursor to begin of block
          end;
      end;
    end;
          
  if CodeFolding.IndentGuides then begin
    case Command of
      ecCut, ecPaste, ecUndo, ecRedo, ecDeleteLastChar, ecDeleteChar:
        CheckIfAtMatchingKeywords;
      ecUp, ecDown, ecPageUp, ecPageDown, ecPageTop, ecPageBottom,
      ecEditorTop, ecEditorBottom, ecGotoXY:
        RepaintGuides;  //###mod highlight current IndentGuide
    end;
  end;
  //### End Code Folding ###
 
  if Assigned(fOnCommandProcessed) then
    fOnCommandProcessed(Self, Command, AChar, Data);
end;


Это сообщение отредактировал(а) DavidCl0nel - 7.11.2006, 14:08
PM MAIL   Вверх
Alienizer
Дата 3.12.2006, 10:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Hello,

I just downloaded SynEdit v2.03 but I don't know where I can download the Code Folding for it? Can someone please tell me where I can download Code Folding for SynEdit v2.03? Thank you.
PM MAIL   Вверх
llutti
Дата 3.12.2006, 15:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 21.9.2006
Где: Blumenau, Brazil

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



Hi,

  You will find the link in http://sepa.spb.ru/?syn_eng.

regards,

Luciano
PM MAIL   Вверх
Alienizer
Дата 4.12.2006, 02:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Thank you Luciano. I appreciate your help.
PM MAIL   Вверх
Alienizer
Дата 4.12.2006, 06:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Maybe I'm very stupid but, I can't get the CodeFolding to work! I set it enabled, a black vert line shows next to the gutter, but that's it. I've set the key assignment for acCollapse etc. still no go. No documentations and no examples on how it works!

Can anyone please help me? Just need a hint, I know how to code so I don't need a whole big example or anything. Thank you.
PM MAIL   Вверх
lookfar
Дата 13.12.2006, 08:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(Alienizer @ 4.12.2006,  06:10)
Maybe I'm very stupid but, I can't get the CodeFolding to work! I set it enabled, a black vert line shows next to the gutter, but that's it. I've set the key assignment for acCollapse etc. still no go. No documentations and no examples on how it works!

Can anyone please help me? Just need a hint, I know how to code so I don't need a whole big example or anything. Thank you.




in order to make the "Light" demo from Unihighlighter, in the uses:
Код

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  Dialogs, Menus, ComCtrls, SynEditPrint, SynExportRTF, SynEditExport,
  SynExportHTML, SynEdit, SynEditHighlighter, SynUniHighlighter,
  SynEditTypes, ToolWin, XPMan, ImgList, ActnList, SynEditTextBuffer,
  SynEditKeyCmds,{$IFDEF CODEFOLDING}SynEditCodeFolding, SynEditMiscClasses, {$ENDIF} IniFiles;


In the "LoadFile" procedure
Код

{$IFDEF CODEFOLDING}
  Edit.Gutter.Width := 16;
  Edit.CodeFolding.Enabled := True;
  Edit.CodeFolding.CollapsedCodeHint := True;
  Edit.CodeFolding.CollapsingMarkStyle := msSquare;
  Edit.CodeFolding.FolderBarColor := clScrollBar;
  Edit.CodeFolding.FolderBarLinesColor := clBlack;
  Edit.InitCodeFolding();
  {$ENDIF}


check my post here:
http://forum.vingrad.ru/topic-124651/kw-bueler.html






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


Новичок



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

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



Without the unihighlighter you should use it in such way:
Код

  With SynMemo.CodeFolding do begin
    Enabled := True;
    IndentGuides := True;
    CollapsedCodeHint := True;
    FolderBarColor := clBtnFace;
    HighlighterFoldRegions := False; //<-- this is important, because usually there is no folding info in the common highlighters, if you dont youe unihighlighter, so you had to set this option and give the codefolding keywords some lines later
    CaseSensitive := True;

    //Keywords
    FoldRegions.Add(rtKeyWord, False, False, True, 'If', 'EndIf');
    FoldRegions.Add(rtKeyWord, False, False, True, 'Case', 'EndCase');
    //...more keywords

  end;
  SynMemo.InitCodeFolding;

PM MAIL   Вверх
Alienizer
Дата 29.1.2007, 10:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Thank you this worked, but, there is another problem. When lines are folded and editing is performed, un-folding the lines makes the folding lines in the gutter all at the wrong places, and it will no longer fold correctly! Also, if the fold region is not smart because if a string literal contain the same word as the keyword, for example "endif" the folding is no longer correct. Is it better to use HighlighterFoldRegions := True; and modify the Highlighter to make the proper folding regions?
PM MAIL   Вверх
pyscripter
Дата 14.2.2007, 02:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



FYI, there is another highly enhanced version of Synedit+Mystix around which unfortunately still contains many of the bugs of the original Mystix code.  It is called SynEditStudio and is available from http://www.cnzjw.net/qiutian/blog/index.asp
Unfortunately the demo is in chinese.
PM MAIL   Вверх
pyscripter
Дата 16.2.2007, 14:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



You can download SynEditStudio v1.5.4 from http://pyscripter.googlepages.com/SynEditStudio.rar
 
Also I had suggested to the author the following: 
* merge the bugfixes from SynMix into his code 
* release a version of his code with English resources 
* apply his enhancements to the unicode version of Synedit 
 
and he said that he will try and do that. 
PM MAIL   Вверх
benne08
Дата 31.3.2009, 21:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(DavidCl0nel @  1.8.2006,  10:39 Найти цитируемый пост)
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;


Hello,

I hope its okay to post here, because this thread seems not to be alive, but I don't understand the other, non-english, boards :-/

So I've a question: I'm using the Codefolding from the (I think) latest SynMix and I recognized a large memory-leak - my program allocates more and more memory (100rds of MB after a few time) if I activate the CodeFolding. 
If I undo this change you see above, everything's fine, but I get some errors... What can I do to fix this leak and to prevent the errors?

Thanks for your help and Best Regards!
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.

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


 




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


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

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