aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CellBuffer.cxx103
-rw-r--r--src/CellBuffer.h29
-rw-r--r--src/CharacterType.h38
-rw-r--r--src/Document.cxx52
-rw-r--r--src/Document.h1
-rw-r--r--src/EditView.cxx63
-rw-r--r--src/Editor.cxx21
-rw-r--r--src/Editor.h4
8 files changed, 209 insertions, 102 deletions
diff --git a/src/CellBuffer.cxx b/src/CellBuffer.cxx
index 3e9deb934..1eac3f9c2 100644
--- a/src/CellBuffer.cxx
+++ b/src/CellBuffer.cxx
@@ -439,35 +439,90 @@ const char *CellBuffer::InsertString(Sci::Position position, const char *s, Sci:
return data;
}
-bool CellBuffer::SetStyleAt(Sci::Position position, char styleValue) noexcept {
- if (!hasStyles) {
- return false;
- }
- const char curVal = style.ValueAt(position);
- if (curVal != styleValue) {
- style.SetValueAt(position, styleValue);
- return true;
- } else {
- return false;
+namespace {
+
+ChangedRange CopyBytes(char *p, const char *styles, Sci::Position length, Sci::Position offset) noexcept {
+ for (Sci::Position start = 0; start < length; start++) {
+ if (p[start] != styles[start]) {
+ for (Sci::Position end = length - 1; end >= 0; end--) {
+ if (p[end] != styles[end]) {
+ memcpy(p+start, styles+start, end-start+1);
+ return { start + offset, end + offset };
+ }
+ }
+ }
}
+ return {};
}
-bool CellBuffer::SetStyleFor(Sci::Position position, Sci::Position lengthStyle, char styleValue) noexcept {
- if (!hasStyles) {
- return false;
- }
- bool changed = false;
- PLATFORM_ASSERT(lengthStyle == 0 ||
- (lengthStyle > 0 && lengthStyle + position <= style.Length()));
- while (lengthStyle--) {
- const char curVal = style.ValueAt(position);
- if (curVal != styleValue) {
- style.SetValueAt(position, styleValue);
- changed = true;
+ChangedRange SetBytes(char *p, char style, Sci::Position length, Sci::Position offset) noexcept {
+ for (Sci::Position start = 0; start < length; start++) {
+ if (p[start] != style) {
+ for (Sci::Position end = length - 1; end >= 0; end--) {
+ if (p[end] != style) {
+ memset(p+start, style, end-start+1);
+ return { start + offset, end + offset };
+ }
+ }
}
- position++;
}
- return changed;
+ return {};
+}
+
+struct Lengths {
+ Sci::Position length1;
+ Sci::Position length2;
+};
+
+Lengths SplitUpdate(const SplitVector<char> &style, Sci::Position position, Sci::Position length) noexcept {
+ length = std::min(length, style.Length() - position);
+
+ // Divide length into two parts if it overlaps the gap
+ const Sci::Position part1Length = style.GapPosition();
+
+ // If all after gap then place in length1 to avoid second call
+ if (position >= part1Length) {
+ return { length, 0 };
+ }
+ // If all before gap then place in length1
+ const Sci::Position beforeGap = part1Length - position;
+ if (length <= beforeGap) {
+ return { length, 0 };
+ }
+ // Some before gap and some after gap so put portion in length1 and rest in length2
+ return { beforeGap, length - beforeGap };
+}
+
+}
+
+ChangedRange CellBuffer::SetStyles(Sci::Position position, const char *styles, Sci::Position length) noexcept {
+ if (!hasStyles || (position < 0) || (length <= 0)) {
+ return {};
+ }
+
+ const Lengths lengths = SplitUpdate(style, position, length);
+ ChangedRange cr = CopyBytes(&style[position], styles, lengths.length1, position);
+ if (lengths.length2) {
+ const ChangedRange cr2 = CopyBytes(&style[position + lengths.length1], styles + lengths.length1,
+ lengths.length2, position + lengths.length1);
+ cr.Merge(cr2);
+ }
+ return cr;
+}
+
+ChangedRange CellBuffer::SetStyleFor(Sci::Position position, Sci::Position length, char value) noexcept {
+ if (!hasStyles || (position < 0) || (length <= 0)) {
+ return {};
+ }
+
+ const Lengths lengths = SplitUpdate(style, position, length);
+ ChangedRange cr = SetBytes(&style[position], value, lengths.length1, position);
+ if (lengths.length2) {
+ const ChangedRange cr2 = SetBytes(&style[position + lengths.length1], value,
+ lengths.length2, position + lengths.length1);
+ cr.Merge(cr2);
+ }
+ return cr;
}
// The char* returned is to an allocation owned by the undo history
diff --git a/src/CellBuffer.h b/src/CellBuffer.h
index 1b035597a..11479f14a 100644
--- a/src/CellBuffer.h
+++ b/src/CellBuffer.h
@@ -10,6 +10,11 @@
namespace Scintilla::Internal {
+struct Failure : public std::runtime_error {
+ Status status;
+ Failure(Status status_) : std::runtime_error("failure with status"), status(status_) {}
+};
+
// Interface to per-line data that wants to see each line insertion and deletion
class PerLine {
public:
@@ -66,6 +71,24 @@ struct SplitView {
}
};
+struct ChangedRange {
+ Sci::Position start = Sci::invalidPosition;
+ Sci::Position end = Sci::invalidPosition;
+ ChangedRange() noexcept = default;
+ ChangedRange(Sci::Position start_, Sci::Position end_) noexcept : start(start_), end(end_) {}
+ [[nodiscard]] bool Empty() const noexcept {
+ return start < 0;
+ }
+ void Merge(const ChangedRange &cr2) noexcept {
+ if (cr2.start >= 0) {
+ if (start < 0) {
+ *this = cr2;
+ } else {
+ end = cr2.end;
+ }
+ }
+ }
+};
/**
* Holder for an expandable array of characters that supports undo and line markers.
@@ -141,9 +164,9 @@ public:
const char *InsertString(Sci::Position position, const char *s, Sci::Position insertLength, bool &startSequence);
/// Setting styles for positions outside the range of the buffer is safe and has no effect.
- /// @return true if the style of a character is changed.
- bool SetStyleAt(Sci::Position position, char styleValue) noexcept;
- bool SetStyleFor(Sci::Position position, Sci::Position lengthStyle, char styleValue) noexcept;
+ /// @return range where style of characters changed.
+ ChangedRange SetStyles(Sci::Position position, const char *styles, Sci::Position length) noexcept;
+ ChangedRange SetStyleFor(Sci::Position position, Sci::Position length, char value) noexcept;
const char *DeleteChars(Sci::Position position, Sci::Position deleteLength, bool &startSequence);
diff --git a/src/CharacterType.h b/src/CharacterType.h
index 437fb8c5c..a7732cec9 100644
--- a/src/CharacterType.h
+++ b/src/CharacterType.h
@@ -12,12 +12,29 @@ namespace Scintilla::Internal {
// Functions for classifying characters
+template <typename T, typename... Args>
+constexpr bool AnyOf(T t, Args... args) noexcept {
+#if defined(__clang__)
+ static_assert(__is_integral(T) || __is_enum(T));
+#endif
+ return ((t == args) || ...);
+}
+
+// prevent pointer without <type_traits>
+template <typename T, typename... Args>
+constexpr void AnyOf([[maybe_unused]] T *t, [[maybe_unused]] Args... args) noexcept {}
+template <typename T, typename... Args>
+constexpr void AnyOf([[maybe_unused]] const T *t, [[maybe_unused]] Args... args) noexcept {}
+
/**
* Check if a character is a space.
* This is ASCII specific but is safe with chars >= 0x80.
*/
+constexpr int charTab = 0x09;
+constexpr int charCarriageReturn = 0x0D;
+
constexpr bool IsASpace(int ch) noexcept {
- return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
+ return (ch == ' ') || ((ch >= charTab) && (ch <= charCarriageReturn));
}
constexpr bool IsSpaceOrTab(int ch) noexcept {
@@ -44,17 +61,18 @@ constexpr bool IsADigit(int ch) noexcept {
}
constexpr bool IsADigit(int ch, int base) noexcept {
- if (base <= 10) {
+ constexpr int digits = 10;
+ if (base <= digits) {
return (ch >= '0') && (ch < '0' + base);
- } else {
- return ((ch >= '0') && (ch <= '9')) ||
- ((ch >= 'A') && (ch < 'A' + base - 10)) ||
- ((ch >= 'a') && (ch < 'a' + base - 10));
}
+ return ((ch >= '0') && (ch <= '9')) ||
+ ((ch >= 'A') && (ch < 'A' + base - digits)) ||
+ ((ch >= 'a') && (ch < 'a' + base - digits));
}
constexpr bool IsASCII(int ch) noexcept {
- return (ch >= 0) && (ch < 0x80);
+ constexpr int lastASCII = 0x7F;
+ return (ch >= 0) && (ch <= lastASCII);
}
constexpr bool IsLowerCase(int ch) noexcept {
@@ -122,16 +140,14 @@ template <typename T>
constexpr T MakeUpperCase(T ch) noexcept {
if (ch < 'a' || ch > 'z')
return ch;
- else
- return ch - 'a' + 'A';
+ return ch - 'a' + 'A';
}
template <typename T>
constexpr T MakeLowerCase(T ch) noexcept {
if (ch < 'A' || ch > 'Z')
return ch;
- else
- return ch - 'A' + 'a';
+ return ch - 'A' + 'a';
}
int CompareCaseInsensitive(const char *a, const char *b) noexcept;
diff --git a/src/Document.cxx b/src/Document.cxx
index 458c1e93f..289fb6731 100644
--- a/src/Document.cxx
+++ b/src/Document.cxx
@@ -530,6 +530,13 @@ void SCI_METHOD Document::SetErrorStatus(int status) {
}
}
+void Document::CheckPosition(Sci::Position pos) const {
+ PLATFORM_ASSERT((pos >= 0) && (pos <= LengthNoExcept()));
+ if ((pos < 0) || (pos > LengthNoExcept())) {
+ throw Failure(Status::OutsideDocument);
+ }
+}
+
Sci_Position SCI_METHOD Document::LineFromPosition(Sci_Position pos) const {
return cb.LineFromPosition(pos);
}
@@ -1485,6 +1492,7 @@ Sci::Position Document::InsertString(Sci::Position position, const char *s, Sci:
if (insertLength <= 0) {
return 0;
}
+ CheckPosition(position);
CheckReadOnly(); // Application may change read only state here
if (cb.IsReadOnly()) {
return 0;
@@ -1907,8 +1915,7 @@ std::string Document::TransformLineEnds(const char *s, size_t len, EndOfLine eol
void Document::ConvertLineEnds(EndOfLine eolModeSet) {
UndoGroup ug(this);
- const Sci::Position length = Length();
- for (Sci::Position pos = 0; pos < length; pos++) {
+ for (Sci::Position pos = 0; pos < LengthNoExcept(); pos++) {
const char ch = cb.CharAt(pos);
if (ch == '\r') {
if (cb.CharAt(pos + 1) == '\n') {
@@ -2572,10 +2579,10 @@ bool SCI_METHOD Document::SetStyleFor(Sci_Position length, char style) {
return false;
}
enteredStyling++;
- const Sci::Position prevEndStyled = endStyled;
- if (cb.SetStyleFor(endStyled, length, style)) {
+ const ChangedRange cr = cb.SetStyleFor(endStyled, length, style);
+ if (!cr.Empty()) {
const DocModification mh(ModificationFlags::ChangeStyle | ModificationFlags::User,
- prevEndStyled, length);
+ cr.start, cr.end - cr.start + 1);
NotifyModified(mh);
}
endStyled += length;
@@ -2588,22 +2595,11 @@ bool SCI_METHOD Document::SetStyles(Sci_Position length, const char *styles) {
return false;
}
enteredStyling++;
- bool didChange = false;
- Sci::Position startMod = 0;
- Sci::Position endMod = 0;
- for (int iPos = 0; iPos < length; iPos++, endStyled++) {
- PLATFORM_ASSERT(endStyled < Length());
- if (cb.SetStyleAt(endStyled, styles[iPos])) {
- if (!didChange) {
- startMod = endStyled;
- }
- didChange = true;
- endMod = endStyled;
- }
- }
- if (didChange) {
+ const ChangedRange cr = cb.SetStyles(endStyled, styles, length);
+ endStyled += length;
+ if (!cr.Empty()) {
const DocModification mh(ModificationFlags::ChangeStyle | ModificationFlags::User,
- startMod, endMod - startMod + 1);
+ cr.start, cr.end - cr.start + 1);
NotifyModified(mh);
}
enteredStyling--;
@@ -3022,7 +3018,7 @@ Sci::Position Document::BraceMatch(Sci::Position position, Sci::Position /*maxRe
return -1;
const int styBrace = StyleIndexAt(position);
int direction = -1;
- if (chBrace == '(' || chBrace == '[' || chBrace == '{' || chBrace == '<')
+ if (AnyOf(chBrace, '(', '[', '{', '<'))
direction = 1;
int depth = 1;
position = useStartPos ? startPos : position + direction;
@@ -3035,7 +3031,7 @@ Sci::Position Document::BraceMatch(Sci::Position position, Sci::Position /*maxRe
while ((position >= 0) && (position < LengthNoExcept())) {
const unsigned char chAtPos = CharAt(position);
- if (chAtPos == chBrace || chAtPos == chSeek) {
+ if (AnyOf(chAtPos, chBrace, chSeek)) {
if (((position > GetEndStyled()) || (StyleIndexAt(position) == styBrace)) &&
(chAtPos <= maxSafeChar || position == MovePositionOutsideChar(position, direction, false))) {
depth += (chAtPos == chBrace) ? 1 : -1;
@@ -3141,7 +3137,9 @@ public:
const Document *doc;
Sci::Position position;
- explicit ByteIterator(const Document *doc_=nullptr, Sci::Position position_=0) noexcept :
+ ByteIterator() noexcept :
+ ByteIterator(nullptr) {}
+ explicit ByteIterator(const Document *doc_, Sci::Position position_=0) noexcept :
doc(doc_), position(position_) {
}
char operator*() const noexcept {
@@ -3206,7 +3204,9 @@ public:
using pointer = wchar_t*;
using reference = wchar_t&;
- explicit UTF8Iterator(const Document *doc_=nullptr, Sci::Position position_=0) noexcept :
+ UTF8Iterator() noexcept :
+ UTF8Iterator(nullptr) {}
+ explicit UTF8Iterator(const Document *doc_, Sci::Position position_=0) noexcept :
doc(doc_), position(position_) {
if (doc) {
ReadCharacter();
@@ -3295,7 +3295,9 @@ public:
using pointer = wchar_t*;
using reference = wchar_t&;
- explicit UTF8Iterator(const Document *doc_=nullptr, Sci::Position position_=0) noexcept :
+ UTF8Iterator() noexcept :
+ UTF8Iterator(nullptr) {}
+ explicit UTF8Iterator(const Document *doc_, Sci::Position position_=0) noexcept :
doc(doc_), position(position_) {
}
wchar_t operator*() const noexcept {
diff --git a/src/Document.h b/src/Document.h
index 7fd150f37..dfb0a7ff5 100644
--- a/src/Document.h
+++ b/src/Document.h
@@ -369,6 +369,7 @@ public:
int SCI_METHOD DEVersion() const noexcept override;
void SCI_METHOD SetErrorStatus(int status) override;
+ void CheckPosition(Sci::Position pos) const;
Sci_Position SCI_METHOD LineFromPosition(Sci_Position pos) const override;
Sci::Line SciLineFromPosition(Sci::Position pos) const noexcept; // Avoids casting LineFromPosition
diff --git a/src/EditView.cxx b/src/EditView.cxx
index 2608f11e5..b25053845 100644
--- a/src/EditView.cxx
+++ b/src/EditView.cxx
@@ -352,7 +352,7 @@ void LayoutSegments(IPositionCache *pCache,
XYPOSITION representationWidth = 0.0;
// Tab is a special case of representation, taking a variable amount of space
// which will be filled in later.
- if (ll->chars[ts.start] != '\t') {
+ if (ll->chars[ts.start] != '\t' || vstyle.tabDrawMode == TabDrawMode::ControlChar) {
representationWidth = vstyle.controlCharWidth;
if (representationWidth <= 0.0) {
assert(ts.representation->stringRep.length() <= Representation::maxLength);
@@ -522,7 +522,7 @@ void EditView::LayoutLine(const EditModel &model, Surface *surface, const ViewSt
for (const TextSegment &ts : segments) {
if (vstyle.styles[ll->styles[ts.start]].visible &&
ts.representation &&
- (ll->chars[ts.start] == '\t')) {
+ ll->chars[ts.start] == '\t' && vstyle.tabDrawMode != TabDrawMode::ControlChar) {
// Simple visible tab, go to next tab stop
const XYPOSITION startTab = ll->positions[ts.start];
const XYPOSITION nextTab = NextTabstopPos(line, startTab, vstyle.tabWidth);
@@ -610,7 +610,7 @@ void EditView::UpdateBidiData(const EditModel &model, const ViewStyle &vstyle, L
const Representation *repr = model.reprs->RepresentationFromCharacter(std::string_view(&ll->chars[charsInLine], charWidth));
ll->bidiData->widthReprs[charsInLine] = 0.0f;
- if (repr && ll->chars[charsInLine] != '\t') {
+ if (repr && (ll->chars[charsInLine] != '\t' || vstyle.tabDrawMode == TabDrawMode::ControlChar)) {
ll->bidiData->widthReprs[charsInLine] = ll->positions[charsInLine + charWidth] - ll->positions[charsInLine];
}
if (charWidth > 1) {
@@ -1286,6 +1286,7 @@ void EditView::DrawEOLAnnotationText(Surface *surface, const EditModel &model, c
// it may be double drawing. This is to allow stadiums with
// curved or angled ends to have the area outside in the correct
// background colour.
+ surface->FillRectangleAligned(rcSegment, Fill(textBack));
FillLineRemainder(surface, model, vsDraw, ll, line, rcLine, rcSegment.right, subLine);
}
@@ -1346,7 +1347,7 @@ void EditView::DrawEOLAnnotationText(Surface *surface, const EditModel &model, c
namespace {
constexpr bool AnnotationBoxedOrIndented(AnnotationVisible annotationVisible) noexcept {
- return annotationVisible == AnnotationVisible::Boxed || annotationVisible == AnnotationVisible::Indented;
+ return AnyOf(annotationVisible, AnnotationVisible::Boxed, AnnotationVisible::Indented);
}
}
@@ -1673,7 +1674,7 @@ void DrawBackground(Surface *surface, const EditModel &model, const ViewStyle &v
ColourRGBA textBack = TextBackground(model, vsDraw, ll, background, inSelection,
inHotspot, ll->styles[i], i);
if (ts.representation) {
- if (ll->chars[i] == '\t') {
+ if (ll->chars[i] == '\t' && vsDraw.tabDrawMode != TabDrawMode::ControlChar) {
// Tab display
if (drawWhitespaceBackground && vsDraw.WhiteSpaceVisible(inIndentation)) {
textBack = vsDraw.ElementColourForced(Element::WhiteSpaceBack).Opaque();
@@ -1682,21 +1683,27 @@ void DrawBackground(Surface *surface, const EditModel &model, const ViewStyle &v
// Blob display
inIndentation = false;
}
- surface->FillRectangleAligned(rcSegment, Fill(textBack));
- } else {
+ }
+ surface->FillRectangleAligned(rcSegment, Fill(textBack));
+ if (!ts.representation) {
// Normal text display
- surface->FillRectangleAligned(rcSegment, Fill(textBack));
if (vsDraw.viewWhitespace != WhiteSpace::Invisible) {
- for (int cpos = 0; cpos <= i - ts.start; cpos++) {
- if (ll->chars[cpos + ts.start] == ' ') {
+ for (int cpos = 0; cpos <= i - ts.start; ) {
+ int countSpaces = 0;
+ while ((countSpaces <= i - ts.start - cpos) && (ll->chars[cpos + ts.start + countSpaces] == ' ')) {
+ countSpaces++;
+ }
+ if (countSpaces) {
if (drawWhitespaceBackground && vsDraw.WhiteSpaceVisible(inIndentation)) {
const PRectangle rcSpace = Intersection(rcLine,
- ll->SpanByte(cpos + ts.start).Offset(horizontalOffset));
+ ll->Span(cpos + ts.start, cpos + ts.start + countSpaces).Offset(horizontalOffset));
surface->FillRectangleAligned(rcSpace,
vsDraw.ElementColourForced(Element::WhiteSpaceBack).Opaque());
}
+ cpos += countSpaces;
} else {
inIndentation = false;
+ cpos++;
}
}
}
@@ -2178,7 +2185,7 @@ void EditView::DrawForeground(Surface *surface, const EditModel &model, const Vi
}
ColourRGBA textBack = TextBackground(model, vsDraw, ll, background, inSelection, inHotspot, styleMain, i);
if (ts.representation) {
- if (ll->chars[i] == '\t') {
+ if (ll->chars[i] == '\t' && vsDraw.tabDrawMode != TabDrawMode::ControlChar) {
// Tab display
if (phasesDraw == PhasesDraw::One) {
if (drawWhitespaceBackground && vsDraw.WhiteSpaceVisible(inIndentation))
@@ -2310,7 +2317,7 @@ void EditView::DrawForeground(Surface *surface, const EditModel &model, const Vi
void EditView::DrawIndentGuidesOverEmpty(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll,
Sci::Line line, int xStart, PRectangle rcLine, int subLine, Sci::Line lineVisible) {
- if ((vsDraw.viewIndentationGuides == IndentView::LookForward || vsDraw.viewIndentationGuides == IndentView::LookBoth)
+ if (AnyOf(vsDraw.viewIndentationGuides, IndentView::LookForward, IndentView::LookBoth)
&& (subLine == 0)) {
const Sci::Position posLineStart = model.pdoc->LineStart(line);
int indentSpace = model.pdoc->GetLineIndentation(line);
@@ -2525,14 +2532,14 @@ void EditView::PaintText(Surface *surfaceWindow, const EditModel &model, const V
for (;;) {
int yposScreen = screenLinePaintFirst * vsDraw.lineHeight;
int ypos = bufferedDraw ? 0 : yposScreen;
- Sci::Line visibleLine = model.TopLineOfMain() + screenLinePaintFirst;
- while (visibleLine < model.pcs->LinesDisplayed() && yposScreen < rcArea.bottom) {
+ Sci::Line lineVisible = model.TopLineOfMain() + screenLinePaintFirst;
+ while (lineVisible < model.pcs->LinesDisplayed() && yposScreen < rcArea.bottom) {
- const Sci::Line lineDoc = model.pcs->DocFromDisplay(visibleLine);
+ const Sci::Line lineDoc = model.pcs->DocFromDisplay(lineVisible);
// Only visible lines should be handled by the code within the loop
PLATFORM_ASSERT(model.pcs->GetVisible(lineDoc));
const Sci::Line lineStartSet = model.pcs->DisplayFromDoc(lineDoc);
- const int subLine = static_cast<int>(visibleLine - lineStartSet);
+ const int subLine = static_cast<int>(lineVisible - lineStartSet);
// Copy this line and its styles from the document into local arrays
// and determine the x position at which each character starts.
@@ -2574,7 +2581,7 @@ void EditView::PaintText(Surface *surfaceWindow, const EditModel &model, const V
surface->FillRectangleAligned(rcSpacer, Fill(vsDraw.styles[StyleDefault].back));
}
- DrawLine(surface, model, vsDraw, ll.get(), lineDoc, visibleLine, xOrigin, rcLine, subLine, phase);
+ DrawLine(surface, model, vsDraw, ll.get(), lineDoc, lineVisible, xOrigin, rcLine, subLine, phase);
#if defined(TIME_PAINTING)
durPaint += ep.Duration(true);
#endif
@@ -2609,7 +2616,7 @@ void EditView::PaintText(Surface *surfaceWindow, const EditModel &model, const V
}
yposScreen += vsDraw.lineHeight;
- visibleLine++;
+ lineVisible++;
}
if (phase >= DrawPhase::carets) {
@@ -2704,7 +2711,7 @@ Sci::Position EditView::FormatRange(bool draw, CharacterRangeFull chrg, Rectangl
} else if (colourMode == PrintOption::BlackOnWhite) {
it->fore = black;
it->back = white;
- } else if (colourMode == PrintOption::ColourOnWhite || colourMode == PrintOption::ColourOnWhiteDefaultBG) {
+ } else if (AnyOf(colourMode, PrintOption::ColourOnWhite, PrintOption::ColourOnWhiteDefaultBG)) {
it->back = white;
}
}
@@ -2756,7 +2763,7 @@ Sci::Position EditView::FormatRange(bool draw, CharacterRangeFull chrg, Rectangl
Sci::Line lineDoc = linePrintStart;
Sci::Position nPrintPos = chrg.cpMin;
- int visibleLine = 0;
+ int lineVisible = 0;
int widthPrint = rc.right - rc.left - vsPrint.fixedColumnWidth;
if (printParameters.wrapState == Wrap::None)
widthPrint = LineLayout::wrapWidthInfinite;
@@ -2785,23 +2792,23 @@ Sci::Position EditView::FormatRange(bool draw, CharacterRangeFull chrg, Rectangl
// When document line is wrapped over multiple display lines, find where
// to start printing from to ensure a particular position is on the first
// line of the page.
- if (visibleLine == 0) {
+ if (lineVisible == 0) {
const Sci::Position startWithinLine = nPrintPos -
model.pdoc->LineStart(lineDoc);
for (int iwl = 0; iwl < ll.lines - 1; iwl++) {
if (ll.LineStart(iwl) <= startWithinLine && ll.LineStart(iwl + 1) >= startWithinLine) {
- visibleLine = -iwl;
+ lineVisible = -iwl;
}
}
if (ll.lines > 1 && startWithinLine >= ll.LineStart(ll.lines - 1)) {
- visibleLine = -(ll.lines - 1);
+ lineVisible = -(ll.lines - 1);
}
}
if (draw && lineNumberWidth &&
(ypos + vsPrint.lineHeight <= rc.bottom) &&
- (visibleLine >= 0)) {
+ (lineVisible >= 0)) {
const std::string number = std::to_string(lineDoc + 1) + lineNumberPrintSpace;
PRectangle rcNumber = rcLine;
rcNumber.right = rcNumber.left + lineNumberWidth;
@@ -2820,15 +2827,15 @@ Sci::Position EditView::FormatRange(bool draw, CharacterRangeFull chrg, Rectangl
for (int iwl = 0; iwl < ll.lines; iwl++) {
if (ypos + vsPrint.lineHeight <= rc.bottom) {
- if (visibleLine >= 0) {
+ if (lineVisible >= 0) {
if (draw) {
rcLine.top = static_cast<XYPOSITION>(ypos);
rcLine.bottom = static_cast<XYPOSITION>(ypos + vsPrint.lineHeight);
- DrawLine(surface, model, vsPrint, &ll, lineDoc, visibleLine, xOrigin, rcLine, iwl, DrawPhase::all);
+ DrawLine(surface, model, vsPrint, &ll, lineDoc, lineVisible, xOrigin, rcLine, iwl, DrawPhase::all);
}
ypos += vsPrint.lineHeight;
}
- visibleLine++;
+ lineVisible++;
if (iwl == ll.lines - 1)
nPrintPos = model.pdoc->LineStart(lineDoc + 1);
else
diff --git a/src/Editor.cxx b/src/Editor.cxx
index 5b42407e3..1dfa8fd6b 100644
--- a/src/Editor.cxx
+++ b/src/Editor.cxx
@@ -3818,7 +3818,7 @@ int Editor::DelWordOrLine(Message iMessage) {
// Rightwards and leftwards deletions differ in treatment of virtual space.
// Clear virtual space for leftwards, realise for rightwards.
- const bool leftwards = (iMessage == Message::DelWordLeft) || (iMessage == Message::DelLineLeft);
+ const bool leftwards = AnyOf(iMessage, Message::DelWordLeft, Message::DelLineLeft);
if (!additionalSelectionTyping) {
InvalidateWholeSelection();
@@ -4029,14 +4029,14 @@ int Editor::KeyCommand(Message iMessage) {
break;
case Message::DeleteBack:
DelCharBack(true);
- if ((caretSticky == CaretSticky::Off) || (caretSticky == CaretSticky::WhiteSpace)) {
+ if (AnyOf(caretSticky, CaretSticky::Off, CaretSticky::WhiteSpace)) {
SetLastXChosen();
}
EnsureCaretVisible();
break;
case Message::DeleteBackNotLine:
DelCharBack(false);
- if ((caretSticky == CaretSticky::Off) || (caretSticky == CaretSticky::WhiteSpace)) {
+ if (AnyOf(caretSticky, CaretSticky::Off, CaretSticky::WhiteSpace)) {
SetLastXChosen();
}
EnsureCaretVisible();
@@ -4053,7 +4053,7 @@ int Editor::KeyCommand(Message iMessage) {
case Message::BackTab:
case Message::LineDedent:
Indent(false, iMessage == Message::LineDedent);
- if ((caretSticky == CaretSticky::Off) || (caretSticky == CaretSticky::WhiteSpace)) {
+ if (AnyOf(caretSticky, CaretSticky::Off, CaretSticky::WhiteSpace)) {
SetLastXChosen();
}
EnsureCaretVisible();
@@ -4859,7 +4859,7 @@ void Editor::ButtonDownWithModifiers(Point pt, unsigned int curTime, KeyMod modi
wordSelectAnchorEndPos = endWord;
wordSelectInitialCaretPos = sel.MainCaret();
WordSelection(wordSelectInitialCaretPos);
- } else if (selectionUnit == TextUnit::subLine || selectionUnit == TextUnit::wholeLine) {
+ } else if (AnyOf(selectionUnit, TextUnit::subLine, TextUnit::wholeLine)) {
lineAnchorPos = newPos.Position();
LineSelection(lineAnchorPos, lineAnchorPos, selectionUnit == TextUnit::wholeLine);
//Platform::DebugPrintf("Triple click: %d - %d\n", anchor, currentPos);
@@ -4919,7 +4919,7 @@ void Editor::ButtonDownWithModifiers(Point pt, unsigned int curTime, KeyMod modi
// Switch to just the click position
SetSelection(newPos, newPos);
}
- if (!sel.Range(selectionPart).Empty()) {
+ if (dragDropEnabled && !sel.Range(selectionPart).Empty()) {
inDragDrop = DragDrop::initial;
}
}
@@ -5395,7 +5395,7 @@ Sci::Position Editor::PositionAfterMaxStyling(Sci::Position posMax, bool scrolli
}
void Editor::StartIdleStyling(bool truncatedLastStyling) {
- if ((idleStyling == IdleStyling::All) || (idleStyling == IdleStyling::AfterVisible)) {
+ if (AnyOf(idleStyling, IdleStyling::All, IdleStyling::AfterVisible)) {
if (pdoc->GetEndStyled() < pdoc->Length()) {
// Style remainder of document in idle time
needIdleStyling = true;
@@ -5899,6 +5899,8 @@ Sci::Position Editor::GetTag(char *tagValue, int tagNumber) {
}
Sci::Position Editor::ReplaceTarget(ReplaceType replaceType, std::string_view text) {
+ pdoc->CheckPosition(targetRange.start.Position());
+
UndoGroup ug(pdoc);
std::string substituted; // Copy in case of re-entrance
@@ -6344,7 +6346,7 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
case Message::Paste:
Paste();
- if ((caretSticky == CaretSticky::Off) || (caretSticky == CaretSticky::WhiteSpace)) {
+ if (AnyOf(caretSticky, CaretSticky::Off, CaretSticky::WhiteSpace)) {
SetLastXChosen();
}
EnsureCaretVisible();
@@ -6697,6 +6699,7 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
Sci::Position insertPos = PositionFromUPtr(wParam);
if (insertPos == -1)
insertPos = CurrentPosition();
+ pdoc->CheckPosition(insertPos);
Sci::Position newCurrent = CurrentPosition();
const char *sz = ConstCharPtrFromSPtr(lParam);
const Sci::Position lengthInserted = pdoc->InsertString(insertPos, sz, strlen(sz));
@@ -6984,7 +6987,7 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
return static_cast<sptr_t>(vs.tabDrawMode);
case Message::SetTabDrawMode:
- vs.tabDrawMode = static_cast<TabDrawMode>(wParam);
+ SetAppearance(vs.tabDrawMode, static_cast<TabDrawMode>(wParam));
Redraw();
break;
diff --git a/src/Editor.h b/src/Editor.h
index 95b83f1f7..0243d5b63 100644
--- a/src/Editor.h
+++ b/src/Editor.h
@@ -16,7 +16,7 @@ class Timer {
public:
bool ticking;
int ticksToWait;
- enum {tickSize = 100};
+ static constexpr int tickSize = 100;
TickerID tickerID;
Timer() noexcept;
@@ -226,7 +226,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
Timer timer;
Timer autoScrollTimer;
- enum { autoScrollDelay = 200 };
+ static constexpr int autoScrollDelay = 200;
Idler idler;