diff --git a/components/synedit/synedit.pp b/components/synedit/synedit.pp index d68703a6e2..c424dfeaa3 100644 --- a/components/synedit/synedit.pp +++ b/components/synedit/synedit.pp @@ -729,7 +729,7 @@ type procedure AddKey(Command: TSynEditorCommand; Key1: word; SS1: TShiftState; Key2: word; SS2: TShiftState); - procedure BeginUndoBlock; //sbs 2000-11-19 + procedure BeginUndoBlock(aList: TSynEditUndoList = nil); procedure BeginUpdate; function CaretXPix: Integer; function CaretYPix: Integer; @@ -746,7 +746,7 @@ type destructor Destroy; override; procedure DoCopyToClipboard(const SText: string); procedure DragDrop(Source: TObject; X, Y: Integer); override; - procedure EndUndoBlock; //sbs 2000-11-19 + procedure EndUndoBlock(aList: TSynEditUndoList = nil); procedure EndUpdate; procedure EnsureCursorPosVisible; {$IFDEF SYN_COMPILER_4_UP} @@ -875,7 +875,7 @@ type property LineHeight: integer read fTextHeight; property LinesInWindow: Integer read fLinesInWindow; // MG: fully visible lines property LineText: string read GetLineText write SetLineText; - property RealLines: TStrings read FTheLinesView write SetRealLines; Deprecated; // As viewed internally (with uncommited spaces / TODO: expanded tabs, folds). This may change, use with care + property RealLines: TStrings read FTheLinesView write SetRealLines; // As viewed internally (with uncommited spaces / TODO: expanded tabs, folds). This may change, use with care property Lines: TStrings read FLines write SetLines; // No uncommited (trailing/trimmable) spaces property Text: string read SynGetText write SynSetText; // No uncommited (trailing/trimmable) spaces property Marks: TSynEditMarkList read fMarkList; @@ -5435,7 +5435,7 @@ begin Item := fRedoList.PeekItem; if Item <> nil then begin {$IFDEF SYN_LAZARUS} - fUndoList.BeginBlock; + BeginUndoBlock; OldChangeNumber := Item.fChangeNumber; {$ELSE} OldChangeNumber := fUndoList.BlockChangeNumber; @@ -5452,7 +5452,7 @@ begin {$ENDIF} finally {$IFDEF SYN_LAZARUS} - fUndoList.EndBlock; + EndUndoBlock; {$ELSE} fUndoList.BlockChangeNumber := OldChangeNumber; {$ENDIF} @@ -5490,35 +5490,27 @@ begin case Item.fChangeReason of crInsert, crPaste, crDragDropInsert: begin - SetCaretAndSelection( - {$IFDEF SYN_LAZARUS}PhysStartPos{$ELSE}Item.fChangeStartPos{$ENDIF}, - Item.fChangeStartPos, Item.fChangeStartPos - ); + SetCaretAndSelection(LogicalToPhysicalPos(Item.ChangeStartPos), + Item.ChangeStartPos, Item.ChangeStartPos); SetSelTextPrimitive(Item.fChangeSelMode, PChar(Item.fChangeStr)); - {$IFDEF SYN_LAZARUS} CaretXY := LogicalToPhysicalPos(Item.fChangeEndPos); - {$ELSE} - CaretXY := Item.fChangeEndPos; //mh 2000-10-30 - {$ENDIF} fUndoList.AddChange(Item.fChangeReason, Item.fChangeStartPos, Item.fChangeEndPos, GetSelText, Item.fChangeSelMode); {begin} //mh 2000-11-20 if Item.fChangeReason = crDragDropInsert then begin - SetCaretAndSelection( - {$IFDEF SYN_LAZARUS}PhysStartPos{$ELSE}Item.fChangeStartPos{$ENDIF}, - Item.fChangeStartPos, Item.fChangeEndPos); + SetCaretAndSelection(PhysStartPos, + Item.fChangeStartPos, Item.fChangeEndPos); end; {end} //mh 2000-11-20 end; crDeleteAfterCursor, crSilentDeleteAfterCursor: //mh 2000-10-30 begin - SetCaretAndSelection( - {$IFDEF SYN_LAZARUS}PhysStartPos{$ELSE}Item.fChangeStartPos{$ENDIF}, - Item.fChangeStartPos,{$IFDEF SYN_LAZARUS}Item.fChangeEndPos{$ELSE}Item.fChangeStartPos{$ENDIF} - ); - fUndoList.AddChange(Item.fChangeReason, Item.fChangeStartPos, - Item.fChangeEndPos, GetSelText, Item.fChangeSelMode); + SetCaretAndSelection(PhysStartPos, + Item.fChangeStartPos, Item.fChangeEndPos); + TempString := GetSelText; SetSelTextPrimitive(Item.fChangeSelMode, PChar(Item.fChangeStr)); + fUndoList.AddChange(Item.fChangeReason, Item.fChangeStartPos, + Item.fChangeEndPos, TempString, Item.fChangeSelMode); {$IFDEF SYN_LAZARUS} CaretXY := LogicalToPhysicalPos(Item.ChangeStartPos); {$ELSE} @@ -5531,9 +5523,10 @@ begin {$IFDEF SYN_LAZARUS}PhysStartPos{$ELSE}Item.fChangeStartPos{$ENDIF}, Item.fChangeStartPos, {$IFDEF SYN_LAZARUS}Item.fChangeEndPos{$ELSE}Item.fChangeStartPos{$ENDIF} ); - fUndoList.AddChange(Item.fChangeReason, Item.fChangeStartPos, - Item.fChangeEndPos, GetSelText, Item.fChangeSelMode); + TempString := GetSelText;; SetSelTextPrimitive(Item.fChangeSelMode, PChar(Item.fChangeStr)); + fUndoList.AddChange(Item.fChangeReason, Item.fChangeStartPos, + Item.fChangeEndPos, TempString, Item.fChangeSelMode); {$IFDEF SYN_LAZARUS} CaretXY := PhysStartPos; {$ELSE} @@ -5555,6 +5548,11 @@ begin {$IFDEF SYN_LAZARUS} crTrimSpace: FTrimmedLinesView.ForceTrim; {$ENDIF} + crTrimRealSpace: + begin + fUndoList.AddChange(Item.fChangeReason, Item.fChangeStartPos, + Item.fChangeEndPos, Item.fChangeStr, Item.fChangeSelMode); + end; crLineBreak: {begin} //sbs 2000-11-20 // CommandProcessor(ecLineBreak, #13, nil); @@ -5670,7 +5668,7 @@ begin Item := fUndoList.PeekItem; if Item <> nil then begin {$IFDEF SYN_LAZARUS} - fRedoList.BeginBlock; + BeginUndoBlock(fRedoList); OldChangeNumber := Item.fChangeNumber; {$ELSE} OldChangeNumber := fRedoList.BlockChangeNumber; @@ -5691,7 +5689,7 @@ begin FTrimmedLinesView.ForceTrim; fUndoList.UnLock; {$IFDEF SYN_LAZARUS} - fRedoList.EndBlock; + EndUndoBlock(fRedoList); {$ELSE} fRedoList.BlockChangeNumber := OldChangeNumber; {$ENDIF} @@ -5781,7 +5779,11 @@ begin FTrimmedLinesView.UndoTrimmedSpaces := False; end; crTrimRealSpace: - FTrimmedLinesView.UndoRealSpaces(Item); + begin + FTrimmedLinesView.UndoRealSpaces(Item); + fRedoList.AddChange(Item.fChangeReason, Item.fChangeStartPos, + Item.fChangeEndPos, Item.fChangeStr, Item.fChangeSelMode); + end; crLineBreak: begin // If there's no selection, we have to set @@ -6893,6 +6895,7 @@ begin if CaretY < FTheLinesView.Count then begin Helper := StringOfChar(' ', LogCaretXY.X - 1 - Len); FTheLinesView[CaretY - 1] := Temp + Helper + FTheLinesView[CaretY]; + FTheLinesView.Delete(CaretY); if helper <> '' then begin Caret := Point(Len+1, CaretY); // logical fUndoList.AddChange(crInsert, PhysicalToLogicalPos(CaretXY), @@ -6900,7 +6903,6 @@ begin end; Caret := Point(1, CaretY + 1); Helper := {$IFDEF SYN_LAZARUS}LineEnding{$ELSE}#13#10{$ENDIF}; - FTheLinesView.Delete(CaretY); DoLinesDeleted(CaretY - 1, 1); end; end; @@ -6915,9 +6917,12 @@ begin if not ReadOnly then begin Len := LogicalToPhysicalCol(LineText,Length(LineText)+1)-1; Helper := ''; + Caret := CaretXY; if Command = ecDeleteWord then begin - if CaretX > Len + 1 then + if CaretX > Len + 1 then begin Helper := StringOfChar(' ', CaretX - 1 - Len); + Caret.X := Caret.X - (CaretX - 1 - Len); + end; WP := NextWordPos{$IFDEF SYN_LAZARUS}(True){$ENDIF}; end else WP := Point(Len + 1, CaretY); @@ -7016,6 +7021,7 @@ begin // break line in two SpaceCount1 := LeftSpaces(copy(Temp, 1, LogCaretXY.X-1)); Temp := Copy(LineText, 1, LogCaretXY.X - 1); + LineText := LineText; // TrimRealSpaces FTheLinesView.Insert(CaretY - 1, Temp); Delete(Temp2, 1, LogCaretXY.X - 1); if Assigned(Beautifier) then @@ -7028,8 +7034,8 @@ begin CaretXY := Point(SpaceCount1 + 1, CaretY + 1); end else begin // move the whole line + LineText := LineText; // TrimRealSpaces FTheLinesView.Insert(CaretY - 1, ''); - FTheLinesView[CaretY] := FTheLinesView[CaretY]; // trigger trim spaces fUndoList.AddChange(crLineBreak, LogCaretXY, LogCaretXY, Temp2, smNormal); @@ -7041,7 +7047,7 @@ begin if FTheLinesView.Count = 0 then FTheLinesView.Add(''); // linebreak after end of line - FTheLinesView[CaretY-1] := FTheLinesView[CaretY-1]; // trigger trim spaces + LineText := LineText; // TrimRealSpaces fUndoList.AddChange(crLineBreak, LogCaretXY, LogCaretXY, '', smNormal); @@ -7710,14 +7716,13 @@ begin end; {begin} //sbs 2000-11-19 -procedure TCustomSynEdit.BeginUndoBlock; +procedure TCustomSynEdit.BeginUndoBlock(aList: TSynEditUndoList = nil); begin - fUndoList.BeginBlock; - {$IFDEF SYN_LAZARUS} + if aList = nil then aList := fUndoList; + aList.BeginBlock; IncPaintLock; FFoldedLinesView.Lock; FTrimmedLinesView.Lock; - {$ENDIF} end; {end} //sbs 2000-11-19 @@ -7727,9 +7732,9 @@ begin end; {begin} //sbs 2000-11-19 -procedure TCustomSynEdit.EndUndoBlock; +procedure TCustomSynEdit.EndUndoBlock(aList: TSynEditUndoList = nil); begin - {$IFDEF SYN_LAZARUS} + if aList = nil then aList := fUndoList; // Write all trimming info to the end of the undo block, // so it will be undone first, and other UndoItems do see the expected spaces FTrimmedLinesView.UnLock; @@ -7737,8 +7742,7 @@ begin // must be last => May call MoveCaretToVisibleArea, which must only happen // after unfold DecPaintLock; - {$ENDIF} - fUndoList.EndBlock; + aList.EndBlock; end; {end} //sbs 2000-11-19 diff --git a/components/synedit/syneditpointclasses.pas b/components/synedit/syneditpointclasses.pas index 2fae074277..534b88c61f 100644 --- a/components/synedit/syneditpointclasses.pas +++ b/components/synedit/syneditpointclasses.pas @@ -748,6 +748,8 @@ begin BB := FirstLineBytePos; BE := LastLineBytePos; if SelAvail then begin + // todo: better move add-undo past actual delete + FLines[BB.Y - 1] := FLines[BB.Y - 1]; // TrimRealSpaces (in case of smNormal or smLine if AddToUndoList then begin if ChangeReason in [crSilentDelete, crSilentDeleteAfterCursor] then begin if IsBackwardSel then diff --git a/components/synedit/synedittexttrimmer.pas b/components/synedit/synedittexttrimmer.pas index a487cabf12..0401461ceb 100644 --- a/components/synedit/synedittexttrimmer.pas +++ b/components/synedit/synedittexttrimmer.pas @@ -112,6 +112,7 @@ procedure TSynEditStringTrimmingList.DoCaretChanged(Sender : TObject); var s: String; begin + if (not fEnabled) then exit; if (fLineIndex = TSynEditCaret(Sender).LinePos - 1) then exit; if (length(fSpaces) > 0) and (fLineIndex > 0) and (fLineIndex <= fSynStrings.Count) @@ -131,6 +132,9 @@ begin fEnabled:=AValue; fLockList.Clear; fLockCount:=0; + FSpaces := ''; + FLineIndex := -1; + FLockList.Clear; if fEnabled and (fLineIndex >= 0) and (fLineIndex < fSynStrings.Count) then fSynStrings[fLineIndex] := TrimLine(fSynStrings[fLineIndex], fLineIndex); end; @@ -139,6 +143,7 @@ procedure TSynEditStringTrimmingList.UndoRealSpaces(Item: TSynEditUndoItem); var i: Integer; begin + if (not fEnabled) then exit; if length(fSynStrings.Strings[Item.fChangeStartPos.y-1]) + 1 <> Item.fChangeStartPos.x then exit; fSynStrings.Strings[Item.fChangeStartPos.y-1] @@ -156,31 +161,26 @@ var temp: String; begin if (not fEnabled) then exit(s); - If (fUndoList.IsLocked and not UndoTrimmedSpaces) then begin - result := s; - temp := ''; - end else begin - if RealUndo then begin - temp := fSynStrings.Strings[Index]; - l := length(temp); - i:= l; - while (i>0) and (temp[i] in [#9, ' ']) do dec(i); - // Add RealSpaceUndo - if i < l then - fUndoList.AddChange(crTrimRealSpace, Point(i+1, Index+1), - Point(l, Index+1), copy(temp, i+1, l-i), smNormal); - end; - - l := length(s); - i := l; - while (i>0) and (s[i] in [#9, ' ']) do dec(i); - temp := copy(s, i+1, l-i); - if i=l then - result := s // No need to make a copy - else - result := copy(s, 1, i); + if RealUndo then begin + temp := fSynStrings.Strings[Index]; + l := length(temp); + i:= l; + while (i>0) and (temp[i] in [#9, ' ']) do dec(i); + // Add RealSpaceUndo + if i < l then + fUndoList.AddChange(crTrimRealSpace, Point(i+1, Index+1), + Point(l, Index+1), copy(temp, i+1, l-i), smNormal); end; + l := length(s); + i := l; + while (i>0) and (s[i] in [#9, ' ']) do dec(i); + temp := copy(s, i+1, l-i); + if i=l then + result := s // No need to make a copy + else + result := copy(s, 1, i); + if fLockCount > 0 then begin i := fLockList.IndexOfObject(TObject(pointer(Index))); if i < 0 then @@ -198,6 +198,7 @@ function TSynEditStringTrimmingList.Spaces(Index : Integer) : String; var i : Integer; begin + if (not fEnabled) then exit(''); if fLockCount > 0 then begin i := fLockList.IndexOfObject(TObject(Pointer(Index))); if i < 0 then @@ -219,6 +220,7 @@ procedure TSynEditStringTrimmingList.DoLinesChanged(Index, N : integer); var i, j: Integer; begin + if (not fEnabled) then exit; if fLockCount > 0 then begin for i := fLockList.Count-1 downto 0 do begin j := Integer(Pointer(fLockList.Objects[i])); @@ -237,7 +239,7 @@ end; procedure TSynEditStringTrimmingList.Lock; begin - if (fLockCount = 0) and (fLineIndex >= 0) then + if (fLockCount = 0) and (fLineIndex >= 0) and Enabled then fLockList.AddObject(Spaces(fLineIndex), TObject(Pointer(fLineIndex))); inc(fLockCount); end; @@ -253,6 +255,7 @@ var i, index, llen, slen: Integer; ltext: String; begin + if (not fEnabled) then exit; i := fLockList.IndexOfObject(TObject(Pointer(fLineIndex))); if i >= 0 then begin fSpaces:= fLockList[i]; @@ -344,12 +347,17 @@ end; procedure TSynEditStringTrimmingList.Delete(Index : integer); begin + TrimLine('', Index, True); fSynStrings.Delete(Index); DoLinesChanged(Index, -1); end; procedure TSynEditStringTrimmingList.DeleteLines(Index, NumLines : integer); +var + i: Integer; begin + for i := 0 to NumLines-1 do + TrimLine('', Index+i, True); fSynStrings.DeleteLines(Index, NumLines); DoLinesChanged(Index, -NumLines); end;