[scintilla:feature-requests] #1567 Remove unnecessary `InvalidateStyleRedraw()` for `Message::SetUseTabs`

0 views
Skip to first unread message

YX Hao

unread,
Sep 29, 2025, 6:51:36 AMSep 29
to scintill...@googlegroups.com

[feature-requests:#1567] Remove unnecessary InvalidateStyleRedraw() for Message::SetUseTabs

Status: open
Group: Initial
Labels: scintilla
Created: Mon Sep 29, 2025 10:51 AM UTC by YX Hao
Last Updated: Mon Sep 29, 2025 10:51 AM UTC
Owner: nobody
Attachments:

Hi Neil and maintainers,

I think Message::SetUseTabs only toggles wheather or not new tabs will be replaced with spaces, and the layout doesn't change. So, InvalidateStyleRedraw() is not necessary.

This eliminates a bug of Notepad4: doesn't work correctly on rectangular selections. If 0 column is selected, press 1+ times. The Ctrl + Tab feature can date back to the original Notepad2.

Thanks in advance!


Sent from sourceforge.net because scintill...@googlegroups.com is subscribed to https://sourceforge.net/p/scintilla/feature-requests/

To unsubscribe from further messages, a project admin can change settings at https://sourceforge.net/p/scintilla/admin/feature-requests/options. Or, if this is a mailing list, you can unsubscribe from the mailing list.

Zufu Liu

unread,
Sep 29, 2025, 8:45:36 AMSep 29
to scintill...@googlegroups.com

useTabs field is only used inside Document::SetLineIndentation() and Editor::Indent() methods, call to InvalidateStyleRedraw() can be eliminated.

Neil Hodgson

unread,
Oct 11, 2025, 5:45:36 PM (3 days ago) Oct 11
to scintill...@googlegroups.com
  • labels: scintilla --> scintilla, indent
  • Comment:

InvalidateStyleRedraw() should be safe to call. If Ctrl+Tab is not working correctly then Message::Tab that it calls may need to perform more setup. If just the change proposed above is done then there may be other ways to reach Message::Tab in a state that fails.

The reason for the failure should be examined more closely and, perhaps fixed inside Editor::Indent that is called for Message::Tab.

While the mentioned InvalidateStyleRedraw() can be removed for performance, the potential failure is more important.


[feature-requests:#1567] Remove unnecessary InvalidateStyleRedraw() for Message::SetUseTabs

Status: open
Group: Initial
Labels: scintilla indent

Created: Mon Sep 29, 2025 10:51 AM UTC by YX Hao

Last Updated: Mon Sep 29, 2025 12:45 PM UTC
Owner: nobody
Attachments:

Zufu Liu

unread,
Oct 11, 2025, 7:02:12 PM (3 days ago) Oct 11
to scintill...@googlegroups.com

The mentioned code block inserts raw tab (\t) character at caret position:

case CMD_CTRLTAB:
    SciCall_SetTabIndents(false);
    SciCall_SetUseTabs(true);
    SciCall_Tab();
    SciCall_SetUseTabs(!fvCurFile.bTabsAsSpaces);
    SciCall_SetTabIndents(fvCurFile.bTabIndents);
    break;

1567before.gif is screenshot with InvalidateStyleRedraw(),
1567after.gif is screenshot without InvalidateStyleRedraw().

Attachments:


[feature-requests:#1567] Remove unnecessary InvalidateStyleRedraw() for Message::SetUseTabs

Status: open
Group: Initial
Labels: scintilla indent

Created: Mon Sep 29, 2025 10:51 AM UTC by YX Hao

Last Updated: Sat Oct 11, 2025 09:45 PM UTC
Owner: nobody
Attachments:

Zufu Liu

unread,
Oct 13, 2025, 6:59:33 AM (yesterday) Oct 13
to scintill...@googlegroups.com

Wonder how YX Hao identified the bug and fix.
Apply 1567-Notepad4-debug-1013.diff onto today's Noetpad4 code, build (e.g. click batch file inside build\VisualStudio\ folder) and run Notepad4.exe from terminal, open a 2 bytes file (\n\n, just two new-lines), hold Alt key to make rectangular selection for the three lines, press Ctrl + Tab twice.

log without InvalidateStyleRedraw() for Message::SetUseTabs:

SetRectangularRange | Editor::ButtonUpWithModifiers(class Scintilla::Internal::Point,unsigned int,enum Scintilla::KeyMod):5267
SetRectangularRange range: 0
SetRectangularRange range: 1
SetRectangularRange range: 2
Tab before: ToString: R#2,0-2 | Editor::KeyCommand(enum Scintilla::Message):4088
ToString: R#2,0-2 | Editor::Indent(bool,bool):4190
Indent DeleteChars(0, 0)
ToString: R#2,0-2 | ModelState::RememberSelectionForUndo(int,const class Scintilla::Internal::Selection &):64
ToString: R#2,1-3 | Editor::Indent(bool,bool):4260
ToString: R#2,1-3 | Editor::Indent(bool,bool):4190
Indent DeleteChars(2, 0)
ToString: R#2,1-3 | ModelState::RememberSelectionForUndo(int,const class Scintilla::Internal::Selection &):64
ToString: R#2,1-4 | Editor::Indent(bool,bool):4260
ToString: R#2,1-4 | Editor::Indent(bool,bool):4190
Indent DeleteChars(4, 0)
ToString: R#2,1-4 | ModelState::RememberSelectionForUndo(int,const class Scintilla::Internal::Selection &):64
ToString: R#2,1-4 | Editor::Indent(bool,bool):4260
ToString: R#2,1-4 | ModelState::RememberSelectionForRedoOntoStack(int,const class Scintilla::Internal::Selection &,__int64):79
Tab  after: ToString: R#2,1-4 | Editor::KeyCommand(enum Scintilla::Message):4096
Tab before: ToString: R#2,1-4 | Editor::KeyCommand(enum Scintilla::Message):4088
ToString: R#2,1-4 | Editor::Indent(bool,bool):4190
Indent DeleteChars(1, 0)
ToString: R#2,1-4 | ModelState::RememberSelectionForUndo(int,const class Scintilla::Internal::Selection &):64
ToString: R#2,2-5 | Editor::Indent(bool,bool):4260
ToString: R#2,2-5 | Editor::Indent(bool,bool):4190
Indent DeleteChars(4, 0)
ToString: R#2,2-5 | ModelState::RememberSelectionForUndo(int,const class Scintilla::Internal::Selection &):64
ToString: R#2,2-6 | Editor::Indent(bool,bool):4260
ToString: R#2,2-6 | Editor::Indent(bool,bool):4190
Indent DeleteChars(7, 0)
ToString: R#2,2-6 | ModelState::RememberSelectionForUndo(int,const class Scintilla::Internal::Selection &):64
ToString: R#2,2-6 | Editor::Indent(bool,bool):4260
ToString: R#2,2-6 | ModelState::RememberSelectionForRedoOntoStack(int,const class Scintilla::Internal::Selection &,__int64):79
Tab  after: ToString: R#2,2-6 | Editor::KeyCommand(enum Scintilla::Message):4096

log with InvalidateStyleRedraw():

SetRectangularRange | Editor::ButtonUpWithModifiers(class Scintilla::Internal::Point,unsigned int,enum Scintilla::KeyMod):5267
SetRectangularRange range: 0
SetRectangularRange range: 1
SetRectangularRange range: 2
Tab before: ToString: R#2,0-2 | Editor::KeyCommand(enum Scintilla::Message):4088
ToString: R#2,0-2 | Editor::Indent(bool,bool):4190
Indent DeleteChars(0, 0)
ToString: R#2,0-2 | ModelState::RememberSelectionForUndo(int,const class Scintilla::Internal::Selection &):64
RefreshStyleData | Editor::NotifyModified(class Scintilla::Internal::Document *,class Scintilla::Internal::DocModification,void *):2917
SetRectangularRange | Editor::RefreshStyleData(const struct std::source_location):260
SetRectangularRange range: 1-0
SetRectangularRange range: 2v8-2
SetRectangularRange range: 3v8-3
ToString: R#2,1-3 | Editor::Indent(bool,bool):4260
ToString: R#2,1-3 | Editor::Indent(bool,bool):4190
Indent DeleteChars(2, 0)
ToString: R#2,1-3 | ModelState::RememberSelectionForUndo(int,const class Scintilla::Internal::Selection &):64
ToString: R#2,1-4 | Editor::Indent(bool,bool):4260
ToString: R#2,1-4 | Editor::Indent(bool,bool):4190
Indent DeleteChars(4, 0)
ToString: R#2,1-4 | ModelState::RememberSelectionForUndo(int,const class Scintilla::Internal::Selection &):64
ToString: R#2,1-4 | Editor::Indent(bool,bool):4260
ToString: R#2,1-4 | ModelState::RememberSelectionForRedoOntoStack(int,const class Scintilla::Internal::Selection &,__int64):79
Tab  after: ToString: R#2,1-4 | Editor::KeyCommand(enum Scintilla::Message):4096
RefreshStyleData | ScintillaWin::PaintDC(struct HDC__ *):1406
SetRectangularRange | Editor::RefreshStyleData(const struct std::source_location):260
SetRectangularRange range: 1-0
SetRectangularRange range: 3-2
SetRectangularRange range: 5-4
Tab before: ToString: R#2,1-4 | Editor::KeyCommand(enum Scintilla::Message):4088
ToString: R#2,1-4 | Editor::Indent(bool,bool):4190
Indent DeleteChars(0, 1)
ToString: R#2,1-4 | ModelState::RememberSelectionForUndo(int,const class Scintilla::Internal::Selection &):64
NotifyModified DeleteText 0, 1
ToString: R#2,1-4 | Editor::NotifyModified(class Scintilla::Internal::Document *,class Scintilla::Internal::DocModification,void *):2866
ToString: R#2,0-3 | Editor::NotifyModified(class Scintilla::Internal::Document *,class Scintilla::Internal::DocModification,void *):2870
RefreshStyleData | Editor::NotifyModified(class Scintilla::Internal::Document *,class Scintilla::Internal::DocModification,void *):2917
SetRectangularRange | Editor::RefreshStyleData(const struct std::source_location):260
SetRectangularRange range: 0
SetRectangularRange range: 1
SetRectangularRange range: 3
ToString: R#2,0-3 | ModelState::RememberSelectionForUndo(int,const class Scintilla::Internal::Selection &):64
ToString: R#2,1-4 | Editor::Indent(bool,bool):4260
ToString: R#2,1-4 | Editor::Indent(bool,bool):4190
Indent DeleteChars(2, 0)
ToString: R#2,1-4 | ModelState::RememberSelectionForUndo(int,const class Scintilla::Internal::Selection &):64
ToString: R#2,1-5 | Editor::Indent(bool,bool):4260
ToString: R#2,1-5 | Editor::Indent(bool,bool):4190
Indent DeleteChars(5, 0)
ToString: R#2,1-5 | ModelState::RememberSelectionForUndo(int,const class Scintilla::Internal::Selection &):64
ToString: R#2,1-5 | Editor::Indent(bool,bool):4260
ToString: R#2,1-5 | ModelState::RememberSelectionForRedoOntoStack(int,const class Scintilla::Internal::Selection &,__int64):79
Tab  after: ToString: R#2,1-5 | Editor::KeyCommand(enum Scintilla::Message):4096
RefreshStyleData | ScintillaWin::PaintDC(struct HDC__ *):1406
SetRectangularRange | Editor::RefreshStyleData(const struct std::source_location):260
SetRectangularRange range: 1-0
SetRectangularRange range: 3-2
SetRectangularRange range: 6-5

So, the underline bug is not fixed: SetRectangularRange() may change selection ranges, and cause pdoc->DeleteChars() inside Indent() to actually delete characters.

Attachments:


[feature-requests:#1567] Remove unnecessary InvalidateStyleRedraw() for Message::SetUseTabs

Status: open
Group: Initial
Labels: scintilla indent

Created: Mon Sep 29, 2025 10:51 AM UTC by YX Hao

Last Updated: Sat Oct 11, 2025 11:02 PM UTC
Owner: nobody
Attachments:

Zufu Liu

unread,
Oct 13, 2025, 7:14:19 AM (yesterday) Oct 13
to scintill...@googlegroups.com
  • labels: scintilla, indent --> scintilla, indent, selection

[feature-requests:#1567] Remove unnecessary InvalidateStyleRedraw() for Message::SetUseTabs

Status: open
Group: Initial
Labels: scintilla indent selection

Created: Mon Sep 29, 2025 10:51 AM UTC by YX Hao

Last Updated: Mon Oct 13, 2025 10:59 AM UTC
Owner: nobody
Attachments:

YX Hao

unread,
Oct 13, 2025, 9:02:58 AM (yesterday) Oct 13
to scintill...@googlegroups.com

I'm not as familiar with the project code as you are. I commented out SciCall_SetTabIndents() and SciCall_SetUseTabs(), leaving only SciCall_Tab(). It worked fine. Then narrowed down to the handling of Message::SetUseTabs and found that InvalidateStyleRedraw() was unnecessary. After removing it, it did work, so I didn't look into it.


[feature-requests:#1567] Remove unnecessary InvalidateStyleRedraw() for Message::SetUseTabs

Status: open
Group: Initial
Labels: scintilla indent selection

Created: Mon Sep 29, 2025 10:51 AM UTC by YX Hao

Last Updated: Mon Oct 13, 2025 11:14 AM UTC
Owner: nobody
Attachments:

Zufu Liu

unread,
6:09 AM (13 hours ago) 6:09 AM
to scintill...@googlegroups.com

Not find a fix, the bug can be reproduced in SciTE with similar code, e.g.:

case IDM_HELP: {
    wEditor.SetTabIndents(false);
    wEditor.SetUseTabs(true);
    wEditor.Tab();
    wEditor.SetUseTabs(props.GetInt("use.tabs", 1));
    wEditor.SetTabIndents(props.GetInt("tab.indents", 1));
    return;

[feature-requests:#1567] Remove unnecessary InvalidateStyleRedraw() for Message::SetUseTabs

Status: open
Group: Initial
Labels: scintilla indent selection

Created: Mon Sep 29, 2025 10:51 AM UTC by YX Hao

Last Updated: Mon Oct 13, 2025 01:02 PM UTC
Owner: nobody
Attachments:

Neil Hodgson

unread,
7:13 PM (15 minutes ago) 7:13 PM
to scintill...@googlegroups.com

I think the basic issue here is between a rectangular selection and Editor::Indent not behaving in a 'rectangular' way. Each piece of the selection is treated as part of a multiple-selection. The selection type stays rectangular but the range is not updated to match the bounds of all of the selection pieces. So there is a mismatch between Selection::rangeRectangular and Selection::ranges.

Likely the best approach would be to work out how Tab should work in a rectangular context and implement that as a separate branch inside Editor::Indent. Less work would be repairing the relationship between the fields. Possibly by setting Selection::rangeRectangular to match the bounds of Selection::ranges then recalculating Selection::ranges.

The role of InvalidateStyleRedraw is to cause SetRectangularRange to occur, which does synchronize ranges from rangeRectangularbut that may be the wrong direction in this case, not matching user preference.


[feature-requests:#1567] Remove unnecessary InvalidateStyleRedraw() for Message::SetUseTabs

Status: open
Group: Initial
Labels: scintilla indent selection
Created: Mon Sep 29, 2025 10:51 AM UTC by YX Hao

Last Updated: Tue Oct 14, 2025 10:09 AM UTC
Owner: nobody
Attachments:

Reply all
Reply to author
Forward
0 new messages