Frage zu TSynEdit
Frage zu TSynEdit
Hallo zusammen,
nachdem mich TSynEdit schon seit Stunden fast in den Wahnsinn treibt hoffe ich, dass mir jemand von Euch helfen kann. Ich verwende Lazarus 2.0.6 unter Windows 10.
Wenn ich eine Textdatei mittels SynEdit.Lines.LoadFromFile() lade, mit Ctrl-A alles markiere, lösche und dann mit SynEdit.Lines.SaveToFile() speichere bleibt in der Datei eine Zeile, die nur aus CR und LF besteht, übrig. Bis jetzt habe ich keine Erklärung für dieses Verhalten finden können und auch keinen Hinweis, wie ich das verhindern kann. Im Programm ist diese Zeile nicht zu sehen, d.h. wenn ich alles gelöscht habe befindet sich der Cursor in der ersten Spalte der ersten Zeile und lässt sich auch nicht über das Zeilenende hinaus bewegen (eoScrollPastEol ist False).
Wenn ich z.B. folgende Zeilen eingebe:
1
2
3
ist das Dateiende am Bildschirm in der dritten Zeile hinter der Ziffer 3 und nicht in der Zeile darunter. Trotzdem ist nach dem Speichern hinter jeder Zeile ein CR/LF in der Datei und wenn ich alles lösche und dann speichere bleibt ein CR/LF in der Datei übrig.
Kann mir jemand sagen, warum nicht alles gelöscht wird und wie ich das verhindern kann?
Vielen Dank für Eure Hilfe!
Grüße,
Ralf
nachdem mich TSynEdit schon seit Stunden fast in den Wahnsinn treibt hoffe ich, dass mir jemand von Euch helfen kann. Ich verwende Lazarus 2.0.6 unter Windows 10.
Wenn ich eine Textdatei mittels SynEdit.Lines.LoadFromFile() lade, mit Ctrl-A alles markiere, lösche und dann mit SynEdit.Lines.SaveToFile() speichere bleibt in der Datei eine Zeile, die nur aus CR und LF besteht, übrig. Bis jetzt habe ich keine Erklärung für dieses Verhalten finden können und auch keinen Hinweis, wie ich das verhindern kann. Im Programm ist diese Zeile nicht zu sehen, d.h. wenn ich alles gelöscht habe befindet sich der Cursor in der ersten Spalte der ersten Zeile und lässt sich auch nicht über das Zeilenende hinaus bewegen (eoScrollPastEol ist False).
Wenn ich z.B. folgende Zeilen eingebe:
1
2
3
ist das Dateiende am Bildschirm in der dritten Zeile hinter der Ziffer 3 und nicht in der Zeile darunter. Trotzdem ist nach dem Speichern hinter jeder Zeile ein CR/LF in der Datei und wenn ich alles lösche und dann speichere bleibt ein CR/LF in der Datei übrig.
Kann mir jemand sagen, warum nicht alles gelöscht wird und wie ich das verhindern kann?
Vielen Dank für Eure Hilfe!
Grüße,
Ralf
Re: Frage zu TSynEdit
Echt so schlimm? Inwiefern ist das ein reales Problem in deinem Fall?dl5eu hat geschrieben: nachdem mich TSynEdit schon seit Stunden fast in den Wahnsinn treibt
Die Zeilenumbrüche "vermehren" sich ja nicht.
Re: Frage zu TSynEdit
Hallo theo,
Mein Problem ist, dass somit eine sichtbar leere Datei eben nicht leer ist, sondern CR/LF enthält und damit SynEdit.Lines.Count gleich 1 ist, TSynEdit mich aber glauben lässt, alle Zeilen gelöscht zu haben.
Ralf
Irrtum. Die Zeilenumbrüche vermehren sich sehr wohl, denn den Zeilenvorschub hinter der letzten Zeile habe nicht ich eingegeben, sondern den hat TSynEdit hinzugefügt.theo hat geschrieben:Inwiefern ist das ein reales Problem in deinem Fall? Die Zeilenumbrüche "vermehren" sich ja nicht.
Mein Problem ist, dass somit eine sichtbar leere Datei eben nicht leer ist, sondern CR/LF enthält und damit SynEdit.Lines.Count gleich 1 ist, TSynEdit mich aber glauben lässt, alle Zeilen gelöscht zu haben.
Ralf
- h-elsner
- Lazarusforum e. V.
- Beiträge: 281
- Registriert: Di 24. Jul 2012, 15:42
- OS, Lazarus, FPC: LINUX Mint21.1, Win10, Lazarus 2.2.4, FPC3.2.2
- CPU-Target: X86-64; arm 32bit
- Wohnort: Illertissen
- Kontaktdaten:
Re: Frage zu TSynEdit
Nach meinem Verständnis ist das genau die Zeile wo sich der Cursor befindet, die dann auch abgespeichert wird. Sonst könnte der Kursor gar nicht angezeigt werden.dl5eu hat geschrieben:wenn ich alles gelöscht habe befindet sich der Cursor in der ersten Spalte der ersten Zeile und lässt sich auch nicht über das Zeilenende hinaus bewegen
Verhindern kann man das, wenn man SynEdit1.Lines.Clear; zum Löschen nimmt.
Eventuell kann man vor dem Speichern SynEdit1.Text abfragen (habe ich nicht ausprobiert).
Gruß HE
Re: Frage zu TSynEdit
Ja, ich denke ein Workaround könnte so aussehen:
Code: Alles auswählen
if Length(Trim(SynEdit1.Text))=0 then
SynEdit1.Lines.Clear;
SynEdit1.Lines.SaveToFile(FileName);
-
- Beiträge: 586
- Registriert: Mi 25. Mär 2009, 21:12
- OS, Lazarus, FPC: Laz trunk / fpc latest release / Win and other
- CPU-Target: mostly 32 bit
Re: Frage zu TSynEdit
Du kannst dein eigenes Save schreiben.
Ansonsten ist das im Moment nicht zu verhindern.
SynEdit speichert (im RAM) Zeilen, aber keine Zeilen-Umbrüche. D.h. SynEdit merkt sich auch nicht ob irgendwo nur ein Cr, oder Lf war. Geschrieben werden immer die für die Plattform typischen Umbrüche.
D.h. Das am Ende der letzten Zeile auch immer ein Umbruch ist, da SynEdit sich nicht merkt ob da einer war oder nicht.
Bei ganz leerem Text ist SynEdit nicht immer Konsequent. Manchmal ist leer gleich:
- 0 Zeilen
- 1 leere Zeile
Ansonsten ist das im Moment nicht zu verhindern.
SynEdit speichert (im RAM) Zeilen, aber keine Zeilen-Umbrüche. D.h. SynEdit merkt sich auch nicht ob irgendwo nur ein Cr, oder Lf war. Geschrieben werden immer die für die Plattform typischen Umbrüche.
D.h. Das am Ende der letzten Zeile auch immer ein Umbruch ist, da SynEdit sich nicht merkt ob da einer war oder nicht.
Bei ganz leerem Text ist SynEdit nicht immer Konsequent. Manchmal ist leer gleich:
- 0 Zeilen
- 1 leere Zeile
Re: Frage zu TSynEdit
Alles klar, jetzt weiß ich wenigstens warum es so ist. Den Workaround werde ich ausprobieren.
Danke und viele Grüße,
Ralf
Danke und viele Grüße,
Ralf
Re: Frage zu TSynEdit
Der Vollständigkeit halber: Es gibt ein Property TStrings.SkipLastLineBreak
https://www.freepascal.org/docs-html/rt ... break.html
Das scheint mir hier (in Synedit) bei mir aber keinen Unterschied zu machen und ich weiss auch nicht, ob es für den "leeren String" gedacht ist.
S.a. https://bugs.freepascal.org/view.php?id=36246
https://www.freepascal.org/docs-html/rt ... break.html
Das scheint mir hier (in Synedit) bei mir aber keinen Unterschied zu machen und ich weiss auch nicht, ob es für den "leeren String" gedacht ist.
S.a. https://bugs.freepascal.org/view.php?id=36246
-
- Beiträge: 2118
- Registriert: Di 23. Sep 2014, 17:46
- OS, Lazarus, FPC: Win10 | Linux
- CPU-Target: x86_64
Re: Frage zu TSynEdit
Ist das verhalten nicht zu erwarten? Erstmal fügt TStringList am Ende ein newline hinzu, wenn die Liste leer ist dürfte das Resultat dann nur ein newline sein. Zum anderen ist es die Datei mit ner newline zu beenden Gang und gebe unter sourcecode Editoren, und es nicht zu machen ist eher die Ausnahme, manche Sprachen wie typescript haben in der Syntax Definition fest vorgeschrieben das jede Datei ein newline am Ende haben muss, eben weil es die Regel ist und man inkonsistenzen vermeiden will. Für einen sourcecode Editor macht mMn was anderes keinen Sinn.
PS. Warum will man denn auch leere Dateien überhaupt abspeichern? Wenn die Datei leer ist sollte sie gelöscht werden, bevor irgendwer noch auf die Idee kommt sie ausversehen ins git zu pushen
PS. Warum will man denn auch leere Dateien überhaupt abspeichern? Wenn die Datei leer ist sollte sie gelöscht werden, bevor irgendwer noch auf die Idee kommt sie ausversehen ins git zu pushen
Re: Frage zu TSynEdit
Hallo zusammen,
Danke für die weiteren Hinweise. TStrings.SkipLastLineBreak scheint tatsächlich keine oder zumindest nicht die von mir gewünschte Wirkung zu haben.
Bisher habe ich TSynEdit noch nie verwendet und bin nur auf diese Komponente gestoßen, weil TMemo für den gedachten Einsatzzweck nicht die nötige Funktionalität besitzt.
Ihr fragt Euch, warum mich das geschilderte Verhalten stört. Die Antwort ist einfach: in meinem Programm benötige ich die Information, ob der Editor Text enthält oder nicht. Wenn ich alle Zeilen lösche ist die Anzahl der Zeilen (Lines.Count) aber gleich 1 und nicht 0, wie ich es erwartet habe. Da es einen anderen, einfachen Weg gibt festzustellen, ob Text vorhanden ist oder nicht (Length(SynEdit1.Text) = 0) kann ich damit leben.
Ich verwende TSynEdit in meinem Programm tatsächlich als eine Art einfachen Code-Editor, nämlich um Dateien mit Befehlen zur Steuerung von Messgeräten zu erstellen und entweder alle oder nur bestimmte Zeilen an die Geräte senden zu können. Natürlich könnte ich die Datei auch mit irgendeinem anderen Editor erstellen. Ich ziehe es aber vor, nur ein Programm aufrufen zu müssen und da SynEdit die nötige Funktionalität bereits mitbringt dürfte sich der Aufwand in Grenzen halten. Außerdem kann ich dabei nur lernen.
Nun möchte ich durch Klicken mit der Maus auf den linken Rand Breakpoints setzen, so wie es in Lazarus möglich ist. Vielleicht kann mir jemand einen Tipp geben, in welchen Units der Lazarus-IDE ich mir das anschauen kann.
Das Ereignis OnGutterClick habe ich gefunden und ich kann eine TSynEditMark setzen, die korrekt angezeigt wird. Nur ist beim nächsten Klick in dieser Zeile der Parameter Mark der aufgerufenen Prozedur wieder nil, obwohl bereits eine Marke gesetzt ist. Ich muss also selbst die gesetzte Marke suchen. Ist das normal bzw. so gewollt?
Vielen Dank für Eure Hilfe!
Ralf
Danke für die weiteren Hinweise. TStrings.SkipLastLineBreak scheint tatsächlich keine oder zumindest nicht die von mir gewünschte Wirkung zu haben.
Bisher habe ich TSynEdit noch nie verwendet und bin nur auf diese Komponente gestoßen, weil TMemo für den gedachten Einsatzzweck nicht die nötige Funktionalität besitzt.
Ihr fragt Euch, warum mich das geschilderte Verhalten stört. Die Antwort ist einfach: in meinem Programm benötige ich die Information, ob der Editor Text enthält oder nicht. Wenn ich alle Zeilen lösche ist die Anzahl der Zeilen (Lines.Count) aber gleich 1 und nicht 0, wie ich es erwartet habe. Da es einen anderen, einfachen Weg gibt festzustellen, ob Text vorhanden ist oder nicht (Length(SynEdit1.Text) = 0) kann ich damit leben.
Ich verwende TSynEdit in meinem Programm tatsächlich als eine Art einfachen Code-Editor, nämlich um Dateien mit Befehlen zur Steuerung von Messgeräten zu erstellen und entweder alle oder nur bestimmte Zeilen an die Geräte senden zu können. Natürlich könnte ich die Datei auch mit irgendeinem anderen Editor erstellen. Ich ziehe es aber vor, nur ein Programm aufrufen zu müssen und da SynEdit die nötige Funktionalität bereits mitbringt dürfte sich der Aufwand in Grenzen halten. Außerdem kann ich dabei nur lernen.
Nun möchte ich durch Klicken mit der Maus auf den linken Rand Breakpoints setzen, so wie es in Lazarus möglich ist. Vielleicht kann mir jemand einen Tipp geben, in welchen Units der Lazarus-IDE ich mir das anschauen kann.
Das Ereignis OnGutterClick habe ich gefunden und ich kann eine TSynEditMark setzen, die korrekt angezeigt wird. Nur ist beim nächsten Klick in dieser Zeile der Parameter Mark der aufgerufenen Prozedur wieder nil, obwohl bereits eine Marke gesetzt ist. Ich muss also selbst die gesetzte Marke suchen. Ist das normal bzw. so gewollt?
Vielen Dank für Eure Hilfe!
Ralf
-
- Beiträge: 586
- Registriert: Mi 25. Mär 2009, 21:12
- OS, Lazarus, FPC: Laz trunk / fpc latest release / Win and other
- CPU-Target: mostly 32 bit
Re: Frage zu TSynEdit
SkipLastLineBreak ist von der BasisKlasse.
In SynEdit nicht implementiert. Patches willkommen.
Der code ist in unit SynEditLines
TSynEditLines = class(TStrings)
In SynEdit nicht implementiert. Patches willkommen.
Der code ist in unit SynEditLines
TSynEditLines = class(TStrings)