Recent

Author Topic: Synedit with word wrap?  (Read 20961 times)

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11454
  • Debugger - SynEdit - and more
    • wiki
Re: Synedit with word wrap?
« Reply #15 on: November 02, 2014, 01:26:54 pm »
Not sure what you mean. But if you delay, then during this delay the display is incorrect.

Example: For the vertical scrollbar, you need:
- the total of visible lines (aka after wrapping)
- the amount of visible lines before the first line on screen.

Doing the plain array is a start. On a modern, decent fast computer it will likely work (unless you have millions of lines).
And if you are not on a laptop, you can keep the CPU as busy as you like.

-------------
Here is another bit of SynEdit that needs to be improved. Create a text(copy and paste) with 100,000 lines (average 20 to 60 char long.

1) You may notice, that pasting 20000 lines, takes a moment
2) Select all 100000 lines, and indent them (tab if configured, or ctrl-i). That takes a moment too. Especially on the 1.2 fixes branch or earlier. Trunk was improved.


Edson

  • Hero Member
  • *****
  • Posts: 1325
Re: Synedit with word wrap?
« Reply #16 on: November 02, 2014, 06:06:16 pm »
I think that @typo refers to treat the lines as paragraphs and storage just the number of lines in every paragraph, not the beginning line. So it isn't not necessary to update all the paragraphs, every time a line is inserted.

Anyway, it still will be necessary to calculate the total lines of the text in some time, but it won't be so heavy as it's just accumulate a counter.

The critical situation is in horizontal-resizing. It would force to process all the paragraphs.

Of course, a word-wrap editor use more CPU. That's a reason it wouldn't be activated   if it's not necessary.
Lazarus 2.2.6 - FPC 3.2.2 - x86_64-win64 on Windows 10

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11454
  • Debugger - SynEdit - and more
    • wiki
Re: Synedit with word wrap?
« Reply #17 on: November 02, 2014, 06:44:04 pm »
I think that @typo refers to treat the lines as paragraphs and storage just the number of lines in every paragraph, not the beginning line. So it isn't not necessary to update all the paragraphs, every time a line is inserted.

Anyway, it still will be necessary to calculate the total lines of the text in some time, but it won't be so heavy as it's just accumulate a counter.

The total amount of lines is needed for the scrollbar, so it is needed all the time.
Yet you can keep a separate counter, that is fine.

The above works well, except if scrolling, or "jump to line", or bookmark.
If you jump to a bookmark at real line 50000 you need to sum up all the lines before. (or you can not show the scrollbar correctly)


Of course 50,000 is not an issue for a modern PC. Then make it 500,000 lines.... (FPC used to have a unit with 300,000 lines, so it is not a theoretical issue)

With normal scrolling, you can avoid recalculating, by calculating the offset to the last known line. But that means you need to add optimizations like that. Because every time you scroll one line, you need to set the scrollbar.
Avoiding this would mean to change lots of synedit code


Edson

  • Hero Member
  • *****
  • Posts: 1325
Re: Synedit with word wrap?
« Reply #18 on: November 03, 2014, 12:05:30 am »
The total amount of lines is needed for the scrollbar, so it is needed all the time.
Yet you can keep a separate counter, that is fine.

You can easy calculate it exactly, if you have just a few thousands of lines. If there are 50000 lines or more, I would use an aproximate value, using just the paragraphs index for have the scrollbar adjusted.

It that case, it could be calculated exactly, just in idle CPU time.

The above works well, except if scrolling, or "jump to line", or bookmark.
If you jump to a bookmark at real line 50000 you need to sum up all the lines before. (or you can not show the scrollbar correctly)

Bookmarks (and "jump to line") must be referred to paragraphs, not to physical lines. Then, it would be easy to jump to any "line".

Even when resizing the control, we could use just an approximate value (using paragraphs, if there are too many lines) for to show the scrollbar. It would be very fast, even breaking the visible lines, on real-time.
« Last Edit: November 03, 2014, 12:09:05 am by Edson »
Lazarus 2.2.6 - FPC 3.2.2 - x86_64-win64 on Windows 10

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11454
  • Debugger - SynEdit - and more
    • wiki
Re: Synedit with word wrap?
« Reply #19 on: November 03, 2014, 12:24:10 am »
On resize, yes it would adjust over time. So apporximate to start with.

Code: [Select]
Bookmarks (and "jump to line") must be referred to paragraphs, not to physical lines. Then, it would be easy to jump to any "line".

You mean the visible line? then you must calculate the real line from it, or else you can not fetch the text.

Edson

  • Hero Member
  • *****
  • Posts: 1325
Re: Synedit with word wrap?
« Reply #20 on: November 03, 2014, 12:51:49 am »
I'm assuming that on a hypothetical word-wrap mode, we show on gutter just a line number for all the paragraphs (like Notepad++ do).

And we maintain the same storage for lines, using a TStrings list like SynEdit currently do. The difference would be now, that "one line" (one entry of Lines[] ), can be visualized on more than one visible "lines". That means that we really storage "paragraphs".

Then when we set a Bookmark, it must save something like Line=5000, Column=200. So, when jumping, we jump quickly to paragraph 5000 (in fact Lines[5000]), and then we must find the real "visible line" that match the column 200 (just breaking the paragraph 5000) [1].

What I propose is just using an approximate value of lines, based on paragraphs, for the scrollbar if we manage many lines, leaving the exactly calculation for a thread or for idle time. It would avoid to break all the lines for the real calculation of line number. After all, it's only necessary for the scrollbar.

[1], we could need to break some previous or next paragraphs, that we need for to show an entire screen.
« Last Edit: November 03, 2014, 12:56:27 am by Edson »
Lazarus 2.2.6 - FPC 3.2.2 - x86_64-win64 on Windows 10

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11454
  • Debugger - SynEdit - and more
    • wiki
Re: Synedit with word wrap?
« Reply #21 on: November 03, 2014, 02:47:58 am »
Ok, I see what you mean. Would probably work.

Just not the way I would go.

Also: While approximation is almost unavoidable during resize of window, it should be avaided whenever possible.

When approximation is used, and the user grabs the scrollbar slider with the mouse, then it will behave unexpected....

In case of a bookmark it can be avoided.

typo

  • Hero Member
  • *****
  • Posts: 3051
Re: Synedit with word wrap?
« Reply #22 on: November 03, 2014, 01:39:32 pm »
If SynEdit could store non-wrapped text and draw it wrapped or justified internally (and also manage the caret around larger spaces which the text would have), external component could calculate the words and lines positons like TSynWordWrap does, instead of writing an already written text and fighting against the caret like it would need to do now.

AFAICS, the text in SynEdit is actually written in TheTextDrawer TextOut, ExtTextOut and NewTextOut methods from SynTextDrawer unit.
« Last Edit: November 03, 2014, 02:27:30 pm by typo »

typo

  • Hero Member
  • *****
  • Posts: 3051
Re: Synedit with word wrap?
« Reply #23 on: November 03, 2014, 08:32:35 pm »
It could work similarly to a highlighter, with SynEdit asking it on where to write the words/characters.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11454
  • Debugger - SynEdit - and more
    • wiki
Re: Synedit with word wrap?
« Reply #24 on: November 03, 2014, 09:11:51 pm »
Look at he fold module. IT's the same logic.

typo

  • Hero Member
  • *****
  • Posts: 3051
Re: Synedit with word wrap?
« Reply #25 on: November 03, 2014, 11:45:18 pm »
The thread which counts lines could increase a counter progressively, at each step while running, avoiding that SynEdit be waiting for the final result. At each step it has a parcial result, which could be used to set scrollbar as properly as possible.

But if after all one enables the user to resize horizontally the control at any time with the mouse, the work is lost. WordPad itself does not allow that. Anyway, it could be possible if the resize action interrupts the previous resetting and restart it with a new value.
« Last Edit: November 04, 2014, 12:22:53 am by typo »

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11454
  • Debugger - SynEdit - and more
    • wiki
Re: Synedit with word wrap?
« Reply #26 on: November 04, 2014, 12:31:18 am »
I am starting to get deja vue, and also am not sure what we try to archive with the discussion from this point on.

There is more than one solution, they differ in cpu usage, battery life time, and how long which actions will take.

But we went through all that. I pointed out which approach I would take (if I would be doing it). But if you offer a different solution, then I wont stop you.

As for how to integrate it with SynEdit., I pointed to the "views". That is the place to go.

All you said can be done there. At least for line mapping. For caret X mapping some extra work will be needed.

typo

  • Hero Member
  • *****
  • Posts: 3051
Re: Synedit with word wrap?
« Reply #27 on: November 04, 2014, 12:45:04 am »
Do not worry, I am not contesting you. My statements have more the character of a question than an answer.

You have already answer what I wanted to know and I am satisfied. Thank you.
« Last Edit: November 04, 2014, 01:03:37 am by typo »

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11454
  • Debugger - SynEdit - and more
    • wiki
Re: Synedit with word wrap?
« Reply #28 on: November 04, 2014, 01:21:52 am »
Never thought as it as a contest, but open questioning. Just thought it started to repeat questions.

1) Determining where to wrap a line, is easy (should be)

2) storing, is important, as it affects speed, but in a good design, can be changed later

3) mapping for synedit
Code: [Select]
  TLazSynDisplayView = class
  private
    FNextView: TLazSynDisplayView;
  public
    constructor Create;
    property NextView: TLazSynDisplayView read FNextView write FNextView;
  public
    procedure InitHighlighterTokens(AHighlighter: TSynCustomHighlighter); virtual;
    procedure SetHighlighterTokensLine(ALine: TLineIdx; out ARealLine: TLineIdx); virtual;
    procedure FinishHighlighterTokens; virtual;
    function  GetNextHighlighterToken(out ATokenInfo: TLazSynDisplayTokenInfo): Boolean; virtual;
    function GetLinesCount: Integer; virtual;
    function GetDrawDividerInfo: TSynDividerDrawConfigSetting; virtual;

    function TextToViewIndex(AIndex: TLineIdx): TLineRange; virtual;
    function ViewToTextIndex(AIndex: TLineIdx): TLineIdx; virtual;
    //function ViewToTextIndexEx(AIndex: TLineIdx; out AScreenRange: TLineRange): TLineIdx;
    // todo: gutter info
  end;
/////////////
  TLazSynDisplayViewEx = class(TLazSynDisplayView)
///////////
  TLazSynDisplayFold = class(TLazSynDisplayViewEx)
This is used by the views, to provide lines for painting. It is placed between the text buffer and the painter.

"SetHighlighterTokensLine" takes input in visible lines.

May need extensions for the gutter.


typo

  • Hero Member
  • *****
  • Posts: 3051
Re: Synedit with word wrap?
« Reply #29 on: November 04, 2014, 09:45:36 pm »
I don't intend to contest you, I want only to understand which modifications you could want for SynEdit and in what direction. Probably SynEdit needs none modifications to remain the IDE's edit window. But it needs a few more modifications to be an edit control available for the community.

Some developers use SynEdit for text editors, maybe because they can see what happens inside it and will not have any suprise about its behavior. They need an edit control for ordinary text edition, with a caret, selection, etc. Maybe SynEdit can be this control.
« Last Edit: November 04, 2014, 10:02:01 pm by typo »

 

TinyPortal © 2005-2018