Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2011-09

SynEdit and gutter behaviour

8 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Bart

Hi,

I have a SynEdit on a form and I do this

  SynEdit1.SelText := '//Bye';

This works as expected, and in the gutter the line is now marked as changed.

However if I do this:

  SynEdit1.Lines[1] := SynEdit1.Lines[1] + ' // Hi';

The Line gets updated allright, but the gutter does not mark the line as changed.

Question:

1: Is this a bug?
2: If it is not a bug, how can I make the gutter mark this line as changed?

Bart

Reply by email

Martin
to Bart
Bart wrote 20 lines
Hi, I have a SynEdit on a form and I do this SynEdit1.SelText := '//Bye'; This works as expected, and in the gutter the line is now marked as changed. However if I do this: SynEdit1.Lines[1] := SynEdit1.Lines[1] + ' // Hi'; The Line gets updated allright, but the gutter does not mark the line as changed. Question: 1: Is this a bug? 2: If it is not a bug, how can I make the gutter mark this line as changed?

this is intended behaviour.

Using SynEdit.Lines, does not trigger any "line change", also it does not add "undo" (and previous undo will stop working) Lines are used for initialization

Since it is of course not desired to select text only to change it, there is
SynEdit.TextBetweenPoints[Point(1,200), Point(20,200)]

which can be set to
SynEdit.TextBetweenPoints[Point(1,200), Point(20,200)] := 'foo';

to insert text, use identical points

there is
SynEdit.TextBetweenPointsEx

which has an extra param, to determine, if the caret should be moved (if it was behind the location, and text changed (eg, lines inserted)

Reply by email

Martin
to Martin
Martin wrote 25 lines
On 14/09/2011 15:43, Bart wrote: > this is intended behaviour. Using SynEdit.Lines, does not trigger any "line change", also it does not add "undo" (and previous undo will stop working) Lines are used for initialization Since it is of course not desired to select text only to change it, there is SynEdit.TextBetweenPoints[Point(1,200), Point(20,200)] which can be set to SynEdit.TextBetweenPoints[Point(1,200), Point(20,200)] := 'foo'; to insert text, use identical points there is SynEdit.TextBetweenPointsEx which has an extra param, to determine, if the caret should be moved (if it was behind the location, and text changed (eg, lines inserted)

you can temporarily set the selection to be persistent, and it should be kept to

options2 := [eoPersistentBlock]

Reply by email

Bart
to Martin: this is intended behaviour. Using SynEdit.Lines, does not trigger any "line change", also…
Martin wrote 5 lines
this is intended behaviour. Using SynEdit.Lines, does not trigger any "line change", also it does not add "undo" (and previous undo will stop working) Lines are used for initialization

OK, I get that.

Since it is of course not desired to select text only to change it,

I really do not understand what you mean by that.
Changing selected text is one of the key features I'm using this app for.

Show quoted text 5 lines
there is SynEdit.TextBetweenPoints[Point(1,200), Point(20,200)] which can be set to SynEdit.TextBetweenPoints[Point(1,200), Point(20,200)] := 'foo';

The whole purpose of this excercise is the following.

In the SynEdit I load a textfile (html in this case) with Lines.LoadfromFile(). Now after loading I want to see if there is a line which contains a html meta-tag defining the charset, something like:

<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

In that line I want to change the ISO-8859-1 part into something else.

So my strategy was to loop through the lines, see if any line has the meta-tag I seek, then change the line.
That part I have in working order.

At this stage in the process I do not know at what "Point" this text is (the caret certainly is not there, so I can't use that as a reference).

Also, considering when I do this (changing Lines[]), I do not mind that all prvious "undo" will stop working.

So, now I see 2 options:
1: Calculate the two points defining the text I want to change and use TextBetweenPoints() or
2: Signal to the gutter that the given line has changed

I really have no idea how to achieve any of those 2 options ATM.

Bart

Reply by email

Martin
to Bart
Bart wrote
On 9/14/11, Martin wrote: > Since it is of course not desired to select text only to change it, I really do not understand what you mean by that. Changing selected text is one of the key features I'm using this app for.

If you wish to change text by code (from your app, rather than user input), then you do not necessarily want to have to select the to-be-changed-text first.

Show quoted text 22 lines
> there is > SynEdit.TextBetweenPoints[Point(1,200), Point(20,200)] > > which can be set to > SynEdit.TextBetweenPoints[Point(1,200), Point(20,200)] := 'foo'; The whole purpose of this excercise is the following. In the SynEdit I load a textfile (html in this case) with Lines.LoadfromFile(). Now after loading I want to see if there is a line which contains a html meta-tag defining the charset, something like: <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> In that line I want to change the ISO-8859-1 part into something else. So my strategy was to loop through the lines, see if any line has the meta-tag I seek, then change the line. That part I have in working order. At this stage in the process I do not know at what "Point" this text is (the caret certainly is not there, so I can't use that as a reference).

Well you loop through the lines? So you got the line-INDEX ?

The line number(for the point is one based, so add one. The X pos is byte based. You should know at which byte in the string (again 1-based) the desired text starts

e.g line with index 3 (4t line on screen:
Foo Bar Some

Bar is Point(5, 4) to Point(8, 4)
the "F" in Foo is Point(1, 4) to Point(2, 4)

point is X,Y

Show quoted text 10 lines
Also, considering when I do this (changing Lines[]), I do not mind that all prvious "undo" will stop working. So, now I see 2 options: 1: Calculate the two points defining the text I want to change and use TextBetweenPoints() or 2: Signal to the gutter that the given line has changed I really have no idea how to achieve any of those 2 options ATM.

For 2:
You need your own subclass of synedit, to get the internal line object.

   procedure TSynEditStringList.MarkModified(AFirst, ALast: Integer);

But there is (and never will be) direct access to TSynEditStringList

you can create a plugin (sourceeditor afaik does, at least once did) => but the whole plugin stuff, is under design => don't trust anything that you find by exploring the units

It is possible though that the modified state of lines can in future be published. Either via the visble lines (would need a typecast, as they are tstrings. Or directly on synedit => as for directly on synedit, I don't like it, too many properties, it needs a bit of structure.

Feel free to come up with ideas. as for how it could be solved, then we can discuss, what would be accepted as patch

Reply by email

Bart
to Martin
Martin wrote
If you wish to change text by code (from your app, rather than user input), then you do not necessarily want to have to select the to-be-changed-text first.

I understood you incorrectly then.
It is the user that selects text, then clicks a button (or uses a key shortcut) to perform actions on the selected text. E.g. you can select text, press Ctrl+B and voila, the text is surrounded by <b> and </b> tags.
(As you might have guessed by now, the application is primarily a html text editor.)

Show quoted text 13 lines
Well you loop through the lines? So you got the line-INDEX ? The line number(for the point is one based, so add one. The X pos is byte based. You should know at which byte in the string (again 1-based) the desired text starts e.g line with index 3 (4t line on screen: Foo Bar Some Bar is Point(5, 4) to Point(8, 4) the "F" in Foo is Point(1, 4) to Point(2, 4) point is X,Y

OK, that makes sense to me.
I will give that a try.

Show quoted text 7 lines
> 2: Signal to the gutter that the given line has changed > For 2: You need your own subclass of synedit, to get the internal line object. procedure TSynEditStringList.MarkModified(AFirst, ALast: Integer); But there is (and never will be) direct access to TSynEditStringList

This sounds like, although it is possible, it is designed in such a way that you are not really supposed/encouraged to do it that way... For now, I'll skip that option.

Show quoted text 8 lines
It is possible though that the modified state of lines can in future be published. Either via the visble lines (would need a typecast, as they are tstrings. Or directly on synedit => as for directly on synedit, I don't like it, too many properties, it needs a bit of structure. Feel free to come up with ideas. as for how it could be solved, then we can discuss, what would be accepted as patch

I severely got lost in all the SynEdit (and related) source code. I would have expected that the GutterPart that does the (visual) marking would have a property to determine (or even set?) if a line was modified.

As for SynEdit itself. Every time I found a method that looked like it might trigger a change in "Line.Modified" status, I ended up (using Ctlr-Click) at a virtual abstract method declaration...

Thanks for the help so far.

Bart

Reply by email

Martin
to Bart
Bart wrote 11 lines
On 9/15/11, Martin wrote: >> 2: Signal to the gutter that the given line has changed >> > For 2: > You need your own subclass of synedit, to get the internal line object. > procedure TSynEditStringList.MarkModified(AFirst, ALast: Integer); > > But there is (and never will be) direct access to TSynEditStringList This sounds like, although it is possible, it is designed in such a way that you are not really supposed/encouraged to do it that way... For now, I'll skip that option.

exactly, extremely discouraged.

Show quoted text 12 lines
> It is possible though that the modified state of lines can in future be > published. Either via the visble lines (would need a typecast, as they > are tstrings. Or directly on synedit => as for directly on synedit, I > don't like it, too many properties, it needs a bit of structure. > > Feel free to come up with ideas. as for how it could be solved, then we > can discuss, what would be accepted as patch > I severely got lost in all the SynEdit (and related) source code. I would have expected that the GutterPart that does the (visual) marking would have a property to determine (or even set?) if a line was modified.

The data is in textbuffer.

Important if you have shared-editors => where 2 synedit work on the same text.

Sure one could add properties to the gutter, to modify it in the textbuffer.

But the gutter is only to show the info. The info exists without the gutter.

then better to have
SynEdit.LineProperties
or similiar

As for SynEdit itself. Every time I found a method that looked like it might trigger a change in "Line.Modified" status, I ended up (using Ctlr-Click) at a virtual abstract method declaration...

oh, yes the textbuffers has a virtual baseclass, as there are layers of wrappers

go to SynEditTextBuffer

Reply by email

Bart
to Martin: If you wish to change text by code (from your app, rather than user input), then you do…
Martin wrote 11 lines
The line number(for the point is one based, so add one. The X pos is byte based. You should know at which byte in the string (again 1-based) the desired text starts e.g line with index 3 (4t line on screen: Foo Bar Some Bar is Point(5, 4) to Point(8, 4) the "F" in Foo is Point(1, 4) to Point(2, 4) point is X,Y

Thanks for the help.
I got it working now with TextBetweenPoints.

Bart

Reply by email