aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorFerdinand Oeinck <unknown>2022-10-04 09:35:06 +1100
committerFerdinand Oeinck <unknown>2022-10-04 09:35:06 +1100
commitf4d5c00424eff7c84b4152b4df4de5c0ba4b12bc (patch)
treee239ae33e6bfb8844a150bb1c25b1b643741211d /src
parent232fad28e7003fd38e2468258bcfacc61381ef7a (diff)
downloadscintilla-mirror-f4d5c00424eff7c84b4152b4df4de5c0ba4b12bc.tar.gz
Feature [feature-requests:#1453] Added SCI_STYLESETINVISIBLEREPRESENTATION to
make it easier to edit around invisible text. This also allows representing long lexemes with a single character to provide a summarized view.
Diffstat (limited to 'src')
-rw-r--r--src/EditView.cxx24
-rw-r--r--src/Editor.cxx17
-rw-r--r--src/Style.cxx3
-rw-r--r--src/Style.h1
4 files changed, 44 insertions, 1 deletions
diff --git a/src/EditView.cxx b/src/EditView.cxx
index 86e59b4dc..8a7a50a7e 100644
--- a/src/EditView.cxx
+++ b/src/EditView.cxx
@@ -435,6 +435,21 @@ void LayoutSegments(IPositionCache *pCache,
std::string_view(&ll->chars[ts.start], ts.length), &ll->positions[ts.start + 1], multiThreaded);
}
}
+ } else if (vstyle.styles[ll->styles[ts.start]].invisibleRepresentation[0]) {
+ const int styleInvisible = ll->styles[ts.start];
+ const std::string_view text = vstyle.styles[styleInvisible].invisibleRepresentation;
+ XYPOSITION positionsRepr[Representation::maxLength + 1];
+ // invisibleRepresentation is UTF-8 which only matches cache if document is UTF-8
+ // or it only contains ASCII which is a subset of all currently supported encodings.
+ if (textUnicode || ViewIsASCII(text)) {
+ pCache->MeasureWidths(surface, vstyle, styleInvisible, text, positionsRepr, multiThreaded);
+ } else {
+ surface->MeasureWidthsUTF8(vstyle.styles[styleInvisible].font.get(), text, positionsRepr);
+ }
+ const XYPOSITION representationWidth = positionsRepr[text.length() - 1];
+ for (int ii = 0; ii < ts.length; ii++) {
+ ll->positions[ts.start + 1 + ii] = representationWidth;
+ }
}
}
}
@@ -2230,6 +2245,15 @@ void EditView::DrawForeground(Surface *surface, const EditModel &model, const Vi
surface->DrawTextNoClip(rcSegment, textFont,
rcSegment.top + vsDraw.maxAscent, text, textFore, textBack);
}
+ } else if (vsDraw.styles[styleMain].invisibleRepresentation[0]) {
+ const std::string_view text = vsDraw.styles[styleMain].invisibleRepresentation;
+ if (phasesDraw != PhasesDraw::One) {
+ surface->DrawTextTransparentUTF8(rcSegment, textFont,
+ rcSegment.top + vsDraw.maxAscent, text, textFore);
+ } else {
+ surface->DrawTextNoClipUTF8(rcSegment, textFont,
+ rcSegment.top + vsDraw.maxAscent, text, textFore, textBack);
+ }
}
if (vsDraw.viewWhitespace != WhiteSpace::Invisible ||
(inIndentation && vsDraw.viewIndentationGuides != IndentView::None)) {
diff --git a/src/Editor.cxx b/src/Editor.cxx
index 97c141bae..35148299e 100644
--- a/src/Editor.cxx
+++ b/src/Editor.cxx
@@ -5832,6 +5832,19 @@ void Editor::StyleSetMessage(Message iMessage, uptr_t wParam, sptr_t lParam) {
case Message::StyleSetVisible:
vs.styles[wParam].visible = lParam != 0;
break;
+ case Message::StyleSetInvisibleRepresentation: {
+ const char *utf8 = ConstCharPtrFromSPtr(lParam);
+ char *rep = vs.styles[wParam].invisibleRepresentation;
+ const int classified = UTF8Classify(utf8);
+ if (!(classified & UTF8MaskInvalid)) {
+ // valid UTF-8
+ int len = classified & UTF8MaskWidth;
+ while (len--)
+ *rep++ = *utf8++;
+ }
+ *rep = 0;
+ break;
+ }
case Message::StyleSetChangeable:
vs.styles[wParam].changeable = lParam != 0;
break;
@@ -5878,6 +5891,8 @@ sptr_t Editor::StyleGetMessage(Message iMessage, uptr_t wParam, sptr_t lParam) {
return vs.styles[wParam].visible ? 1 : 0;
case Message::StyleGetChangeable:
return vs.styles[wParam].changeable ? 1 : 0;
+ case Message::StyleGetInvisibleRepresentation:
+ return StringResult(lParam, vs.styles[wParam].invisibleRepresentation);
case Message::StyleGetHotSpot:
return vs.styles[wParam].hotspot ? 1 : 0;
case Message::StyleGetCheckMonospaced:
@@ -7328,6 +7343,7 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
case Message::StyleSetChangeable:
case Message::StyleSetHotSpot:
case Message::StyleSetCheckMonospaced:
+ case Message::StyleSetInvisibleRepresentation:
StyleSetMessage(iMessage, wParam, lParam);
break;
@@ -7347,6 +7363,7 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
case Message::StyleGetChangeable:
case Message::StyleGetHotSpot:
case Message::StyleGetCheckMonospaced:
+ case Message::StyleGetInvisibleRepresentation:
return StyleGetMessage(iMessage, wParam, lParam);
case Message::StyleResetDefault:
diff --git a/src/Style.cxx b/src/Style.cxx
index 76ffa4942..a45072292 100644
--- a/src/Style.cxx
+++ b/src/Style.cxx
@@ -72,7 +72,8 @@ Style::Style(const char *fontName_) noexcept :
caseForce(CaseForce::mixed),
visible(true),
changeable(true),
- hotspot(false) {
+ hotspot(false),
+ invisibleRepresentation{} {
}
void Style::Copy(std::shared_ptr<Font> font_, const FontMeasurements &fm_) noexcept {
diff --git a/src/Style.h b/src/Style.h
index 6cef6bb60..da8159d6c 100644
--- a/src/Style.h
+++ b/src/Style.h
@@ -51,6 +51,7 @@ public:
bool visible;
bool changeable;
bool hotspot;
+ char invisibleRepresentation[5];
std::shared_ptr<Font> font;