Restoring the vertical position

32 views
Skip to first unread message

Jean Lalonde

unread,
Mar 17, 2025, 11:54:47 AMMar 17
to scintilla-interest
Hi,

I need to capture the current vertical position of the caret (or selection start) in the editor in order to restore this position after a complete replacement of the editor content with SCI_SETTEXT(). Using SCI_SETSEL() to restore the previous position in the document works. But I can't find how to restore the previous vertical position.

The expected result is that after replacing the content, the user find the caret at the same vertical position it was before the replacement. The replaced text has the same number of lines and lines length as the original text.

I tried various methods under the "Scrolling and automatic scrolling" section of the doc, including SCI_SETYCARETPOLICY(), but none gives the expected result.

Thanks for your help.

Mitchell

unread,
Mar 17, 2025, 12:04:37 PMMar 17
to scintilla...@googlegroups.com
Hi,
Have you tried saving SCI_GETFIRSTVISIBLELINE and restoring it with SCI_SETFIRSTVISIBLELINE?

Cheers,
Mitchell

Jean Lalonde

unread,
Mar 17, 2025, 12:06:39 PMMar 17
to scintilla-interest
I forgot to mention that I also tried

intFisrtVisibleLine := SCI_GETFIRSTVISIBLELINE()
...
SCI_  SETFIRSTVISIBLELINE(intFisrtVisibleLine)

But this does not restore the expected position. FYI, SCI_SETWRAPMODE() is enabled.

Mitchell

unread,
Mar 17, 2025, 12:14:50 PMMar 17
to scintilla...@googlegroups.com
Hi,

> On Mar 17, 2025, at 12:06 PM, Jean Lalonde <jlalo...@gmail.com> wrote:
>
> I forgot to mention that I also tried
>
> intFisrtVisibleLine := SCI_GETFIRSTVISIBLELINE()
> ...
> SCI_ SETFIRSTVISIBLELINE(intFisrtVisibleLine)
>
> But this does not restore the expected position. FYI, SCI_SETWRAPMODE() is enabled.

Then I think you’ll have to save with SCI_DOCLINEFROMVISIBLE(SCI_GETFIRSTVISIBLELINE) and restore with SCI_VISIBLEFROMDOCLINE.

You might need to trigger a Scintilla repaint in-between your SCI_SETTEXT and SCI_VISIBLEFROMDOCLINE. You could wait for an SCN_UPDATEUI notification, but that would require some extra work.

Cheers,
Mitchell

Jean Lalonde

unread,
Mar 17, 2025, 5:02:38 PMMar 17
to scintilla-interest
Thank you for your help Mitchell.

Here is a sample of my AutoHotkey code. The function SetEditorText() gets the current vertical position, replace the editor with the new text and tries to restore the vertical position.

;---------------------------------------------------------
SetEditorText(strNewText, intStart, intEnd)
;---------------------------------------------------------
{
; o_Sci is an AutoHotkey class wrapper for Scintilla commands messages

intFirstVisibleLine := o_Sci.GETFIRSTVISIBLELINE()
intDocLineFromVisible := o_Sci.DOCLINEFROMVISIBLE(intFirstVisibleLine)

o_Sci.SETTEXT("", strNewText, 1)

o_Sci.SETSEL(intStart, intEnd)
o_Sci.VISIBLEFROMDOCLINE(intDocLineFromVisible)
}
;---------------------------------------------------------


The current result with this code is that regardless of the original position of the selected text in the visible portion (middle or bottom of the window), the selection vertical position is always restored at the top of the window (first visible line). See the example attached where the selected text has been converted to uppercase.

Thanks,
Jean
1-selection-before.png
2-selection-after.png

Mitchell

unread,
Mar 17, 2025, 5:54:26 PMMar 17
to scintilla...@googlegroups.com
Hi,

> On Mar 17, 2025, at 5:02 PM, Jean Lalonde <jlalo...@gmail.com> wrote:
>
> Thank you for your help Mitchell.
>
> Here is a sample of my AutoHotkey code. The function SetEditorText() gets the current vertical position, replace the editor with the new text and tries to restore the vertical position.
>
> ;---------------------------------------------------------
> SetEditorText(strNewText, intStart, intEnd)
> ;---------------------------------------------------------
> {
> ; o_Sci is an AutoHotkey class wrapper for Scintilla commands messages
>
> intFirstVisibleLine := o_Sci.GETFIRSTVISIBLELINE()
> intDocLineFromVisible := o_Sci.DOCLINEFROMVISIBLE(intFirstVisibleLine)
>
> o_Sci.SETTEXT("", strNewText, 1)
>
> o_Sci.SETSEL(intStart, intEnd)
> o_Sci.VISIBLEFROMDOCLINE(intDocLineFromVisible)

I think you need `o_Sci.SETFIRSTVISIBLELINE(o_Sci.VISIBLEFROMDOCLINE(intDocLineFromVisible))`

In my last response, what I meant by “restore with VISIBLEFROMDOCLINE” was to pass the result to SETFIRSTVISIBLELINE. Sorry that wasn’t more clear.

Cheers,
Mitchell

Neil Hodgson

unread,
Mar 17, 2025, 8:42:45 PMMar 17
to scintilla-interest
Wrapping is a slow operation so is performed as an idle task. The lines will not be wrapped at the time that SCI_SETFIRSTVISIBLELINE is called. A short wait that allows idle processing, possibly on a timer may cause SCI_SETFIRSTVISIBLELINE to produce a result closer to your preference.

Neil

Jean Lalonde

unread,
Mar 17, 2025, 10:23:34 PMMar 17
to scintilla-interest
@Mitchell: OK I got it. Thanks.

@Neil: Thanks for the notice.

This being considered, I think I'll refactor my code to avoid SetText() for the whole editor and, instead, use ReplaceSel() for the selected text (or for each selection when there are multiple selections). This will eliminate the need for restoring the vertical position. Thanks for your help.

Jean

Neil Hodgson

unread,
Mar 19, 2025, 1:12:00 AMMar 19
to Scintilla mailing list
Me:

> Wrapping is a slow operation so is performed as an idle task. The lines will not be wrapped at the time that SCI_SETFIRSTVISIBLELINE is called. A short wait that allows idle processing, possibly on a timer may cause SCI_SETFIRSTVISIBLELINE to produce a result closer to your preference.

Since Scintilla runs the idle time wrapping, it may be reasonable for it to offer a SetFirstVisibleLineAfterWrap method that waited until wrapping had passed that line before setting the vertical scroll position.

This may be a significant time (possibly 10 seconds or more) later so the operation should be cancelled if the user starts interacting before then as it would be annoying for the visual context to be ripped away once the user starts scrolling or typing, for example.

To deal with changing conditions like text enlargement or window resizing, it may be better to use a (character) position to anchor the display instead of a visible or document line.

Neil

Reply all
Reply to author
Forward
0 new messages