[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.
useTabs
field is only used inside Document::SetLineIndentation()
and Editor::Indent()
methods, call to InvalidateStyleRedraw()
can be eliminated.
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:
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:
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:
[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:
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:
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:
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 rangeRectangular
but 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: