Frage zu TSynEdit

Rund um die LCL und andere Komponenten
Antworten
dl5eu
Beiträge: 33
Registriert: Do 12. Sep 2013, 12:40

Frage zu TSynEdit

Beitrag von dl5eu »

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

Benutzeravatar
theo
Beiträge: 10468
Registriert: Mo 11. Sep 2006, 19:01

Re: Frage zu TSynEdit

Beitrag von theo »

dl5eu hat geschrieben:nachdem mich TSynEdit schon seit Stunden fast in den Wahnsinn treibt


Echt so schlimm? Inwiefern ist das ein reales Problem in deinem Fall?
Die Zeilenumbrüche "vermehren" sich ja nicht.

dl5eu
Beiträge: 33
Registriert: Do 12. Sep 2013, 12:40

Re: Frage zu TSynEdit

Beitrag von dl5eu »

Hallo theo,

theo hat geschrieben:Inwiefern ist das ein reales Problem in deinem Fall? Die Zeilenumbrüche "vermehren" sich ja nicht.


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.

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

Benutzeravatar
h-elsner
Lazarusforum e. V.
Beiträge: 259
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

Beitrag von h-elsner »

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


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.

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

Benutzeravatar
theo
Beiträge: 10468
Registriert: Mo 11. Sep 2006, 19:01

Re: Frage zu TSynEdit

Beitrag von theo »

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)

martin_frb
Beiträge: 572
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

Beitrag von martin_frb »

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

dl5eu
Beiträge: 33
Registriert: Do 12. Sep 2013, 12:40

Re: Frage zu TSynEdit

Beitrag von dl5eu »

Alles klar, jetzt weiß ich wenigstens warum es so ist. Den Workaround werde ich ausprobieren.

Danke und viele Grüße,

Ralf

Benutzeravatar
theo
Beiträge: 10468
Registriert: Mo 11. Sep 2006, 19:01

Re: Frage zu TSynEdit

Beitrag von theo »

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

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Frage zu TSynEdit

Beitrag von Warf »

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

dl5eu
Beiträge: 33
Registriert: Do 12. Sep 2013, 12:40

Re: Frage zu TSynEdit

Beitrag von dl5eu »

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

martin_frb
Beiträge: 572
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

Beitrag von martin_frb »

SkipLastLineBreak ist von der BasisKlasse.

In SynEdit nicht implementiert. Patches willkommen.

Der code ist in unit SynEditLines

TSynEditLines = class(TStrings)

Antworten