From 8f0909685dad46096ecf92152e82d309b0852bfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrico=20Tr=C3=B6ger?= Date: Sat, 26 Sep 2020 10:03:07 +0000 Subject: [PATCH] Update Scintilla to version 3.21.1 (#2506) --- scintilla/Makefile.am | 1 + scintilla/gtk/Converter.h | 5 + scintilla/gtk/PlatGTK.cxx | 159 ++-- scintilla/gtk/ScintillaGTK.cxx | 185 ++--- scintilla/gtk/ScintillaGTK.h | 19 +- scintilla/gtk/ScintillaGTKAccessible.cxx | 9 +- scintilla/gtk/ScintillaGTKAccessible.h | 2 +- scintilla/include/Compat.h | 70 ++ scintilla/include/ILexer.h | 9 +- scintilla/include/Makefile.am | 1 + scintilla/include/Platform.h | 70 +- scintilla/include/SciLexer.h | 73 ++ scintilla/include/Scintilla.h | 76 +- scintilla/include/Scintilla.iface | 905 ++++++++++++++++------- scintilla/lexers/LexAbaqus.cxx | 2 +- scintilla/lexers/LexAsm.cxx | 21 +- scintilla/lexers/LexBash.cxx | 7 +- scintilla/lexers/LexBasic.cxx | 15 +- scintilla/lexers/LexBatch.cxx | 838 +++++++++++---------- scintilla/lexers/LexCPP.cxx | 81 +- scintilla/lexers/LexCmake.cxx | 5 +- scintilla/lexers/LexD.cxx | 6 +- scintilla/lexers/LexHTML.cxx | 62 +- scintilla/lexers/LexHaskell.cxx | 9 +- scintilla/lexers/LexLaTeX.cxx | 21 + scintilla/lexers/LexMatlab.cxx | 2 +- scintilla/lexers/LexPerl.cxx | 41 +- scintilla/lexers/LexProps.cxx | 18 +- scintilla/lexers/LexPython.cxx | 94 +-- scintilla/lexers/LexR.cxx | 2 +- scintilla/lexers/LexRuby.cxx | 6 +- scintilla/lexers/LexRust.cxx | 7 +- scintilla/lexers/LexSQL.cxx | 17 +- scintilla/lexers/LexTCL.cxx | 5 +- scintilla/lexers/LexVHDL.cxx | 4 +- scintilla/lexers/LexVerilog.cxx | 6 +- scintilla/lexlib/CatalogueModules.h | 70 ++ scintilla/lexlib/CharacterCategory.cxx | 175 +++-- scintilla/lexlib/CharacterCategory.h | 2 +- scintilla/lexlib/CharacterSet.cxx | 4 +- scintilla/lexlib/CharacterSet.h | 75 +- scintilla/lexlib/DefaultLexer.cxx | 20 +- scintilla/lexlib/DefaultLexer.h | 10 +- scintilla/lexlib/LexAccessor.h | 12 +- scintilla/lexlib/LexerBase.cxx | 21 +- scintilla/lexlib/LexerBase.h | 6 +- scintilla/lexlib/LexerModule.cxx | 17 +- scintilla/lexlib/LexerModule.h | 29 +- scintilla/lexlib/LexerSimple.cxx | 8 + scintilla/lexlib/LexerSimple.h | 3 + scintilla/lexlib/OptionSet.h | 21 +- scintilla/lexlib/PropSetSimple.cxx | 18 +- scintilla/lexlib/PropSetSimple.h | 2 +- scintilla/lexlib/SparseState.h | 8 +- scintilla/lexlib/StyleContext.h | 10 +- scintilla/lexlib/SubStyles.h | 34 +- scintilla/lexlib/WordList.cxx | 58 +- scintilla/lexlib/WordList.h | 18 +- scintilla/scintilla_changes.patch | 6 +- scintilla/src/AutoComplete.h | 4 +- scintilla/src/CallTip.cxx | 242 +++--- scintilla/src/CallTip.h | 35 +- scintilla/src/CaseConvert.cxx | 19 +- scintilla/src/CaseConvert.h | 2 +- scintilla/src/CaseFolder.cxx | 4 +- scintilla/src/CaseFolder.h | 4 +- scintilla/src/Catalogue.cxx | 40 +- scintilla/src/Catalogue.h | 2 +- scintilla/src/CellBuffer.cxx | 312 +++++--- scintilla/src/CellBuffer.h | 55 +- scintilla/src/CharClassify.cxx | 4 +- scintilla/src/CharClassify.h | 6 +- scintilla/src/ContractionState.cxx | 82 +- scintilla/src/ContractionState.h | 24 +- scintilla/src/Decoration.cxx | 66 +- scintilla/src/Decoration.h | 32 +- scintilla/src/Document.cxx | 277 ++++--- scintilla/src/Document.h | 109 +-- scintilla/src/EditModel.cxx | 5 +- scintilla/src/EditModel.h | 5 +- scintilla/src/EditView.cxx | 290 +++++--- scintilla/src/EditView.h | 10 +- scintilla/src/Editor.cxx | 518 ++++++++----- scintilla/src/Editor.h | 64 +- scintilla/src/ElapsedPeriod.h | 2 +- scintilla/src/ExternalLexer.cxx | 108 ++- scintilla/src/ExternalLexer.h | 58 +- scintilla/src/Indicator.cxx | 356 +++++---- scintilla/src/Indicator.h | 14 +- scintilla/src/KeyMap.cxx | 4 +- scintilla/src/KeyMap.h | 6 +- scintilla/src/LineMarker.cxx | 632 +++++++++------- scintilla/src/LineMarker.h | 6 +- scintilla/src/MarginView.cxx | 31 +- scintilla/src/Partitioning.h | 58 +- scintilla/src/PerLine.cxx | 176 +++-- scintilla/src/PerLine.h | 36 +- scintilla/src/Position.h | 5 - scintilla/src/PositionCache.cxx | 57 +- scintilla/src/PositionCache.h | 27 +- scintilla/src/RESearch.cxx | 26 +- scintilla/src/RESearch.h | 26 +- scintilla/src/RunStyles.cxx | 8 +- scintilla/src/ScintillaBase.cxx | 47 +- scintilla/src/ScintillaBase.h | 7 +- scintilla/src/Selection.cxx | 100 +-- scintilla/src/Selection.h | 125 ++-- scintilla/src/SparseVector.h | 103 ++- scintilla/src/SplitVector.h | 14 +- scintilla/src/Style.cxx | 10 +- scintilla/src/Style.h | 11 +- scintilla/src/UniConversion.cxx | 2 +- scintilla/src/UniConversion.h | 17 +- scintilla/src/UniqueString.cxx | 6 +- scintilla/src/UniqueString.h | 4 +- scintilla/src/ViewStyle.cxx | 72 +- scintilla/src/ViewStyle.h | 18 +- scintilla/src/XPM.cxx | 37 +- scintilla/src/XPM.h | 28 +- scintilla/version.txt | 2 +- 120 files changed, 4919 insertions(+), 3011 deletions(-) create mode 100644 scintilla/include/Compat.h create mode 100644 scintilla/lexlib/CatalogueModules.h diff --git a/scintilla/Makefile.am b/scintilla/Makefile.am index a5b7e9627e..d7a179247a 100644 --- a/scintilla/Makefile.am +++ b/scintilla/Makefile.am @@ -60,6 +60,7 @@ gtk/scintilla-marshal.c \ gtk/scintilla-marshal.h \ lexlib/Accessor.cxx \ lexlib/Accessor.h \ +lexlib/CatalogueModules.h \ lexlib/CharacterCategory.cxx \ lexlib/CharacterCategory.h \ lexlib/CharacterSet.cxx \ diff --git a/scintilla/gtk/Converter.h b/scintilla/gtk/Converter.h index eb665b4b6e..30bb781ac0 100644 --- a/scintilla/gtk/Converter.h +++ b/scintilla/gtk/Converter.h @@ -29,6 +29,11 @@ class Converter { iconvh = iconvhBad; Open(charSetDestination, charSetSource, transliterations); } + // Deleted so Converter objects can not be copied. + Converter(const Converter &) = delete; + Converter(Converter &&) = delete; + Converter &operator=(const Converter &) = delete; + Converter &operator=(Converter &&) = delete; ~Converter() { Close(); } diff --git a/scintilla/gtk/PlatGTK.cxx b/scintilla/gtk/PlatGTK.cxx index 3e18423dad..b999feeee0 100644 --- a/scintilla/gtk/PlatGTK.cxx +++ b/scintilla/gtk/PlatGTK.cxx @@ -42,16 +42,16 @@ using namespace Scintilla; namespace { -const double kPi = 3.14159265358979323846; +constexpr double kPi = 3.14159265358979323846; // The Pango version guard for pango_units_from_double and pango_units_to_double // is more complex than simply implementing these here. -int pangoUnitsFromDouble(double d) noexcept { +constexpr int pangoUnitsFromDouble(double d) noexcept { return static_cast(d * PANGO_SCALE + 0.5); } -float floatFromPangoUnits(int pu) noexcept { +constexpr float floatFromPangoUnits(int pu) noexcept { return static_cast(pu) / PANGO_SCALE; } @@ -80,6 +80,11 @@ class FontHandle { pfd = pfd_; characterSet = characterSet_; } + // Deleted so FontHandle objects can not be copied. + FontHandle(const FontHandle &) = delete; + FontHandle(FontHandle &&) = delete; + FontHandle &operator=(const FontHandle &) = delete; + FontHandle &operator=(FontHandle &&) = delete; ~FontHandle() { if (pfd) pango_font_description_free(pfd); @@ -103,7 +108,7 @@ FontHandle *FontHandle::CreateNewFont(const FontParameters &fp) { } // X has a 16 bit coordinate space, so stop drawing here to avoid wrapping -const int maxCoordinate = 32000; +constexpr int maxCoordinate = 32000; FontHandle *PFont(const Font &f) noexcept { return static_cast(f.GetID()); @@ -145,6 +150,11 @@ class SurfaceImpl : public Surface { void SetConverter(int characterSet_); public: SurfaceImpl() noexcept; + // Deleted so SurfaceImpl objects can not be copied. + SurfaceImpl(const SurfaceImpl&) = delete; + SurfaceImpl(SurfaceImpl&&) = delete; + SurfaceImpl&operator=(const SurfaceImpl&) = delete; + SurfaceImpl&operator=(SurfaceImpl&&) = delete; ~SurfaceImpl() override; void Init(WindowID wid) override; @@ -171,7 +181,7 @@ class SurfaceImpl : public Surface { void Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back) override; void Copy(PRectangle rc, Point from, Surface &surfaceSource) override; - void DrawTextBase(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore); + void DrawTextBase(PRectangle rc, const Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore); void DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back) override; void DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back) override; void DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore) override; @@ -292,7 +302,7 @@ bool SurfaceImpl::Initialised() { if (inited && context) { if (cairo_status(context) == CAIRO_STATUS_SUCCESS) { // Even when status is success, the target surface may have been - // finished whch may cause an assertion to fail crashing the application. + // finished which may cause an assertion to fail crashing the application. // The cairo_surface_has_show_text_glyphs call checks the finished flag // and when set, sets the status to CAIRO_STATUS_SURFACE_FINISHED // which leads to warning messages instead of crashes. @@ -339,7 +349,8 @@ void SurfaceImpl::Init(SurfaceID sid, WindowID wid) { void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_, WindowID wid) { PLATFORM_ASSERT(surface_); Release(); - SurfaceImpl *surfImpl = static_cast(surface_); + SurfaceImpl *surfImpl = dynamic_cast(surface_); + PLATFORM_ASSERT(surfImpl); PLATFORM_ASSERT(wid); context = cairo_reference(surfImpl->context); pcontext = gtk_widget_create_pango_context(PWidget(wid)); @@ -448,7 +459,7 @@ void SurfaceImpl::Polygon(Point *pts, size_t npts, ColourDesired fore, void SurfaceImpl::RectangleDraw(PRectangle rc, ColourDesired fore, ColourDesired back) { if (context) { cairo_rectangle(context, rc.left + 0.5, rc.top + 0.5, - rc.right - rc.left - 1, rc.bottom - rc.top - 1); + rc.Width() - 1, rc.Height() - 1); PenColour(back); cairo_fill_preserve(context); PenColour(fore); @@ -459,37 +470,21 @@ void SurfaceImpl::RectangleDraw(PRectangle rc, ColourDesired fore, ColourDesired void SurfaceImpl::FillRectangle(PRectangle rc, ColourDesired back) { PenColour(back); if (context && (rc.left < maxCoordinate)) { // Protect against out of range - rc.left = std::round(rc.left); - rc.right = std::round(rc.right); - cairo_rectangle(context, rc.left, rc.top, - rc.right - rc.left, rc.bottom - rc.top); + rc.left = Sci::round(rc.left); + rc.right = Sci::round(rc.right); + cairo_rectangle(context, rc.left, rc.top, rc.Width(), rc.Height()); cairo_fill(context); } } void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) { - SurfaceImpl &surfi = static_cast(surfacePattern); - const bool canDraw = surfi.psurf != nullptr; - if (canDraw) { - PLATFORM_ASSERT(context); + SurfaceImpl &surfi = dynamic_cast(surfacePattern); + if (context && surfi.psurf) { // Tile pattern over rectangle - // Currently assumes 8x8 pattern - const int widthPat = 8; - const int heightPat = 8; - const IntegerRectangle irc(rc); - for (int xTile = irc.left; xTile < irc.right; xTile += widthPat) { - const int widthx = (xTile + widthPat > irc.right) ? irc.right - xTile : widthPat; - for (int yTile = irc.top; yTile < irc.bottom; yTile += heightPat) { - const int heighty = (yTile + heightPat > irc.bottom) ? irc.bottom - yTile : heightPat; - cairo_set_source_surface(context, surfi.psurf, xTile, yTile); - cairo_rectangle(context, xTile, yTile, widthx, heighty); - cairo_fill(context); - } - } - } else { - // Something is wrong so try to show anyway - // Shows up black because colour not allocated - FillRectangle(rc, ColourDesired(0)); + cairo_set_source_surface(context, surfi.psurf, rc.left, rc.top); + cairo_pattern_set_extend(cairo_get_source(context), CAIRO_EXTEND_REPEAT); + cairo_rectangle(context, rc.left, rc.top, rc.Width(), rc.Height()); + cairo_fill(context); } } @@ -506,14 +501,14 @@ void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourDesired fore, ColourDesi Point(rc.left, rc.bottom - 2), Point(rc.left, rc.top + 2), }; - Polygon(pts, ELEMENTS(pts), fore, back); + Polygon(pts, Sci::size(pts), fore, back); } else { RectangleDraw(rc, fore, back); } } -static void PathRoundRectangle(cairo_t *context, double left, double top, double width, double height, int radius) noexcept { - const double degrees = kPi / 180.0; +static void PathRoundRectangle(cairo_t *context, double left, double top, double width, double height, double radius) noexcept { + constexpr double degrees = kPi / 180.0; cairo_new_sub_path(context); cairo_arc(context, left + width - radius, top + radius, radius, -90 * degrees, 0 * degrees); @@ -533,9 +528,9 @@ void SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize, ColourDesired fi cdFill.GetBlue() / 255.0, alphaFill / 255.0); if (cornerSize > 0) - PathRoundRectangle(context, rc.left + 1.0, rc.top + 1.0, rc.right - rc.left - 2.0, rc.bottom - rc.top - 2.0, cornerSize); + PathRoundRectangle(context, rc.left + 1.0, rc.top + 1.0, rc.Width() - 2.0, rc.Height() - 2.0, cornerSize); else - cairo_rectangle(context, rc.left + 1.0, rc.top + 1.0, rc.right - rc.left - 2.0, rc.bottom - rc.top - 2.0); + cairo_rectangle(context, rc.left + 1.0, rc.top + 1.0, rc.Width() - 2.0, rc.Height() - 2.0); cairo_fill(context); const ColourDesired cdOutline(outline.AsInteger()); @@ -545,9 +540,9 @@ void SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize, ColourDesired fi cdOutline.GetBlue() / 255.0, alphaOutline / 255.0); if (cornerSize > 0) - PathRoundRectangle(context, rc.left + 0.5, rc.top + 0.5, rc.right - rc.left - 1, rc.bottom - rc.top - 1, cornerSize); + PathRoundRectangle(context, rc.left + 0.5, rc.top + 0.5, rc.Width() - 1, rc.Height() - 1, cornerSize); else - cairo_rectangle(context, rc.left + 0.5, rc.top + 0.5, rc.right - rc.left - 1, rc.bottom - rc.top - 1); + cairo_rectangle(context, rc.left + 0.5, rc.top + 0.5, rc.Width() - 1, rc.Height() - 1); cairo_stroke(context); } } @@ -587,23 +582,18 @@ void SurfaceImpl::DrawRGBAImage(PRectangle rc, int width, int height, const unsi rc.top += (rc.Height() - height) / 2; rc.bottom = rc.top + height; - int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width); + const int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width); const int ucs = stride * height; std::vector image(ucs); - for (int iy=0; iy(s[i]); + const unsigned char uch = static_cast(s[i]); if (uch < 0x80) { utfForm[lenU++] = uch; } else { @@ -647,7 +637,9 @@ std::string UTF8FromLatin1(const char *s, int len) { return utfForm; } -static std::string UTF8FromIconv(const Converter &conv, const char *s, int len) { +namespace { + +std::string UTF8FromIconv(const Converter &conv, const char *s, int len) { if (conv) { std::string utfForm(len*3+1, '\0'); char *pin = const_cast(s); @@ -667,9 +659,9 @@ static std::string UTF8FromIconv(const Converter &conv, const char *s, int len) // Work out how many bytes are in a character by trying to convert using iconv, // returning the first length that succeeds. -static size_t MultiByteLenFromIconv(const Converter &conv, const char *s, size_t len) { +size_t MultiByteLenFromIconv(const Converter &conv, const char *s, size_t len) noexcept { for (size_t lenMB=1; (lenMB<4) && (lenMB <= len); lenMB++) { - char wcForm[2]; + char wcForm[2] {}; char *pin = const_cast(s); gsize inLeft = lenMB; char *pout = wcForm; @@ -682,7 +674,9 @@ static size_t MultiByteLenFromIconv(const Converter &conv, const char *s, size_t return 1; } -void SurfaceImpl::DrawTextBase(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, +} + +void SurfaceImpl::DrawTextBase(PRectangle rc, const Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore) { PenColour(fore); if (context) { @@ -747,6 +741,12 @@ class ClusterIterator { iter = pango_layout_get_iter(layout); pango_layout_iter_get_cluster_extents(iter, nullptr, &pos); } + // Deleted so ClusterIterator objects can not be copied. + ClusterIterator(const ClusterIterator&) = delete; + ClusterIterator(ClusterIterator&&) = delete; + ClusterIterator&operator=(const ClusterIterator&) = delete; + ClusterIterator&operator=(ClusterIterator&&) = delete; + ~ClusterIterator() { pango_layout_iter_free(iter); } @@ -814,7 +814,7 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, XYPOSITION positions[i++] = iti.position - (places - place) * iti.distance / places; positionsCalculated++; } - clusterStart += UTF8BytesOfLead[static_cast(utfForm.c_str()[clusterStart])]; + clusterStart += UTF8BytesOfLead[static_cast(utfForm[clusterStart])]; place++; } } @@ -877,7 +877,6 @@ XYPOSITION SurfaceImpl::WidthText(Font &font_, const char *s, int len) { if (PFont(font_)->pfd) { std::string utfForm; pango_layout_set_font_description(layout, PFont(font_)->pfd); - PangoRectangle pos; if (et == UTF8) { pango_layout_set_text(layout, s, len); } else { @@ -889,6 +888,7 @@ XYPOSITION SurfaceImpl::WidthText(Font &font_, const char *s, int len) { pango_layout_set_text(layout, utfForm.c_str(), utfForm.length()); } PangoLayoutLine *pangoLine = pango_layout_get_line_readonly(layout, 0); + PangoRectangle pos {}; pango_layout_line_get_extents(pangoLine, nullptr, &pos); return floatFromPangoUnits(pos.width); } @@ -907,7 +907,7 @@ XYPOSITION SurfaceImpl::Ascent(Font &font_) { if (PFont(font_)->pfd) { PangoFontMetrics *metrics = pango_context_get_metrics(pcontext, PFont(font_)->pfd, pango_context_get_language(pcontext)); - ascent = std::floor(floatFromPangoUnits( + ascent = Sci::round(floatFromPangoUnits( pango_font_metrics_get_ascent(metrics))); pango_font_metrics_unref(metrics); } @@ -923,7 +923,7 @@ XYPOSITION SurfaceImpl::Descent(Font &font_) { if (PFont(font_)->pfd) { PangoFontMetrics *metrics = pango_context_get_metrics(pcontext, PFont(font_)->pfd, pango_context_get_language(pcontext)); - const XYPOSITION descent = std::floor(floatFromPangoUnits( + const XYPOSITION descent = Sci::round(floatFromPangoUnits( pango_font_metrics_get_descent(metrics))); pango_font_metrics_unref(metrics); return descent; @@ -945,7 +945,7 @@ XYPOSITION SurfaceImpl::AverageCharWidth(Font &font_) { void SurfaceImpl::SetClip(PRectangle rc) { PLATFORM_ASSERT(context); - cairo_rectangle(context, rc.left, rc.top, rc.right, rc.bottom); + cairo_rectangle(context, rc.left, rc.top, rc.Width(), rc.Height()); cairo_clip(context); } @@ -1011,7 +1011,7 @@ void Window::SetPosition(PRectangle rc) { namespace { -GdkRectangle MonitorRectangleForWidget(GtkWidget *wid) { +GdkRectangle MonitorRectangleForWidget(GtkWidget *wid) noexcept { GdkWindow *wnd = WindowFromWidget(wid); GdkRectangle rcScreen = GdkRectangle(); #if GTK_CHECK_VERSION(3,22,0) @@ -1136,7 +1136,7 @@ PRectangle Window::GetMonitorRect(Point pt) { gdk_window_get_origin(WindowFromWidget(PWidget(wid)), &x_offset, &y_offset); - GdkRectangle rect; + GdkRectangle rect {}; #if GTK_CHECK_VERSION(3,22,0) GdkDisplay *pdisplay = gtk_widget_get_display(PWidget(wid)); @@ -1208,6 +1208,11 @@ class ListBoxX : public ListBox { #endif delegate(nullptr) { } + // Deleted so ListBoxX objects can not be copied. + ListBoxX(const ListBoxX&) = delete; + ListBoxX(ListBoxX&&) = delete; + ListBoxX&operator=(const ListBoxX&) = delete; + ListBoxX&operator=(ListBoxX&&) = delete; ~ListBoxX() override { if (pixhash) { g_hash_table_foreach((GHashTable *) pixhash, list_image_free, nullptr); @@ -1360,13 +1365,13 @@ static gboolean ButtonRelease(GtkWidget *, GdkEventButton *ev, gpointer p) { return FALSE; } -/* Change the active color to the selected color so the listbox uses the color +/* Change the active colour to the selected colour so the listbox uses the colour scheme that it would use if it had the focus. */ static void StyleSet(GtkWidget *w, GtkStyle *, void *) { g_return_if_fail(w != nullptr); - /* Copy the selected color to active. Note that the modify calls will cause + /* Copy the selected colour to active. Note that the modify calls will cause recursive calls to this function after the value is updated and w->style to be set to a new object */ @@ -1675,7 +1680,7 @@ void ListBoxX::Append(char *s, int type) { list_image = static_cast(g_hash_table_lookup((GHashTable *) pixhash, GINT_TO_POINTER(type))); } - GtkTreeIter iter; + GtkTreeIter iter {}; GtkListStore *store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(list))); gtk_list_store_append(GTK_LIST_STORE(store), &iter); @@ -1715,7 +1720,7 @@ int ListBoxX::Length() { } void ListBoxX::Select(int n) { - GtkTreeIter iter; + GtkTreeIter iter {}; GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(list)); GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(list)); @@ -1770,8 +1775,8 @@ void ListBoxX::Select(int n) { int ListBoxX::GetSelection() { int index = -1; - GtkTreeIter iter; - GtkTreeModel *model; + GtkTreeIter iter {}; + GtkTreeModel *model {}; GtkTreeSelection *selection; selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(list)); if (gtk_tree_selection_get_selected(selection, &model, &iter)) { @@ -1786,13 +1791,13 @@ int ListBoxX::GetSelection() { } int ListBoxX::Find(const char *prefix) { - GtkTreeIter iter; + GtkTreeIter iter {}; GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(list)); bool valid = gtk_tree_model_get_iter_first(model, &iter) != FALSE; int i = 0; while (valid) { - gchar *s; + gchar *s = nullptr; gtk_tree_model_get(model, &iter, TEXT_COLUMN, &s, -1); if (s && (0 == strncmp(prefix, s, strlen(prefix)))) { g_free(s); @@ -1807,7 +1812,7 @@ int ListBoxX::Find(const char *prefix) { void ListBoxX::GetValue(int n, char *value, int len) { char *text = nullptr; - GtkTreeIter iter; + GtkTreeIter iter {}; GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(list)); const bool valid = gtk_tree_model_iter_nth_child(model, &iter, nullptr, n) != FALSE; if (valid) { @@ -1907,7 +1912,7 @@ void Menu::Destroy() { } #if !GTK_CHECK_VERSION(3,22,0) -static void MenuPositionFunc(GtkMenu *, gint *x, gint *y, gboolean *, gpointer userData) { +static void MenuPositionFunc(GtkMenu *, gint *x, gint *y, gboolean *, gpointer userData) noexcept { sptr_t intFromPointer = GPOINTER_TO_INT(userData); *x = intFromPointer & 0xffff; *y = intFromPointer >> 16; @@ -1947,7 +1952,11 @@ class DynamicLibraryImpl : public DynamicLibrary { explicit DynamicLibraryImpl(const char *modulePath) noexcept { m = g_module_open(modulePath, G_MODULE_BIND_LAZY); } - + // Deleted so DynamicLibraryImpl objects can not be copied. + DynamicLibraryImpl(const DynamicLibraryImpl&) = delete; + DynamicLibraryImpl(DynamicLibraryImpl&&) = delete; + DynamicLibraryImpl&operator=(const DynamicLibraryImpl&) = delete; + DynamicLibraryImpl&operator=(DynamicLibraryImpl&&) = delete; ~DynamicLibraryImpl() override { if (m != nullptr) g_module_close(m); diff --git a/scintilla/gtk/ScintillaGTK.cxx b/scintilla/gtk/ScintillaGTK.cxx index a78f00d7ba..659eb76356 100644 --- a/scintilla/gtk/ScintillaGTK.cxx +++ b/scintilla/gtk/ScintillaGTK.cxx @@ -41,14 +41,8 @@ #include "ILexer.h" #include "Scintilla.h" #include "ScintillaWidget.h" -#ifdef SCI_LEXER -#include "SciLexer.h" -#endif #include "StringCopy.h" #include "CharacterCategory.h" -#ifdef SCI_LEXER -#include "LexerModule.h" -#endif #include "Position.h" #include "UniqueString.h" #include "SplitVector.h" @@ -77,10 +71,6 @@ #include "AutoComplete.h" #include "ScintillaBase.h" -#ifdef SCI_LEXER -#include "ExternalLexer.h" -#endif - #include "ScintillaGTK.h" #include "scintilla-marshal.h" #include "ScintillaGTKAccessible.h" @@ -90,10 +80,10 @@ #define IS_WIDGET_REALIZED(w) (gtk_widget_get_realized(GTK_WIDGET(w))) #define IS_WIDGET_MAPPED(w) (gtk_widget_get_mapped(GTK_WIDGET(w))) -#define SC_INDICATOR_INPUT INDIC_IME -#define SC_INDICATOR_TARGET INDIC_IME+1 -#define SC_INDICATOR_CONVERTED INDIC_IME+2 -#define SC_INDICATOR_UNKNOWN INDIC_IME_MAX +#define SC_INDICATOR_INPUT INDICATOR_IME +#define SC_INDICATOR_TARGET INDICATOR_IME+1 +#define SC_INDICATOR_CONVERTED INDICATOR_IME+2 +#define SC_INDICATOR_UNKNOWN INDICATOR_IME_MAX static GdkWindow *WindowFromWidget(GtkWidget *w) noexcept { return gtk_widget_get_window(w); @@ -132,6 +122,7 @@ enum { }; GdkAtom ScintillaGTK::atomUTF8 = nullptr; +GdkAtom ScintillaGTK::atomUTF8Mime = nullptr; GdkAtom ScintillaGTK::atomString = nullptr; GdkAtom ScintillaGTK::atomUriList = nullptr; GdkAtom ScintillaGTK::atomDROPFILES_DND = nullptr; @@ -140,14 +131,14 @@ static const GtkTargetEntry clipboardCopyTargets[] = { { (gchar *) "UTF8_STRING", 0, TARGET_UTF8_STRING }, { (gchar *) "STRING", 0, TARGET_STRING }, }; -static const gint nClipboardCopyTargets = ELEMENTS(clipboardCopyTargets); +static constexpr gint nClipboardCopyTargets = ELEMENTS(clipboardCopyTargets); static const GtkTargetEntry clipboardPasteTargets[] = { { (gchar *) "text/uri-list", 0, TARGET_URI }, { (gchar *) "UTF8_STRING", 0, TARGET_UTF8_STRING }, { (gchar *) "STRING", 0, TARGET_STRING }, }; -static const gint nClipboardPasteTargets = ELEMENTS(clipboardPasteTargets); +static constexpr gint nClipboardPasteTargets = ELEMENTS(clipboardPasteTargets); static const GdkDragAction actionCopyOrMove = static_cast(GDK_ACTION_COPY | GDK_ACTION_MOVE); @@ -155,7 +146,7 @@ static GtkWidget *PWidget(const Window &w) noexcept { return static_cast(w.GetID()); } -ScintillaGTK *ScintillaGTK::FromWidget(GtkWidget *widget) { +ScintillaGTK *ScintillaGTK::FromWidget(GtkWidget *widget) noexcept { ScintillaObject *scio = SCINTILLA(widget); return static_cast(scio->pscin); } @@ -169,8 +160,10 @@ ScintillaGTK::ScintillaGTK(_ScintillaObject *sci_) : lastKey(0), rectangularSelectionModifier(SCMOD_CTRL), parentClass(nullptr), atomSought(nullptr), + preeditInitialized(false), im_context(nullptr), - lastNonCommonScript(PANGO_SCRIPT_INVALID_CODE), + lastNonCommonScript(G_UNICODE_SCRIPT_INVALID_CODE), + lastWheelMouseTime(0), lastWheelMouseDirection(0), wheelMouseIntensity(0), smoothScrollY(0), @@ -200,8 +193,6 @@ ScintillaGTK::ScintillaGTK(_ScintillaObject *sci_) : #else linesPerScroll = 4; #endif - lastWheelMouseTime.tv_sec = 0; - lastWheelMouseTime.tv_usec = 0; Init(); } @@ -218,7 +209,7 @@ ScintillaGTK::~ScintillaGTK() { wPreedit.Destroy(); } -static void UnRefCursor(GdkCursor *cursor) { +static void UnRefCursor(GdkCursor *cursor) noexcept { #if GTK_CHECK_VERSION(3,0,0) g_object_unref(cursor); #else @@ -269,6 +260,8 @@ void ScintillaGTK::RealizeThis(GtkWidget *widget) { gdk_window_show(widget->window); UnRefCursor(cursor); #endif + + preeditInitialized = false; gtk_widget_realize(PWidget(wPreedit)); gtk_widget_realize(PWidget(wPreeditDraw)); @@ -278,6 +271,7 @@ void ScintillaGTK::RealizeThis(GtkWidget *widget) { g_signal_connect(G_OBJECT(im_context), "preedit_changed", G_CALLBACK(PreeditChanged), this); gtk_im_context_set_client_window(im_context, WindowFromWidget(widget)); + GtkWidget *widtxt = PWidget(wText); // // No code inside the G_OBJECT macro g_signal_connect_after(G_OBJECT(widtxt), "style_set", G_CALLBACK(ScintillaGTK::StyleSetText), nullptr); @@ -343,7 +337,7 @@ void ScintillaGTK::UnRealize(GtkWidget *widget) { sciThis->UnRealizeThis(widget); } -static void MapWidget(GtkWidget *widget) { +static void MapWidget(GtkWidget *widget) noexcept { if (widget && gtk_widget_get_visible(GTK_WIDGET(widget)) && !IS_WIDGET_MAPPED(widget)) { @@ -424,14 +418,19 @@ class PreEditString { gboolean validUTF8; glong uniStrLen; gunichar *uniStr; - PangoScript pscript; + GUnicodeScript pscript; - explicit PreEditString(GtkIMContext *im_context) { + explicit PreEditString(GtkIMContext *im_context) noexcept { gtk_im_context_get_preedit_string(im_context, &str, &attrs, &cursor_pos); validUTF8 = g_utf8_validate(str, strlen(str), nullptr); uniStr = g_utf8_to_ucs4_fast(str, strlen(str), &uniStrLen); - pscript = pango_script_for_unichar(uniStr[0]); + pscript = g_unichar_get_script(uniStr[0]); } + // Deleted so PreEditString objects can not be copied. + PreEditString(const PreEditString&) = delete; + PreEditString(PreEditString&&) = delete; + PreEditString&operator=(const PreEditString&) = delete; + PreEditString&operator=(PreEditString&&) = delete; ~PreEditString() { g_free(str); g_free(uniStr); @@ -444,18 +443,24 @@ class PreEditString { gint ScintillaGTK::FocusInThis(GtkWidget *) { try { SetFocusState(true); + if (im_context) { + gtk_im_context_focus_in(im_context); PreEditString pes(im_context); if (PWidget(wPreedit)) { + if (!preeditInitialized) { + GtkWidget *top = gtk_widget_get_toplevel(PWidget(wMain)); + gtk_window_set_transient_for(GTK_WINDOW(PWidget(wPreedit)), GTK_WINDOW(top)); + preeditInitialized = true; + } + if (strlen(pes.str) > 0) { gtk_widget_show(PWidget(wPreedit)); } else { gtk_widget_hide(PWidget(wPreedit)); } } - gtk_im_context_focus_in(im_context); } - } catch (...) { errorStatus = SC_STATUS_FAILURE; } @@ -536,7 +541,7 @@ void ScintillaGTK::SizeAllocate(GtkWidget *widget, GtkAllocation *allocation) { } void ScintillaGTK::Init() { - parentClass = reinterpret_cast( + parentClass = static_cast( g_type_class_ref(gtk_container_get_type())); gint maskSmooth = 0; @@ -751,16 +756,16 @@ std::string ConvertText(const char *s, size_t len, const char *charSetDest, // Returns the target converted to UTF8. // Return the length in bytes. Sci::Position ScintillaGTK::TargetAsUTF8(char *text) const { - const Sci::Position targetLength = targetEnd - targetStart; + const Sci::Position targetLength = targetRange.Length(); if (IsUnicodeMode()) { if (text) { - pdoc->GetCharRange(text, targetStart, targetLength); + pdoc->GetCharRange(text, targetRange.start.Position(), targetLength); } } else { // Need to convert const char *charSetBuffer = CharacterSetID(); if (*charSetBuffer) { - std::string s = RangeText(targetStart, targetEnd); + std::string s = RangeText(targetRange.start.Position(), targetRange.end.Position()); std::string tmputf = ConvertText(&s[0], targetLength, "UTF-8", charSetBuffer, false); if (text) { memcpy(text, tmputf.c_str(), tmputf.length()); @@ -768,7 +773,7 @@ Sci::Position ScintillaGTK::TargetAsUTF8(char *text) const { return tmputf.length(); } else { if (text) { - pdoc->GetCharRange(text, targetStart, targetLength); + pdoc->GetCharRange(text, targetRange.start.Position(), targetLength); } } } @@ -828,11 +833,6 @@ sptr_t ScintillaGTK::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam case SCI_GETDIRECTPOINTER: return reinterpret_cast(this); -#ifdef SCI_LEXER - case SCI_LOADLEXERLIBRARY: - LexerManager::GetInstance()->Load(ConstCharPtrFromSPtr(lParam)); - break; -#endif case SCI_TARGETASUTF8: return TargetAsUTF8(CharPtrFromSPtr(lParam)); @@ -1201,6 +1201,11 @@ struct CaseMapper { mapped = g_utf8_strdown(sUTF8.c_str(), sUTF8.length()); } } + // Deleted so CaseMapper objects can not be copied. + CaseMapper(const CaseMapper&) = delete; + CaseMapper(CaseMapper&&) = delete; + CaseMapper&operator=(const CaseMapper&) = delete; + CaseMapper&operator=(CaseMapper&&) = delete; ~CaseMapper() { g_free(mapped); } @@ -1268,7 +1273,7 @@ namespace { class SelectionReceiver : GObjectWatcher { ScintillaGTK *sci; - void Destroyed() override { + void Destroyed() noexcept override { sci = nullptr; } @@ -1278,10 +1283,10 @@ class SelectionReceiver : GObjectWatcher { sci(sci_) { } - static void ClipboardReceived(GtkClipboard *, GtkSelectionData *selection_data, gpointer data) { + static void ClipboardReceived(GtkClipboard *clipboard, GtkSelectionData *selection_data, gpointer data) { SelectionReceiver *self = static_cast(data); if (self->sci) { - self->sci->ReceivedClipboard(selection_data); + self->sci->ReceivedClipboard(clipboard, selection_data); } delete self; } @@ -1321,9 +1326,8 @@ void ScintillaGTK::CreateCallTipWindow(PRectangle rc) { G_CALLBACK(ScintillaGTK::PressCT), this); gtk_widget_set_events(widcdrw, GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK); - GtkWidget *top = gtk_widget_get_toplevel(static_cast(wMain.GetID())); - gtk_window_set_transient_for(GTK_WINDOW(static_cast(PWidget(ct.wCallTip))), - GTK_WINDOW(top)); + GtkWidget *top = gtk_widget_get_toplevel(PWidget(wMain)); + gtk_window_set_transient_for(GTK_WINDOW(PWidget(ct.wCallTip)), GTK_WINDOW(top)); } const int width = static_cast(rc.Width()); const int height = static_cast(rc.Height()); @@ -1374,10 +1378,14 @@ void ScintillaGTK::ClaimSelection() { } } -static const guchar *DataOfGSD(GtkSelectionData *sd) { return gtk_selection_data_get_data(sd); } -static gint LengthOfGSD(GtkSelectionData *sd) { return gtk_selection_data_get_length(sd); } -static GdkAtom TypeOfGSD(GtkSelectionData *sd) { return gtk_selection_data_get_data_type(sd); } -static GdkAtom SelectionOfGSD(GtkSelectionData *sd) { return gtk_selection_data_get_selection(sd); } +bool ScintillaGTK::IsStringAtom(GdkAtom type) { + return (type == GDK_TARGET_STRING) || (type == atomUTF8) || (type == atomUTF8Mime); +} + +static const guchar *DataOfGSD(GtkSelectionData *sd) noexcept { return gtk_selection_data_get_data(sd); } +static gint LengthOfGSD(GtkSelectionData *sd) noexcept { return gtk_selection_data_get_length(sd); } +static GdkAtom TypeOfGSD(GtkSelectionData *sd) noexcept { return gtk_selection_data_get_data_type(sd); } +static GdkAtom SelectionOfGSD(GtkSelectionData *sd) noexcept { return gtk_selection_data_get_selection(sd); } // Detect rectangular text, convert line ends to current mode, convert from or to UTF-8 void ScintillaGTK::GetGtkSelectionText(GtkSelectionData *selectionData, SelectionText &selText) { @@ -1386,7 +1394,7 @@ void ScintillaGTK::GetGtkSelectionText(GtkSelectionData *selectionData, Selectio GdkAtom selectionTypeData = TypeOfGSD(selectionData); // Return empty string if selection is not a string - if ((selectionTypeData != GDK_TARGET_STRING) && (selectionTypeData != atomUTF8)) { + if (!IsStringAtom(selectionTypeData)) { selText.Clear(); return; } @@ -1432,7 +1440,7 @@ void ScintillaGTK::GetGtkSelectionText(GtkSelectionData *selectionData, Selectio } } -void ScintillaGTK::InsertSelection(GtkSelectionData *selectionData) { +void ScintillaGTK::InsertSelection(GtkClipboard *clipBoard, GtkSelectionData *selectionData) { const gint length = gtk_selection_data_get_length(selectionData); if (length >= 0) { GdkAtom selection = gtk_selection_data_get_selection(selectionData); @@ -1447,6 +1455,15 @@ void ScintillaGTK::InsertSelection(GtkSelectionData *selectionData) { InsertPasteShape(selText.Data(), selText.Length(), selText.rectangular ? pasteRectangular : pasteStream); EnsureCaretVisible(); + } else { + GdkAtom target = gtk_selection_data_get_target(selectionData); + if (target == atomUTF8) { + // In case data is actually only stored as text/plain;charset=utf-8 not UTF8_STRING + gtk_clipboard_request_contents(clipBoard, atomUTF8Mime, + SelectionReceiver::ClipboardReceived, + new SelectionReceiver(this) + ); + } } Redraw(); } @@ -1455,9 +1472,9 @@ GObject *ScintillaGTK::MainObject() const noexcept { return G_OBJECT(PWidget(wMain)); } -void ScintillaGTK::ReceivedClipboard(GtkSelectionData *selection_data) noexcept { +void ScintillaGTK::ReceivedClipboard(GtkClipboard *clipBoard, GtkSelectionData *selection_data) noexcept { try { - InsertSelection(selection_data); + InsertSelection(clipBoard, selection_data); } catch (...) { errorStatus = SC_STATUS_FAILURE; } @@ -1471,9 +1488,9 @@ void ScintillaGTK::ReceivedSelection(GtkSelectionData *selection_data) { atomSought = atomString; gtk_selection_convert(GTK_WIDGET(PWidget(wMain)), SelectionOfGSD(selection_data), atomSought, GDK_CURRENT_TIME); - } else if ((LengthOfGSD(selection_data) > 0) && - ((TypeOfGSD(selection_data) == GDK_TARGET_STRING) || (TypeOfGSD(selection_data) == atomUTF8))) { - InsertSelection(selection_data); + } else if ((LengthOfGSD(selection_data) > 0) && IsStringAtom(TypeOfGSD(selection_data))) { + GtkClipboard *clipBoard = gtk_widget_get_clipboard(GTK_WIDGET(PWidget(wMain)), SelectionOfGSD(selection_data)); + InsertSelection(clipBoard, selection_data); } } // else fprintf(stderr, "Target non string %d %d\n", (int)(selection_data->type), @@ -1490,7 +1507,7 @@ void ScintillaGTK::ReceivedDrop(GtkSelectionData *selection_data) { std::vector drop(data, data + LengthOfGSD(selection_data)); drop.push_back('\0'); NotifyURIDropped(&drop[0]); - } else if ((TypeOfGSD(selection_data) == GDK_TARGET_STRING) || (TypeOfGSD(selection_data) == atomUTF8)) { + } else if (IsStringAtom(TypeOfGSD(selection_data))) { if (LengthOfGSD(selection_data) > 0) { SelectionText selText; GetGtkSelectionText(selection_data, selText); @@ -1524,7 +1541,7 @@ void ScintillaGTK::GetSelection(GtkSelectionData *selection_data, guint info, Se const char *charSet = ::CharacterSetID(text->characterSet); if (*charSet) { std::string tmputf = ConvertText(text->Data(), text->Length(), "UTF-8", charSet, false); - converted.reset(new SelectionText()); + converted = Sci::make_unique(); converted->Copy(tmputf, SC_CP_UTF8, 0, text->rectangular, false); text = converted.get(); } @@ -1534,7 +1551,7 @@ void ScintillaGTK::GetSelection(GtkSelectionData *selection_data, guint info, Se // As I can not work out how to store data on the clipboard in multiple formats // and need some way to mark the clipping as being stream or rectangular, // the terminating \0 is included in the length for rectangular clippings. - // All other tested aplications behave benignly by ignoring the \0. + // All other tested applications behave benignly by ignoring the \0. // The #if is here because on Windows cfColumnSelect clip entry is used // instead as standard indicator of rectangularness (so no need to kludge) const char *textData = text->Data(); @@ -1684,7 +1701,7 @@ void ScintillaGTK::Resize(int width, int height) { namespace { -void SetAdjustmentValue(GtkAdjustment *object, int value) { +void SetAdjustmentValue(GtkAdjustment *object, int value) noexcept { GtkAdjustment *adjustment = GTK_ADJUSTMENT(object); const int maxValue = static_cast( gtk_adjustment_get_upper(adjustment) - gtk_adjustment_get_page_size(adjustment)); @@ -1751,7 +1768,7 @@ gint ScintillaGTK::PressThis(GdkEventButton *event) { if (event->button == 1) { #if PLAT_GTK_MACOSX const bool meta = ctrl; - // GDK reports the Command modifer key as GDK_MOD2_MASK for button events, + // GDK reports the Command modifier key as GDK_MOD2_MASK for button events, // not GDK_META_MASK like in key events. ctrl = (event->state & GDK_MOD2_MASK) != 0; #else @@ -1780,7 +1797,7 @@ gint ScintillaGTK::PressThis(GdkEventButton *event) { } else { #if PLAT_GTK_MACOSX const bool meta = ctrl; - // GDK reports the Command modifer key as GDK_MOD2_MASK for button events, + // GDK reports the Command modifier key as GDK_MOD2_MASK for button events, // not GDK_META_MASK like in key events. ctrl = (event->state & GDK_MOD2_MASK) != 0; #else @@ -1882,13 +1899,8 @@ gint ScintillaGTK::ScrollEvent(GtkWidget *widget, GdkEventScroll *event) { cLineScroll = 4; sciThis->wheelMouseIntensity = cLineScroll; #else - int timeDelta = 1000000; - GTimeVal curTime; - g_get_current_time(&curTime); - if (curTime.tv_sec == sciThis->lastWheelMouseTime.tv_sec) - timeDelta = curTime.tv_usec - sciThis->lastWheelMouseTime.tv_usec; - else if (curTime.tv_sec == sciThis->lastWheelMouseTime.tv_sec + 1) - timeDelta = 1000000 + (curTime.tv_usec - sciThis->lastWheelMouseTime.tv_usec); + const gint64 curTime = g_get_monotonic_time(); + const gint64 timeDelta = curTime - sciThis->lastWheelMouseTime; if ((event->direction == sciThis->lastWheelMouseDirection) && (timeDelta < 250000)) { if (sciThis->wheelMouseIntensity < 12) sciThis->wheelMouseIntensity++; @@ -1899,11 +1911,11 @@ gint ScintillaGTK::ScrollEvent(GtkWidget *widget, GdkEventScroll *event) { cLineScroll = 4; sciThis->wheelMouseIntensity = cLineScroll; } + sciThis->lastWheelMouseTime = curTime; #endif if (event->direction == GDK_SCROLL_UP || event->direction == GDK_SCROLL_LEFT) { cLineScroll *= -1; } - g_get_current_time(&sciThis->lastWheelMouseTime); sciThis->lastWheelMouseDirection = event->direction; // Note: Unpatched versions of win32gtk don't set the 'state' value so @@ -1954,7 +1966,7 @@ gint ScintillaGTK::Motion(GtkWidget *widget, GdkEventMotion *event) { return FALSE; int x = 0; int y = 0; - GdkModifierType state; + GdkModifierType state {}; if (event->is_hint) { #if GTK_CHECK_VERSION(3,0,0) gdk_window_get_device_position(event->window, @@ -1982,7 +1994,7 @@ gint ScintillaGTK::Motion(GtkWidget *widget, GdkEventMotion *event) { } // Map the keypad keys to their equivalent functions -static int KeyTranslate(int keyIn) { +static int KeyTranslate(int keyIn) noexcept { switch (keyIn) { #if GTK_CHECK_VERSION(3,0,0) case GDK_KEY_ISO_Left_Tab: @@ -2241,9 +2253,9 @@ gboolean ScintillaGTK::ExposePreedit(GtkWidget *widget, GdkEventExpose *ose, Sci bool ScintillaGTK::KoreanIME() { PreEditString pes(im_context); - if (pes.pscript != PANGO_SCRIPT_COMMON) + if (pes.pscript != G_UNICODE_SCRIPT_COMMON) lastNonCommonScript = pes.pscript; - return lastNonCommonScript == PANGO_SCRIPT_HANGUL; + return lastNonCommonScript == G_UNICODE_SCRIPT_HANGUL; } void ScintillaGTK::MoveImeCarets(int pos) { @@ -2258,9 +2270,9 @@ void ScintillaGTK::MoveImeCarets(int pos) { void ScintillaGTK::DrawImeIndicator(int indicator, int len) { // Emulate the visual style of IME characters with indicators. // Draw an indicator on the character before caret by the character bytes of len - // so it should be called after addCharUTF(). + // so it should be called after InsertCharacter(). // It does not affect caret positions. - if (indicator < 8 || indicator > INDIC_MAX) { + if (indicator < 8 || indicator > INDICATOR_MAX) { return; } pdoc->DecorationSetCurrentIndicator(indicator); @@ -2325,8 +2337,10 @@ void ScintillaGTK::SetCandidateWindowPos() { // Composition box accompanies candidate box. const Point pt = PointMainCaret(); GdkRectangle imeBox = {0}; // No need to set width - imeBox.x = static_cast(pt.x); // Only need positiion - imeBox.y = static_cast(pt.y) + vs.lineHeight; // underneath the first charater + imeBox.x = static_cast(pt.x); + imeBox.y = static_cast(pt.y + std::max(4, vs.lineHeight/4)); + // prevent overlapping with current line + imeBox.height = vs.lineHeight; gtk_im_context_set_cursor_location(im_context, &imeBox); } @@ -2350,7 +2364,7 @@ void ScintillaGTK::CommitThis(char *commitStr) { if (!IsUnicodeMode()) docChar = ConvertText(u8Char, u8CharLen, charSetSource, "UTF-8", true); - AddCharUTF(docChar.c_str(), docChar.size()); + InsertCharacter(docChar.c_str(), docChar.size(), CharacterSource::directInput); } g_free(uniStr); ShowCaretAtCurrentPosition(); @@ -2397,14 +2411,15 @@ void ScintillaGTK::PreeditChangedInlineThis() { return; } - if (initialCompose) + if (initialCompose) { ClearBeforeTentativeStart(); + } + + SetCandidateWindowPos(); pdoc->TentativeStart(); // TentativeActive() from now on std::vector indicator = MapImeIndicators(preeditStr.attrs, preeditStr.str); - const bool tmpRecordingMacro = recordingMacro; - recordingMacro = false; for (glong i = 0; i < preeditStr.uniStrLen; i++) { gchar u8Char[UTF8MaxBytes+2] = {0}; const gint u8CharLen = g_unichar_to_utf8(preeditStr.uniStr[i], u8Char); @@ -2412,11 +2427,10 @@ void ScintillaGTK::PreeditChangedInlineThis() { if (!IsUnicodeMode()) docChar = ConvertText(u8Char, u8CharLen, charSetSource, "UTF-8", true); - AddCharUTF(docChar.c_str(), docChar.size()); + InsertCharacter(docChar.c_str(), docChar.size(), CharacterSource::tentativeInput); DrawImeIndicator(indicator[i], docChar.size()); } - recordingMacro = tmpRecordingMacro; // Move caret to ime cursor position. const int imeEndToImeCaretU32 = preeditStr.cursor_pos - preeditStr.uniStrLen; @@ -2435,7 +2449,6 @@ void ScintillaGTK::PreeditChangedInlineThis() { } EnsureCaretVisible(); - SetCandidateWindowPos(); ShowCaretAtCurrentPosition(); } catch (...) { errorStatus = SC_STATUS_FAILURE; @@ -2446,6 +2459,8 @@ void ScintillaGTK::PreeditChangedWindowedThis() { try { PreEditString pes(im_context); if (strlen(pes.str) > 0) { + SetCandidateWindowPos(); + PangoLayout *layout = gtk_widget_create_pango_layout(PWidget(wText), pes.str); pango_layout_set_attributes(layout, pes.attrs); @@ -3048,10 +3063,8 @@ GType scintilla_object_get_type() { void ScintillaGTK::ClassInit(OBJECT_CLASS *object_class, GtkWidgetClass *widget_class, GtkContainerClass *container_class) { Platform_Initialise(); -#ifdef SCI_LEXER - Scintilla_LinkLexers(); -#endif atomUTF8 = gdk_atom_intern("UTF8_STRING", FALSE); + atomUTF8Mime = gdk_atom_intern("text/plain;charset=utf-8", FALSE); atomString = GDK_SELECTION_TYPE_STRING; atomUriList = gdk_atom_intern("text/uri-list", FALSE); atomDROPFILES_DND = gdk_atom_intern("DROPFILES_DND", FALSE); diff --git a/scintilla/gtk/ScintillaGTK.h b/scintilla/gtk/ScintillaGTK.h index b878088244..e8c61f85f0 100644 --- a/scintilla/gtk/ScintillaGTK.h +++ b/scintilla/gtk/ScintillaGTK.h @@ -37,6 +37,7 @@ class ScintillaGTK : public ScintillaBase { GtkWidgetClass *parentClass; static GdkAtom atomUTF8; + static GdkAtom atomUTF8Mime; static GdkAtom atomString; static GdkAtom atomUriList; static GdkAtom atomDROPFILES_DND; @@ -46,14 +47,15 @@ class ScintillaGTK : public ScintillaBase { CLIPFORMAT cfColumnSelect; #endif + bool preeditInitialized; Window wPreedit; Window wPreeditDraw; GtkIMContext *im_context; - PangoScript lastNonCommonScript; + GUnicodeScript lastNonCommonScript; // Wheel mouse support unsigned int linesPerScroll; - GTimeVal lastWheelMouseTime; + gint64 lastWheelMouseTime; gint lastWheelMouseDirection; gint wheelMouseIntensity; gdouble smoothScrollY; @@ -78,7 +80,7 @@ class ScintillaGTK : public ScintillaBase { ScintillaGTK &operator=(const ScintillaGTK &) = delete; ScintillaGTK &operator=(ScintillaGTK &&) = delete; virtual ~ScintillaGTK(); - static ScintillaGTK *FromWidget(GtkWidget *widget); + static ScintillaGTK *FromWidget(GtkWidget *widget) noexcept; static void ClassInit(OBJECT_CLASS *object_class, GtkWidgetClass *widget_class, GtkContainerClass *container_class); private: void Init(); @@ -132,11 +134,12 @@ class ScintillaGTK : public ScintillaBase { void AddToPopUp(const char *label, int cmd = 0, bool enabled = true) override; bool OwnPrimarySelection(); void ClaimSelection() override; + static bool IsStringAtom(GdkAtom type); void GetGtkSelectionText(GtkSelectionData *selectionData, SelectionText &selText); - void InsertSelection(GtkSelectionData *selectionData); + void InsertSelection(GtkClipboard *clipBoard, GtkSelectionData *selectionData); public: // Public for SelectionReceiver GObject *MainObject() const noexcept; - void ReceivedClipboard(GtkSelectionData *selection_data) noexcept; + void ReceivedClipboard(GtkClipboard *clipBoard, GtkSelectionData *selection_data) noexcept; private: void ReceivedSelection(GtkSelectionData *selection_data); void ReceivedDrop(GtkSelectionData *selection_data); @@ -274,6 +277,12 @@ class GObjectWatcher { g_object_weak_ref(weakRef, WeakNotify, this); } + // Deleted so GObjectWatcher objects can not be copied. + GObjectWatcher(const GObjectWatcher&) = delete; + GObjectWatcher(GObjectWatcher&&) = delete; + GObjectWatcher&operator=(const GObjectWatcher&) = delete; + GObjectWatcher&operator=(GObjectWatcher&&) = delete; + virtual ~GObjectWatcher() { if (weakRef) { g_object_weak_unref(weakRef, WeakNotify, this); diff --git a/scintilla/gtk/ScintillaGTKAccessible.cxx b/scintilla/gtk/ScintillaGTKAccessible.cxx index f9cedcb82f..90b41ebc6c 100644 --- a/scintilla/gtk/ScintillaGTKAccessible.cxx +++ b/scintilla/gtk/ScintillaGTKAccessible.cxx @@ -1,5 +1,5 @@ /* Scintilla source code edit control */ -/* ScintillaGTKAccessible.c - GTK+ accessibility for ScintillaGTK */ +/* ScintillaGTKAccessible.cxx - GTK+ accessibility for ScintillaGTK */ /* Copyright 2016 by Colomban Wendling * The License.txt file describes the conditions under which this software may be distributed. */ @@ -53,6 +53,7 @@ #include #include +#include #include #include @@ -91,14 +92,8 @@ #include "ILexer.h" #include "Scintilla.h" #include "ScintillaWidget.h" -#ifdef SCI_LEXER -#include "SciLexer.h" -#endif #include "StringCopy.h" #include "CharacterCategory.h" -#ifdef SCI_LEXER -#include "LexerModule.h" -#endif #include "Position.h" #include "UniqueString.h" #include "SplitVector.h" diff --git a/scintilla/gtk/ScintillaGTKAccessible.h b/scintilla/gtk/ScintillaGTKAccessible.h index 264bbae1ce..2168d034c9 100644 --- a/scintilla/gtk/ScintillaGTKAccessible.h +++ b/scintilla/gtk/ScintillaGTKAccessible.h @@ -191,4 +191,4 @@ class ScintillaGTKAccessible { } -#endif /* SCINTILLAGTKACCESSIBLE_H */ +#endif diff --git a/scintilla/include/Compat.h b/scintilla/include/Compat.h new file mode 100644 index 0000000000..b6d41e5918 --- /dev/null +++ b/scintilla/include/Compat.h @@ -0,0 +1,70 @@ +// c++11 compatibility with some c++14 features and higher. +// This helps minimize changes from the default branch. + +#ifndef COMPAT_H +#define COMPAT_H + +#ifdef __cplusplus + +#include +#include +#include +#include +#include + +namespace Sci { + +// std::clamp +template +inline constexpr T clamp(T val, T minVal, T maxVal) { + return (val > maxVal) ? maxVal : ((val < minVal) ? minVal : val); +} + +// std::round (not present on older MacOSX SDKs) +template +T round(T arg) { + return ::round(arg); +} + +// std::lround (not present on older MacOSX SDKs) +template +long lround(T arg) { + return ::lround(arg); +} + +// std::make_unique +template struct _Unique_if { + typedef std::unique_ptr _Single_object; +}; +template struct _Unique_if { + typedef std::unique_ptr _Unknown_bound; +}; +template struct _Unique_if { + typedef void _Known_bound; +}; +template + typename _Unique_if::_Single_object + make_unique(Args&&... args) { + return std::unique_ptr(new T(std::forward(args)...)); + } +template + typename _Unique_if::_Unknown_bound + make_unique(size_t n) { + typedef typename std::remove_extent::type U; + return std::unique_ptr(new U[n]()); + } +template + typename _Unique_if::_Known_bound + make_unique(Args&&...) = delete; + +// std::size +template +constexpr size_t size(const T (&)[N]) noexcept { + return N; +} + +} + +#endif + +#endif diff --git a/scintilla/include/ILexer.h b/scintilla/include/ILexer.h index 42f980f896..f7f188972f 100644 --- a/scintilla/include/ILexer.h +++ b/scintilla/include/ILexer.h @@ -46,7 +46,7 @@ class IDocumentWithLineEnd : public IDocument { virtual int SCI_METHOD GetCharacterAndWidth(Sci_Position position, Sci_Position *pWidth) const = 0; }; -enum { lvOriginal=0, lvSubStyles=1, lvMetaData=2 }; +enum { lvOriginal=0, lvSubStyles=1, lvMetaData=2, lvIdentity=3 }; class ILexer { public: @@ -85,6 +85,13 @@ class ILexerWithMetaData : public ILexerWithSubStyles { virtual const char * SCI_METHOD DescriptionOfStyle(int style) = 0; }; +class ILexerWithIdentity : public ILexerWithMetaData { +public: + virtual const char * SCI_METHOD GetName() = 0; + virtual int SCI_METHOD GetIdentifier() = 0; + virtual const char * SCI_METHOD PropertyGet(const char *key) = 0; +}; + } #endif diff --git a/scintilla/include/Makefile.am b/scintilla/include/Makefile.am index 688c5154d7..9fa85d7c2a 100644 --- a/scintilla/include/Makefile.am +++ b/scintilla/include/Makefile.am @@ -7,6 +7,7 @@ noinst_HEADERS = \ scintilla_includedir = $(includedir)/geany/scintilla/ scintilla_include_HEADERS = \ + Compat.h \ SciLexer.h \ Scintilla.h \ Scintilla.iface \ diff --git a/scintilla/include/Platform.h b/scintilla/include/Platform.h index 8f5417fe09..b5e2109b4d 100644 --- a/scintilla/include/Platform.h +++ b/scintilla/include/Platform.h @@ -104,19 +104,19 @@ class Point { constexpr explicit Point(XYPOSITION x_=0, XYPOSITION y_=0) noexcept : x(x_), y(y_) { } - static Point FromInts(int x_, int y_) noexcept { + static constexpr Point FromInts(int x_, int y_) noexcept { return Point(static_cast(x_), static_cast(y_)); } - bool operator!=(Point other) const noexcept { + constexpr bool operator!=(Point other) const noexcept { return (x != other.x) || (y != other.y); } - Point operator+(Point other) const noexcept { + constexpr Point operator+(Point other) const noexcept { return Point(x + other.x, y + other.y); } - Point operator-(Point other) const noexcept { + constexpr Point operator-(Point other) const noexcept { return Point(x - other.x, y - other.y); } @@ -139,31 +139,31 @@ class PRectangle { left(left_), top(top_), right(right_), bottom(bottom_) { } - static PRectangle FromInts(int left_, int top_, int right_, int bottom_) noexcept { + static constexpr PRectangle FromInts(int left_, int top_, int right_, int bottom_) noexcept { return PRectangle(static_cast(left_), static_cast(top_), static_cast(right_), static_cast(bottom_)); } // Other automatically defined methods (assignment, copy constructor, destructor) are fine - bool operator==(const PRectangle &rc) const noexcept { + constexpr bool operator==(const PRectangle &rc) const noexcept { return (rc.left == left) && (rc.right == right) && (rc.top == top) && (rc.bottom == bottom); } - bool Contains(Point pt) const noexcept { + constexpr bool Contains(Point pt) const noexcept { return (pt.x >= left) && (pt.x <= right) && (pt.y >= top) && (pt.y <= bottom); } - bool ContainsWholePixel(Point pt) const noexcept { + constexpr bool ContainsWholePixel(Point pt) const noexcept { // Does the rectangle contain all of the pixel to left/below the point return (pt.x >= left) && ((pt.x+1) <= right) && (pt.y >= top) && ((pt.y+1) <= bottom); } - bool Contains(PRectangle rc) const noexcept { + constexpr bool Contains(PRectangle rc) const noexcept { return (rc.left >= left) && (rc.right <= right) && (rc.top >= top) && (rc.bottom <= bottom); } - bool Intersects(PRectangle other) const noexcept { + constexpr bool Intersects(PRectangle other) const noexcept { return (right > other.left) && (left < other.right) && (bottom > other.top) && (top < other.bottom); } @@ -173,9 +173,9 @@ class PRectangle { right += xDelta; bottom += yDelta; } - XYPOSITION Width() const noexcept { return right - left; } - XYPOSITION Height() const noexcept { return bottom - top; } - bool Empty() const noexcept { + constexpr XYPOSITION Width() const noexcept { return right - left; } + constexpr XYPOSITION Height() const noexcept { return bottom - top; } + constexpr bool Empty() const noexcept { return (Height() <= 0) || (Width() <= 0); } }; @@ -187,40 +187,40 @@ constexpr const float componentMaximum = 255.0f; class ColourDesired { int co; public: - explicit ColourDesired(int co_=0) noexcept : co(co_) { + constexpr explicit ColourDesired(int co_=0) noexcept : co(co_) { } - ColourDesired(unsigned int red, unsigned int green, unsigned int blue) noexcept : + constexpr ColourDesired(unsigned int red, unsigned int green, unsigned int blue) noexcept : co(red | (green << 8) | (blue << 16)) { } - bool operator==(const ColourDesired &other) const noexcept { + constexpr bool operator==(const ColourDesired &other) const noexcept { return co == other.co; } - int AsInteger() const noexcept { + constexpr int AsInteger() const noexcept { return co; } // Red, green and blue values as bytes 0..255 - unsigned char GetRed() const noexcept { + constexpr unsigned char GetRed() const noexcept { return co & 0xff; } - unsigned char GetGreen() const noexcept { + constexpr unsigned char GetGreen() const noexcept { return (co >> 8) & 0xff; } - unsigned char GetBlue() const noexcept { + constexpr unsigned char GetBlue() const noexcept { return (co >> 16) & 0xff; } // Red, green and blue values as float 0..1.0 - float GetRedComponent() const noexcept { + constexpr float GetRedComponent() const noexcept { return GetRed() / componentMaximum; } - float GetGreenComponent() const noexcept { + constexpr float GetGreenComponent() const noexcept { return GetGreen() / componentMaximum; } - float GetBlueComponent() const noexcept { + constexpr float GetBlueComponent() const noexcept { return GetBlue() / componentMaximum; } }; @@ -230,30 +230,30 @@ class ColourDesired { */ class ColourAlpha : public ColourDesired { public: - explicit ColourAlpha(int co_ = 0) noexcept : ColourDesired(co_) { + constexpr explicit ColourAlpha(int co_ = 0) noexcept : ColourDesired(co_) { } - ColourAlpha(unsigned int red, unsigned int green, unsigned int blue) noexcept : + constexpr ColourAlpha(unsigned int red, unsigned int green, unsigned int blue) noexcept : ColourDesired(red | (green << 8) | (blue << 16)) { } - ColourAlpha(unsigned int red, unsigned int green, unsigned int blue, unsigned int alpha) noexcept : + constexpr ColourAlpha(unsigned int red, unsigned int green, unsigned int blue, unsigned int alpha) noexcept : ColourDesired(red | (green << 8) | (blue << 16) | (alpha << 24)) { } - ColourAlpha(ColourDesired cd, unsigned int alpha) noexcept : + constexpr ColourAlpha(ColourDesired cd, unsigned int alpha) noexcept : ColourDesired(cd.AsInteger() | (alpha << 24)) { } - ColourDesired GetColour() const noexcept { + constexpr ColourDesired GetColour() const noexcept { return ColourDesired(AsInteger() & 0xffffff); } - unsigned char GetAlpha() const noexcept { + constexpr unsigned char GetAlpha() const noexcept { return (AsInteger() >> 24) & 0xff; } - float GetAlphaComponent() const noexcept { + constexpr float GetAlphaComponent() const noexcept { return GetAlpha() / componentMaximum; } @@ -371,11 +371,11 @@ class Surface { virtual void Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back)=0; virtual void Copy(PRectangle rc, Point from, Surface &surfaceSource)=0; - virtual void DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back)=0; - virtual void DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back)=0; - virtual void DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore)=0; - virtual void MeasureWidths(Font &font_, const char *s, int len, XYPOSITION *positions)=0; - virtual XYPOSITION WidthText(Font &font_, const char *s, int len)=0; + virtual void DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back) = 0; + virtual void DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back) = 0; + virtual void DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore) = 0; + virtual void MeasureWidths(Font &font_, const char *s, int len, XYPOSITION *positions) = 0; + virtual XYPOSITION WidthText(Font &font_, const char *s, int len) = 0; virtual XYPOSITION Ascent(Font &font_)=0; virtual XYPOSITION Descent(Font &font_)=0; virtual XYPOSITION InternalLeading(Font &font_)=0; diff --git a/scintilla/include/SciLexer.h b/scintilla/include/SciLexer.h index ae20985cea..e58f6184cf 100644 --- a/scintilla/include/SciLexer.h +++ b/scintilla/include/SciLexer.h @@ -140,6 +140,10 @@ #define SCLEX_SAS 125 #define SCLEX_NIM 126 #define SCLEX_CIL 127 +#define SCLEX_X12 128 +#define SCLEX_DATAFLEX 129 +#define SCLEX_HOLLYWOOD 130 +#define SCLEX_RAKU 131 #define SCLEX_LPEG 999 #define SCLEX_AUTOMATIC 1000 #define SCE_P_DEFAULT 0 @@ -513,6 +517,7 @@ #define SCE_ERR_GCC_INCLUDED_FROM 22 #define SCE_ERR_ESCSEQ 23 #define SCE_ERR_ESCSEQ_UNKNOWN 24 +#define SCE_ERR_GCC_EXCERPT 25 #define SCE_ERR_ES_BLACK 40 #define SCE_ERR_ES_RED 41 #define SCE_ERR_ES_GREEN 42 @@ -1886,6 +1891,74 @@ #define SCE_CIL_OPERATOR 8 #define SCE_CIL_IDENTIFIER 9 #define SCE_CIL_STRINGEOL 10 +#define SCE_X12_DEFAULT 0 +#define SCE_X12_BAD 1 +#define SCE_X12_ENVELOPE 2 +#define SCE_X12_FUNCTIONGROUP 3 +#define SCE_X12_TRANSACTIONSET 4 +#define SCE_X12_SEGMENTHEADER 5 +#define SCE_X12_SEGMENTEND 6 +#define SCE_X12_SEP_ELEMENT 7 +#define SCE_X12_SEP_SUBELEMENT 8 +#define SCE_DF_DEFAULT 0 +#define SCE_DF_IDENTIFIER 1 +#define SCE_DF_METATAG 2 +#define SCE_DF_IMAGE 3 +#define SCE_DF_COMMENTLINE 4 +#define SCE_DF_PREPROCESSOR 5 +#define SCE_DF_PREPROCESSOR2 6 +#define SCE_DF_NUMBER 7 +#define SCE_DF_HEXNUMBER 8 +#define SCE_DF_WORD 9 +#define SCE_DF_STRING 10 +#define SCE_DF_STRINGEOL 11 +#define SCE_DF_SCOPEWORD 12 +#define SCE_DF_OPERATOR 13 +#define SCE_DF_ICODE 14 +#define SCE_HOLLYWOOD_DEFAULT 0 +#define SCE_HOLLYWOOD_COMMENT 1 +#define SCE_HOLLYWOOD_COMMENTBLOCK 2 +#define SCE_HOLLYWOOD_NUMBER 3 +#define SCE_HOLLYWOOD_KEYWORD 4 +#define SCE_HOLLYWOOD_STDAPI 5 +#define SCE_HOLLYWOOD_PLUGINAPI 6 +#define SCE_HOLLYWOOD_PLUGINMETHOD 7 +#define SCE_HOLLYWOOD_STRING 8 +#define SCE_HOLLYWOOD_STRINGBLOCK 9 +#define SCE_HOLLYWOOD_PREPROCESSOR 10 +#define SCE_HOLLYWOOD_OPERATOR 11 +#define SCE_HOLLYWOOD_IDENTIFIER 12 +#define SCE_HOLLYWOOD_CONSTANT 13 +#define SCE_HOLLYWOOD_HEXNUMBER 14 +#define SCE_RAKU_DEFAULT 0 +#define SCE_RAKU_ERROR 1 +#define SCE_RAKU_COMMENTLINE 2 +#define SCE_RAKU_COMMENTEMBED 3 +#define SCE_RAKU_POD 4 +#define SCE_RAKU_CHARACTER 5 +#define SCE_RAKU_HEREDOC_Q 6 +#define SCE_RAKU_HEREDOC_QQ 7 +#define SCE_RAKU_STRING 8 +#define SCE_RAKU_STRING_Q 9 +#define SCE_RAKU_STRING_QQ 10 +#define SCE_RAKU_STRING_Q_LANG 11 +#define SCE_RAKU_STRING_VAR 12 +#define SCE_RAKU_REGEX 13 +#define SCE_RAKU_REGEX_VAR 14 +#define SCE_RAKU_ADVERB 15 +#define SCE_RAKU_NUMBER 16 +#define SCE_RAKU_PREPROCESSOR 17 +#define SCE_RAKU_OPERATOR 18 +#define SCE_RAKU_WORD 19 +#define SCE_RAKU_FUNCTION 20 +#define SCE_RAKU_IDENTIFIER 21 +#define SCE_RAKU_TYPEDEF 22 +#define SCE_RAKU_MU 23 +#define SCE_RAKU_POSITIONAL 24 +#define SCE_RAKU_ASSOCIATIVE 25 +#define SCE_RAKU_CALLABLE 26 +#define SCE_RAKU_GRAMMAR 27 +#define SCE_RAKU_CLASS 28 /* --Autogenerated -- end of section automatically generated from Scintilla.iface */ #endif diff --git a/scintilla/include/Scintilla.h b/scintilla/include/Scintilla.h index b4b4f2e7ec..6f59d4e278 100644 --- a/scintilla/include/Scintilla.h +++ b/scintilla/include/Scintilla.h @@ -38,6 +38,8 @@ typedef intptr_t sptr_t; typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, sptr_t lParam); +#ifndef SCI_DISABLE_AUTOGENERATED + /* ++Autogenerated -- start of section automatically generated from Scintilla.iface */ #define INVALID_POSITION -1 #define SCI_START 2000 @@ -63,6 +65,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_CANREDO 2016 #define SCI_MARKERLINEFROMHANDLE 2017 #define SCI_MARKERDELETEHANDLE 2018 +#define SCI_MARKERHANDLEFROMLINE 2732 +#define SCI_MARKERNUMBERFROMLINE 2733 #define SCI_GETUNDOCOLLECTION 2019 #define SCWS_INVISIBLE 0 #define SCWS_VISIBLEALWAYS 1 @@ -93,6 +97,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_SETBUFFEREDDRAW 2035 #define SCI_SETTABWIDTH 2036 #define SCI_GETTABWIDTH 2121 +#define SCI_SETTABMINIMUMWIDTH 2724 +#define SCI_GETTABMINIMUMWIDTH 2725 #define SCI_CLEARTABSTOPS 2675 #define SCI_ADDTABSTOP 2676 #define SCI_GETNEXTTABSTOP 2677 @@ -102,6 +108,13 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SC_IME_INLINE 1 #define SCI_GETIMEINTERACTION 2678 #define SCI_SETIMEINTERACTION 2679 +#define SC_ALPHA_TRANSPARENT 0 +#define SC_ALPHA_OPAQUE 255 +#define SC_ALPHA_NOALPHA 256 +#define SC_CURSORNORMAL -1 +#define SC_CURSORARROW 2 +#define SC_CURSORWAIT 4 +#define SC_CURSORREVERSEARROW 7 #define MARKER_MAX 31 #define SC_MARK_CIRCLE 0 #define SC_MARK_ROUNDRECT 1 @@ -293,14 +306,14 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define INDIC_POINTCHARACTER 19 #define INDIC_GRADIENT 20 #define INDIC_GRADIENTCENTRE 21 +#define INDIC_CONTAINER 8 #define INDIC_IME 32 #define INDIC_IME_MAX 35 #define INDIC_MAX 35 -#define INDIC_CONTAINER 8 -#define INDIC0_MASK 0x20 -#define INDIC1_MASK 0x40 -#define INDIC2_MASK 0x80 -#define INDICS_MASK 0xE0 +#define INDICATOR_CONTAINER 8 +#define INDICATOR_IME 32 +#define INDICATOR_IME_MAX 35 +#define INDICATOR_MAX 35 #define SCI_INDICSETSTYLE 2080 #define SCI_INDICGETSTYLE 2081 #define SCI_INDICSETFORE 2082 @@ -399,6 +412,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SC_PRINT_SCREENCOLOURS 5 #define SCI_SETPRINTCOLOURMODE 2148 #define SCI_GETPRINTCOLOURMODE 2149 +#define SCFIND_NONE 0x0 #define SCFIND_WHOLEWORD 0x2 #define SCFIND_MATCHCASE 0x4 #define SCFIND_WORDSTART 0x00100000 @@ -448,8 +462,12 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_GETCARETWIDTH 2189 #define SCI_SETTARGETSTART 2190 #define SCI_GETTARGETSTART 2191 +#define SCI_SETTARGETSTARTVIRTUALSPACE 2728 +#define SCI_GETTARGETSTARTVIRTUALSPACE 2729 #define SCI_SETTARGETEND 2192 #define SCI_GETTARGETEND 2193 +#define SCI_SETTARGETENDVIRTUALSPACE 2730 +#define SCI_GETTARGETENDVIRTUALSPACE 2731 #define SCI_SETTARGETRANGE 2686 #define SCI_GETTARGETTEXT 2687 #define SCI_TARGETFROMSELECTION 2287 @@ -669,6 +687,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_BRACEBADLIGHT 2352 #define SCI_BRACEBADLIGHTINDICATOR 2499 #define SCI_BRACEMATCH 2353 +#define SCI_BRACEMATCHNEXT 2369 #define SCI_GETVIEWEOL 2355 #define SCI_SETVIEWEOL 2356 #define SCI_GETDOCPOINTER 2357 @@ -686,6 +705,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_SETEDGECOLOUR 2365 #define SCI_MULTIEDGEADDLINE 2694 #define SCI_MULTIEDGECLEARALL 2695 +#define SCI_GETMULTIEDGECOLUMN 2749 #define SCI_SEARCHANCHOR 2366 #define SCI_SEARCHNEXT 2367 #define SCI_SEARCHPREV 2368 @@ -720,10 +740,6 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_GETMOUSEDOWNCAPTURES 2385 #define SCI_SETMOUSEWHEELCAPTURES 2696 #define SCI_GETMOUSEWHEELCAPTURES 2697 -#define SC_CURSORNORMAL -1 -#define SC_CURSORARROW 2 -#define SC_CURSORWAIT 4 -#define SC_CURSORREVERSEARROW 7 #define SCI_SETCURSOR 2386 #define SCI_GETCURSOR 2387 #define SCI_SETCONTROLCHARSYMBOL 2388 @@ -818,26 +834,24 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_SETLENGTHFORENCODE 2448 #define SCI_ENCODEDFROMUTF8 2449 #define SCI_FINDCOLUMN 2456 -#define SCI_GETCARETSTICKY 2457 -#define SCI_SETCARETSTICKY 2458 #define SC_CARETSTICKY_OFF 0 #define SC_CARETSTICKY_ON 1 #define SC_CARETSTICKY_WHITESPACE 2 +#define SCI_GETCARETSTICKY 2457 +#define SCI_SETCARETSTICKY 2458 #define SCI_TOGGLECARETSTICKY 2459 #define SCI_SETPASTECONVERTENDINGS 2467 #define SCI_GETPASTECONVERTENDINGS 2468 #define SCI_SELECTIONDUPLICATE 2469 -#define SC_ALPHA_TRANSPARENT 0 -#define SC_ALPHA_OPAQUE 255 -#define SC_ALPHA_NOALPHA 256 #define SCI_SETCARETLINEBACKALPHA 2470 #define SCI_GETCARETLINEBACKALPHA 2471 #define CARETSTYLE_INVISIBLE 0 #define CARETSTYLE_LINE 1 #define CARETSTYLE_BLOCK 2 #define CARETSTYLE_OVERSTRIKE_BAR 0 -#define CARETSTYLE_OVERSTRIKE_BLOCK 16 +#define CARETSTYLE_OVERSTRIKE_BLOCK 0x10 #define CARETSTYLE_INS_MASK 0xF +#define CARETSTYLE_BLOCK_AFTER 0x100 #define SCI_SETCARETSTYLE 2512 #define SCI_GETCARETSTYLE 2513 #define SCI_SETINDICATORCURRENT 2500 @@ -896,6 +910,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_ANNOTATIONGETSTYLEOFFSET 2551 #define SCI_RELEASEALLEXTENDEDSTYLES 2552 #define SCI_ALLOCATEEXTENDEDSTYLES 2553 +#define UNDO_NONE 0 #define UNDO_MAY_COALESCE 1 #define SCI_ADDUNDOACTION 2560 #define SCI_CHARPOSITIONFROMPOINT 2561 @@ -928,7 +943,9 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_GETSELECTIONNANCHORVIRTUALSPACE 2583 #define SCI_SETSELECTIONNSTART 2584 #define SCI_GETSELECTIONNSTART 2585 +#define SCI_GETSELECTIONNSTARTVIRTUALSPACE 2726 #define SCI_SETSELECTIONNEND 2586 +#define SCI_GETSELECTIONNENDVIRTUALSPACE 2727 #define SCI_GETSELECTIONNEND 2587 #define SCI_SETRECTANGULARSELECTIONCARET 2588 #define SCI_GETRECTANGULARSELECTIONCARET 2589 @@ -992,6 +1009,18 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_SETREPRESENTATION 2665 #define SCI_GETREPRESENTATION 2666 #define SCI_CLEARREPRESENTATION 2667 +#define SCI_EOLANNOTATIONSETTEXT 2740 +#define SCI_EOLANNOTATIONGETTEXT 2741 +#define SCI_EOLANNOTATIONSETSTYLE 2742 +#define SCI_EOLANNOTATIONGETSTYLE 2743 +#define SCI_EOLANNOTATIONCLEARALL 2744 +#define EOLANNOTATION_HIDDEN 0 +#define EOLANNOTATION_STANDARD 1 +#define EOLANNOTATION_BOXED 2 +#define SCI_EOLANNOTATIONSETVISIBLE 2745 +#define SCI_EOLANNOTATIONGETVISIBLE 2746 +#define SCI_EOLANNOTATIONSETSTYLEOFFSET 2747 +#define SCI_EOLANNOTATIONGETSTYLEOFFSET 2748 #define SCI_STARTRECORD 3001 #define SCI_STOPRECORD 3002 #define SCI_SETLEXER 4001 @@ -1028,6 +1057,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_NAMEOFSTYLE 4030 #define SCI_TAGSOFSTYLE 4031 #define SCI_DESCRIPTIONOFSTYLE 4032 +#define SC_MOD_NONE 0x0 #define SC_MOD_INSERTTEXT 0x1 #define SC_MOD_DELETETEXT 0x2 #define SC_MOD_CHANGESTYLE 0x4 @@ -1050,7 +1080,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SC_MOD_LEXERSTATE 0x80000 #define SC_MOD_INSERTCHECK 0x100000 #define SC_MOD_CHANGETABSTOPS 0x200000 -#define SC_MODEVENTMASKALL 0x3FFFFF +#define SC_MOD_CHANGEEOLANNOTATION 0x400000 +#define SC_MODEVENTMASKALL 0x7FFFFF #define SC_UPDATE_CONTENT 0x1 #define SC_UPDATE_SELECTION 0x2 #define SC_UPDATE_V_SCROLL 0x4 @@ -1089,6 +1120,9 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SC_AC_TAB 3 #define SC_AC_NEWLINE 4 #define SC_AC_COMMAND 5 +#define SC_CHARACTERSOURCE_DIRECT_INPUT 0 +#define SC_CHARACTERSOURCE_TENTATIVE_INPUT 1 +#define SC_CHARACTERSOURCE_IME_RESULT 2 #define SCN_STYLENEEDED 2000 #define SCN_CHARADDED 2001 #define SCN_SAVEPOINTREACHED 2002 @@ -1133,6 +1167,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #endif /* --Autogenerated -- end of section automatically generated from Scintilla.iface */ +#endif + /* These structures are defined to be exactly the same shape as the Win32 * CHARRANGE, TEXTRANGE, FINDTEXTEX, FORMATRANGE, and NMHDR structs. * So older code that treats Scintilla as a RichEdit will work. */ @@ -1226,6 +1262,7 @@ struct SCNotification { int updated; /* SCN_UPDATEUI */ int listCompletionMethod; /* SCN_AUTOCSELECTION, SCN_AUTOCCOMPLETED, SCN_USERLISTSELECTION, */ + int characterSource; /* SCN_CHARADDED */ }; #ifdef INCLUDE_DEPRECATED_FEATURES @@ -1243,6 +1280,13 @@ struct SCNotification { #define SCI_GETSTYLEBITS 2091 #define SCI_GETSTYLEBITSNEEDED 4011 +#define INDIC0_MASK 0x20 +#define INDIC1_MASK 0x40 +#define INDIC2_MASK 0x80 +#define INDICS_MASK 0xE0 + #endif +#include "Compat.h" + #endif diff --git a/scintilla/include/Scintilla.iface b/scintilla/include/Scintilla.iface index c009371c10..7d32ed46df 100644 --- a/scintilla/include/Scintilla.iface +++ b/scintilla/include/Scintilla.iface @@ -10,7 +10,7 @@ ## A line starting with # followed by a space is a documentation comment and refers ## to the next feature definition. -## Each feature is defined by a line starting with fun, get, set, val or evt. +## Each feature is defined by a line starting with fun, get, set, val, evt, enu, lex, or ali. ## cat -> start a category ## fun -> a function ## get -> a property get function @@ -19,6 +19,7 @@ ## evt -> an event ## enu -> associate an enumeration with a set of vals with a prefix ## lex -> associate a lexer with the lexical classes it produces +## ali -> add an alias for a val, commonly adding '_' to separate words ## ## All other feature names should be ignored. They may be defined in the future. ## A property may have a set function, a get function or both. Each will have @@ -46,19 +47,22 @@ ## to enu. The name may not be the same as that used within the lexer so the lexerVal ## should be used to tie these entities together. -## Types: +## Types: Never start with a capital letter ## void ## int ## bool -> integer, 1=true, 0=false -## position -> integer position in a document +## position -> intptr_t position in a document +## line -> intptr_t line in a document ## colour -> colour integer containing red, green and blue bytes. ## string -> pointer to const character ## stringresult -> pointer to character, NULL-> return size of result ## cells -> pointer to array of cells, each cell containing a style byte and character byte +## pointer -> void* pointer that may point to a document, loader, internal text storage or similar ## textrange -> range of a min and a max position with an output string ## findtext -> searchrange, text -> foundposition ## keymod -> integer containing key in low half and modifiers in high half ## formatrange +## Enumeration types always start with a capital letter ## Types no longer used: ## findtextex -> searchrange ## charrange -> range of a min and a max position @@ -90,28 +94,28 @@ val SCI_OPTIONAL_START=3000 val SCI_LEXER_START=4000 # Add text to the document at current position. -fun void AddText=2001(int length, string text) +fun void AddText=2001(position length, string text) # Add array of cells to document. -fun void AddStyledText=2002(int length, cells c) +fun void AddStyledText=2002(position length, cells c) # Insert string at a position. fun void InsertText=2003(position pos, string text) # Change the text that is being inserted in response to SC_MOD_INSERTCHECK -fun void ChangeInsertion=2672(int length, string text) +fun void ChangeInsertion=2672(position length, string text) # Delete all text in the document. fun void ClearAll=2004(,) # Delete a range of text in the document. -fun void DeleteRange=2645(position start, int lengthDelete) +fun void DeleteRange=2645(position start, position lengthDelete) # Set all style bytes to 0, remove all folding information. fun void ClearDocumentStyle=2005(,) # Returns the number of bytes in the document. -get int GetLength=2006(,) +get position GetLength=2006(,) # Returns the character byte at the position. get int GetCharAt=2007(position pos,) @@ -141,17 +145,23 @@ fun void SetSavePoint=2014(,) # Retrieve a buffer of cells. # Returns the number of bytes in the buffer not including terminating NULs. -fun int GetStyledText=2015(, textrange tr) +fun position GetStyledText=2015(, textrange tr) # Are there any redoable actions in the undo history? fun bool CanRedo=2016(,) # Retrieve the line number at which a particular marker is located. -fun int MarkerLineFromHandle=2017(int markerHandle,) +fun line MarkerLineFromHandle=2017(int markerHandle,) # Delete a marker. fun void MarkerDeleteHandle=2018(int markerHandle,) +# Retrieve marker handles of a line +fun int MarkerHandleFromLine=2732(line line, int which) + +# Retrieve marker number of a marker handle +fun int MarkerNumberFromLine=2733(line line, int which) + # Is undo history being collected? get bool GetUndoCollection=2019(,) @@ -161,23 +171,30 @@ val SCWS_VISIBLEALWAYS=1 val SCWS_VISIBLEAFTERINDENT=2 val SCWS_VISIBLEONLYININDENT=3 +ali SCWS_VISIBLEALWAYS=VISIBLE_ALWAYS +ali SCWS_VISIBLEAFTERINDENT=VISIBLE_AFTER_INDENT +ali SCWS_VISIBLEONLYININDENT=VISIBLE_ONLY_IN_INDENT + # Are white space characters currently visible? # Returns one of SCWS_* constants. -get int GetViewWS=2020(,) +get WhiteSpace GetViewWS=2020(,) # Make white space characters invisible, always visible or visible outside indentation. -set void SetViewWS=2021(int viewWS,) +set void SetViewWS=2021(WhiteSpace viewWS,) enu TabDrawMode=SCTD_ val SCTD_LONGARROW=0 val SCTD_STRIKEOUT=1 +ali SCTD_LONGARROW=LONG_ARROW +ali SCTD_STRIKEOUT=STRIKE_OUT + # Retrieve the current tab draw mode. # Returns one of SCTD_* constants. -get int GetTabDrawMode=2698(,) +get TabDrawMode GetTabDrawMode=2698(,) # Set how tabs are drawn when visible. -set void SetTabDrawMode=2699(int tabDrawMode,) +set void SetTabDrawMode=2699(TabDrawMode tabDrawMode,) # Find the position from a point within the window. fun position PositionFromPoint=2022(int x, int y) @@ -187,7 +204,7 @@ fun position PositionFromPoint=2022(int x, int y) fun position PositionFromPointClose=2023(int x, int y) # Set caret to start of a line and ensure it is visible. -fun void GotoLine=2024(int line,) +fun void GotoLine=2024(line line,) # Set caret to a position and ensure it is visible. fun void GotoPos=2025(position caret,) @@ -199,7 +216,7 @@ set void SetAnchor=2026(position anchor,) # Retrieve the text of the line containing the caret. # Returns the index of the caret on the line. # Result is NUL-terminated. -fun int GetCurLine=2027(int length, stringresult text) +fun position GetCurLine=2027(position length, stringresult text) # Retrieve the position of the last correctly styled character. get position GetEndStyled=2028(,) @@ -209,14 +226,16 @@ val SC_EOL_CRLF=0 val SC_EOL_CR=1 val SC_EOL_LF=2 +ali SC_EOL_CRLF=CR_LF + # Convert all line endings in the document to one mode. -fun void ConvertEOLs=2029(int eolMode,) +fun void ConvertEOLs=2029(EndOfLine eolMode,) # Retrieve the current end of line mode - one of CRLF, CR, or LF. -get int GetEOLMode=2030(,) +get EndOfLine GetEOLMode=2030(,) # Set the current end of line mode. -set void SetEOLMode=2031(int eolMode,) +set void SetEOLMode=2031(EndOfLine eolMode,) # Set the current styling position to start. # The unused parameter is no longer used and should be set to 0. @@ -224,7 +243,7 @@ fun void StartStyling=2032(position start, int unused) # Change style from current styling position for length characters to a style # and move the current styling position to after this newly styled segment. -fun void SetStyling=2033(int length, int style) +fun void SetStyling=2033(position length, int style) # Is drawing done first into a buffer or direct to the screen? get bool GetBufferedDraw=2034(,) @@ -239,14 +258,20 @@ set void SetTabWidth=2036(int tabWidth,) # Retrieve the visible size of a tab. get int GetTabWidth=2121(,) +# Set the minimum visual width of a tab. +set void SetTabMinimumWidth=2724(int pixels,) + +# Get the minimum visual width of a tab. +get int GetTabMinimumWidth=2725(,) + # Clear explicit tabstops on a line. -fun void ClearTabStops=2675(int line,) +fun void ClearTabStops=2675(line line,) # Add an explicit tab stop for a line. -fun void AddTabStop=2676(int line, int x) +fun void AddTabStop=2676(line line, int x) # Find the next explicit tab stop position on a line after a position. -fun int GetNextTabStop=2677(int line, int x) +fun int GetNextTabStop=2677(line line, int x) # The SC_CP_UTF8 value can be used to enter Unicode mode. # This is the same value as CP_UTF8 in Windows @@ -261,10 +286,25 @@ val SC_IME_WINDOWED=0 val SC_IME_INLINE=1 # Is the IME displayed in a window or inline? -get int GetIMEInteraction=2678(,) +get IMEInteraction GetIMEInteraction=2678(,) -# Choose to display the the IME in a winow or inline. -set void SetIMEInteraction=2679(int imeInteraction,) +# Choose to display the IME in a window or inline. +set void SetIMEInteraction=2679(IMEInteraction imeInteraction,) + +enu Alpha=SC_ALPHA_ +val SC_ALPHA_TRANSPARENT=0 +val SC_ALPHA_OPAQUE=255 +val SC_ALPHA_NOALPHA=256 + +ali SC_ALPHA_NOALPHA=NO_ALPHA + +enu CursorShape=SC_CURSOR +val SC_CURSORNORMAL=-1 +val SC_CURSORARROW=2 +val SC_CURSORWAIT=4 +val SC_CURSORREVERSEARROW=7 + +ali SC_CURSORREVERSEARROW=REVERSE_ARROW enu MarkerSymbol=SC_MARK_ val MARKER_MAX=31 @@ -308,6 +348,29 @@ val SC_MARK_VERTICALBOOKMARK=32 val SC_MARK_CHARACTER=10000 +ali SC_MARK_ROUNDRECT=ROUND_RECT +ali SC_MARK_SMALLRECT=SMALL_RECT +ali SC_MARK_SHORTARROW=SHORT_ARROW +ali SC_MARK_ARROWDOWN=ARROW_DOWN +ali SC_MARK_VLINE=V_LINE +ali SC_MARK_LCORNER=L_CORNER +ali SC_MARK_TCORNER=T_CORNER +ali SC_MARK_BOXPLUS=BOX_PLUS +ali SC_MARK_BOXPLUSCONNECTED=BOX_PLUS_CONNECTED +ali SC_MARK_BOXMINUS=BOX_MINUS +ali SC_MARK_BOXMINUSCONNECTED=BOX_MINUS_CONNECTED +ali SC_MARK_LCORNERCURVE=L_CORNER_CURVE +ali SC_MARK_TCORNERCURVE=T_CORNER_CURVE +ali SC_MARK_CIRCLEPLUS=CIRCLE_PLUS +ali SC_MARK_CIRCLEPLUSCONNECTED=CIRCLE_PLUS_CONNECTED +ali SC_MARK_CIRCLEMINUS=CIRCLE_MINUS +ali SC_MARK_CIRCLEMINUSCONNECTED=CIRCLE_MINUS_CONNECTED +ali SC_MARK_DOTDOTDOT=DOT_DOT_DOT +ali SC_MARK_FULLRECT=FULL_RECT +ali SC_MARK_LEFTRECT=LEFT_RECT +ali SC_MARK_RGBAIMAGE=RGBA_IMAGE +ali SC_MARK_VERTICALBOOKMARK=VERTICAL_BOOKMARK + enu MarkerOutline=SC_MARKNUM_ # Markers used for outlining column. val SC_MARKNUM_FOLDEREND=25 @@ -318,10 +381,18 @@ val SC_MARKNUM_FOLDERSUB=29 val SC_MARKNUM_FOLDER=30 val SC_MARKNUM_FOLDEROPEN=31 +ali SC_MARKNUM_FOLDEREND=FOLDER_END +ali SC_MARKNUM_FOLDEROPENMID=FOLDER_OPEN_MID +ali SC_MARKNUM_FOLDERMIDTAIL=FOLDER_MID_TAIL +ali SC_MARKNUM_FOLDERTAIL=FOLDER_TAIL +ali SC_MARKNUM_FOLDERSUB=FOLDER_SUB +ali SC_MARKNUM_FOLDEROPEN=FOLDER_OPEN + +# SC_MASK_FOLDERS doesn't go in an enumeration as larger than max 32-bit positive integer val SC_MASK_FOLDERS=0xFE000000 # Set the symbol used for a particular marker number. -fun void MarkerDefine=2040(int markerNumber, int markerSymbol) +fun void MarkerDefine=2040(int markerNumber, MarkerSymbol markerSymbol) # Set the foreground colour used for a particular marker number. set void MarkerSetFore=2041(int markerNumber, colour fore) @@ -332,36 +403,36 @@ set void MarkerSetBack=2042(int markerNumber, colour back) # Set the background colour used for a particular marker number when its folding block is selected. set void MarkerSetBackSelected=2292(int markerNumber, colour back) -# Enable/disable highlight for current folding bloc (smallest one that contains the caret) +# Enable/disable highlight for current folding block (smallest one that contains the caret) fun void MarkerEnableHighlight=2293(bool enabled,) # Add a marker to a line, returning an ID which can be used to find or delete the marker. -fun int MarkerAdd=2043(int line, int markerNumber) +fun int MarkerAdd=2043(line line, int markerNumber) # Delete a marker from a line. -fun void MarkerDelete=2044(int line, int markerNumber) +fun void MarkerDelete=2044(line line, int markerNumber) # Delete all markers with a particular number from all lines. fun void MarkerDeleteAll=2045(int markerNumber,) # Get a bit mask of all the markers set on a line. -fun int MarkerGet=2046(int line,) +fun int MarkerGet=2046(line line,) # Find the next line at or after lineStart that includes a marker in mask. # Return -1 when no more lines. -fun int MarkerNext=2047(int lineStart, int markerMask) +fun line MarkerNext=2047(line lineStart, int markerMask) # Find the previous line before lineStart that includes a marker in mask. -fun int MarkerPrevious=2048(int lineStart, int markerMask) +fun line MarkerPrevious=2048(line lineStart, int markerMask) # Define a marker from a pixmap. fun void MarkerDefinePixmap=2049(int markerNumber, string pixmap) # Add a set of markers to a line. -fun void MarkerAddSet=2466(int line, int markerSet) +fun void MarkerAddSet=2466(line line, int markerSet) # Set the alpha used for a marker that is drawn in the text area, not the margin. -set void MarkerSetAlpha=2476(int markerNumber, int alpha) +set void MarkerSetAlpha=2476(int markerNumber, Alpha alpha) val SC_MAX_MARGIN=4 @@ -374,11 +445,13 @@ val SC_MARGIN_TEXT=4 val SC_MARGIN_RTEXT=5 val SC_MARGIN_COLOUR=6 +ali SC_MARGIN_RTEXT=R_TEXT + # Set a margin to be either numeric or symbolic. -set void SetMarginTypeN=2240(int margin, int marginType) +set void SetMarginTypeN=2240(int margin, MarginType marginType) # Retrieve the type of a margin. -get int GetMarginTypeN=2241(int margin,) +get MarginType GetMarginTypeN=2241(int margin,) # Set the width of a margin to a width expressed in pixels. set void SetMarginWidthN=2242(int margin, int pixelWidth) @@ -399,10 +472,10 @@ set void SetMarginSensitiveN=2246(int margin, bool sensitive) get bool GetMarginSensitiveN=2247(int margin,) # Set the cursor shown when the mouse is inside a margin. -set void SetMarginCursorN=2248(int margin, int cursor) +set void SetMarginCursorN=2248(int margin, CursorShape cursor) # Retrieve the cursor shown in a margin. -get int GetMarginCursorN=2249(int margin,) +get CursorShape GetMarginCursorN=2249(int margin,) # Set the background colour of a margin. Only visible for SC_MARGIN_COLOUR. set void SetMarginBackN=2250(int margin, colour back) @@ -429,6 +502,15 @@ val STYLE_FOLDDISPLAYTEXT=39 val STYLE_LASTPREDEFINED=39 val STYLE_MAX=255 +ali STYLE_LINENUMBER=LINE_NUMBER +ali STYLE_BRACELIGHT=BRACE_LIGHT +ali STYLE_BRACEBAD=BRACE_BAD +ali STYLE_CONTROLCHAR=CONTROL_CHAR +ali STYLE_INDENTGUIDE=INDENT_GUIDE +ali STYLE_CALLTIP=CALL_TIP +ali STYLE_FOLDDISPLAYTEXT=FOLD_DISPLAY_TEXT +ali STYLE_LASTPREDEFINED=LAST_PREDEFINED + # Character set identifiers are used in StyleSetCharacterSet. # The values are the same as the Windows *_CHARSET values. enu CharacterSet=SC_CHARSET_ @@ -455,6 +537,13 @@ val SC_CHARSET_VIETNAMESE=163 val SC_CHARSET_THAI=222 val SC_CHARSET_8859_15=1000 +ali SC_CHARSET_CHINESEBIG5=CHINESE_BIG5 +ali SC_CHARSET_EASTEUROPE=EAST_EUROPE +ali SC_CHARSET_GB2312=G_B_2312 +ali SC_CHARSET_OEM866=OEM_866 +ali SC_CHARSET_SHIFTJIS=SHIFT_JIS +ali SC_CHARSET_8859_15=ISO_8859_15 + # Clear all the styles and make equivalent to the global default style. fun void StyleClearAll=2050(,) @@ -518,10 +607,10 @@ get bool StyleGetEOLFilled=2487(int style,) get bool StyleGetUnderline=2488(int style,) # Get is a style mixed case, or to force upper or lower case. -get int StyleGetCase=2489(int style,) +get CaseVisible StyleGetCase=2489(int style,) # Get the character get of the font in a style. -get int StyleGetCharacterSet=2490(int style,) +get CharacterSet StyleGetCharacterSet=2490(int style,) # Get is a style visible or not. get bool StyleGetVisible=2491(int style,) @@ -534,7 +623,7 @@ get bool StyleGetChangeable=2492(int style,) get bool StyleGetHotSpot=2493(int style,) # Set a style to be mixed case, or to force upper or lower case. -set void StyleSetCase=2060(int style, int caseVisible) +set void StyleSetCase=2060(int style, CaseVisible caseVisible) val SC_FONT_SIZE_MULTIPLIER=100 @@ -549,14 +638,16 @@ val SC_WEIGHT_NORMAL=400 val SC_WEIGHT_SEMIBOLD=600 val SC_WEIGHT_BOLD=700 +ali SC_WEIGHT_SEMIBOLD=SEMI_BOLD + # Set the weight of characters of a style. -set void StyleSetWeight=2063(int style, int weight) +set void StyleSetWeight=2063(int style, FontWeight weight) # Get the weight of characters of a style. -get int StyleGetWeight=2064(int style,) +get FontWeight StyleGetWeight=2064(int style,) # Set the character set of the font in a style. -set void StyleSetCharacterSet=2066(int style, int characterSet) +set void StyleSetCharacterSet=2066(int style, CharacterSet characterSet) # Set a style to be a hotspot or not. set void StyleSetHotSpot=2409(int style, bool hotspot) @@ -568,10 +659,10 @@ fun void SetSelFore=2067(bool useSetting, colour fore) fun void SetSelBack=2068(bool useSetting, colour back) # Get the alpha of the selection. -get int GetSelAlpha=2477(,) +get Alpha GetSelAlpha=2477(,) # Set the alpha of the selection. -set void SetSelAlpha=2478(int alpha,) +set void SetSelAlpha=2478(Alpha alpha,) # Is the selection end of line filled? get bool GetSelEOLFilled=2479(,) @@ -592,7 +683,7 @@ fun void ClearCmdKey=2071(keymod keyDefinition,) fun void ClearAllCmdKeys=2072(,) # Set the styles for a segment of the document. -fun void SetStylingEx=2073(int length, string styles) +fun void SetStylingEx=2073(position length, string styles) # Set a style to be visible or not. set void StyleSetVisible=2074(int style, bool visible) @@ -648,20 +739,39 @@ val INDIC_POINT=18 val INDIC_POINTCHARACTER=19 val INDIC_GRADIENT=20 val INDIC_GRADIENTCENTRE=21 + +# INDIC_CONTAINER, INDIC_IME, INDIC_IME_MAX, and INDIC_MAX are indicator numbers, +# not IndicatorStyles so should not really be in the INDIC_ enumeration. +# They are redeclared in IndicatorNumbers INDICATOR_. +val INDIC_CONTAINER=8 val INDIC_IME=32 val INDIC_IME_MAX=35 val INDIC_MAX=35 -val INDIC_CONTAINER=8 -val INDIC0_MASK=0x20 -val INDIC1_MASK=0x40 -val INDIC2_MASK=0x80 -val INDICS_MASK=0xE0 + +enu IndicatorNumbers=INDICATOR_ +val INDICATOR_CONTAINER=8 +val INDICATOR_IME=32 +val INDICATOR_IME_MAX=35 +val INDICATOR_MAX=35 + +ali INDIC_TT=T_T +ali INDIC_ROUNDBOX=ROUND_BOX +ali INDIC_STRAIGHTBOX=STRAIGHT_BOX +ali INDIC_SQUIGGLELOW=SQUIGGLE_LOW +ali INDIC_DOTBOX=DOT_BOX +ali INDIC_SQUIGGLEPIXMAP=SQUIGGLE_PIXMAP +ali INDIC_COMPOSITIONTHICK=COMPOSITION_THICK +ali INDIC_COMPOSITIONTHIN=COMPOSITION_THIN +ali INDIC_FULLBOX=FULL_BOX +ali INDIC_TEXTFORE=TEXT_FORE +ali INDIC_POINTCHARACTER=POINT_CHARACTER +ali INDIC_GRADIENTCENTRE=GRADIENT_CENTRE # Set an indicator to plain, squiggle or TT. -set void IndicSetStyle=2080(int indicator, int indicatorStyle) +set void IndicSetStyle=2080(int indicator, IndicatorStyle indicatorStyle) # Retrieve the style of an indicator. -get int IndicGetStyle=2081(int indicator,) +get IndicatorStyle IndicGetStyle=2081(int indicator,) # Set the foreground colour of an indicator. set void IndicSetFore=2082(int indicator, colour fore) @@ -676,10 +786,10 @@ set void IndicSetUnder=2510(int indicator, bool under) get bool IndicGetUnder=2511(int indicator,) # Set a hover indicator to plain, squiggle or TT. -set void IndicSetHoverStyle=2680(int indicator, int indicatorStyle) +set void IndicSetHoverStyle=2680(int indicator, IndicatorStyle indicatorStyle) # Retrieve the hover style of an indicator. -get int IndicGetHoverStyle=2681(int indicator,) +get IndicatorStyle IndicGetHoverStyle=2681(int indicator,) # Set the foreground hover colour of an indicator. set void IndicSetHoverFore=2682(int indicator, colour fore) @@ -687,17 +797,20 @@ set void IndicSetHoverFore=2682(int indicator, colour fore) # Retrieve the foreground hover colour of an indicator. get colour IndicGetHoverFore=2683(int indicator,) +enu IndicValue=SC_INDICVALUE val SC_INDICVALUEBIT=0x1000000 val SC_INDICVALUEMASK=0xFFFFFF enu IndicFlag=SC_INDICFLAG_ val SC_INDICFLAG_VALUEFORE=1 +ali SC_INDICFLAG_VALUEFORE=VALUE_FORE + # Set the attributes of an indicator. -set void IndicSetFlags=2684(int indicator, int flags) +set void IndicSetFlags=2684(int indicator, IndicFlag flags) # Retrieve the attributes of an indicator. -get int IndicGetFlags=2685(int indicator,) +get IndicFlag IndicGetFlags=2685(int indicator,) # Set the foreground colour of all whitespace and whether to use this setting. fun void SetWhitespaceFore=2084(bool useSetting, colour fore) @@ -712,10 +825,10 @@ set void SetWhitespaceSize=2086(int size,) get int GetWhitespaceSize=2087(,) # Used to hold extra styling information for each line. -set void SetLineState=2092(int line, int state) +set void SetLineState=2092(line line, int state) # Retrieve the extra styling information for a line. -get int GetLineState=2093(int line,) +get int GetLineState=2093(line line,) # Retrieve the last line number that has line state. get int GetMaxLineState=2094(,) @@ -747,7 +860,7 @@ set void StyleSetChangeable=2099(int style, bool changeable) # Display a auto-completion list. # The lengthEntered parameter indicates how many characters before # the caret should be used to provide context. -fun void AutoCShow=2100(int lengthEntered, string itemList) +fun void AutoCShow=2100(position lengthEntered, string itemList) # Remove the auto-completion list from the screen. fun void AutoCCancel=2101(,) @@ -855,22 +968,22 @@ set void SetUseTabs=2124(bool useTabs,) get bool GetUseTabs=2125(,) # Change the indentation of a line to a number of columns. -set void SetLineIndentation=2126(int line, int indentation) +set void SetLineIndentation=2126(line line, int indentation) # Retrieve the number of columns that a line is indented. -get int GetLineIndentation=2127(int line,) +get int GetLineIndentation=2127(line line,) # Retrieve the position before the first non indentation character on a line. -get position GetLineIndentPosition=2128(int line,) +get position GetLineIndentPosition=2128(line line,) # Retrieve the column number of a position, taking tab width into account. -get int GetColumn=2129(position pos,) +get position GetColumn=2129(position pos,) # Count characters between two positions. -fun int CountCharacters=2633(position start, position end) +fun position CountCharacters=2633(position start, position end) # Count code units between two positions. -fun int CountCodeUnits=2715(position start, position end) +fun position CountCodeUnits=2715(position start, position end) # Show or hide the horizontal scroll bar. set void SetHScrollBar=2130(bool visible,) @@ -883,21 +996,24 @@ val SC_IV_REAL=1 val SC_IV_LOOKFORWARD=2 val SC_IV_LOOKBOTH=3 +ali SC_IV_LOOKFORWARD=LOOK_FORWARD +ali SC_IV_LOOKBOTH=LOOK_BOTH + # Show or hide indentation guides. -set void SetIndentationGuides=2132(int indentView,) +set void SetIndentationGuides=2132(IndentView indentView,) # Are the indentation guides visible? -get int GetIndentationGuides=2133(,) +get IndentView GetIndentationGuides=2133(,) # Set the highlighted indentation guide column. # 0 = no highlighted guide. -set void SetHighlightGuide=2134(int column,) +set void SetHighlightGuide=2134(position column,) # Get the highlighted indentation guide column. -get int GetHighlightGuide=2135(,) +get position GetHighlightGuide=2135(,) # Get the position after the last visible characters on a line. -get position GetLineEndPosition=2136(int line,) +get position GetLineEndPosition=2136(line line,) # Get the code page used to interpret the bytes of the document as characters. get int GetCodePage=2137(,) @@ -947,13 +1063,20 @@ val SC_PRINT_COLOURONWHITEDEFAULTBG=4 # PrintColourMode - use same colours as screen, including line number margins. val SC_PRINT_SCREENCOLOURS=5 +ali SC_PRINT_INVERTLIGHT=INVERT_LIGHT +ali SC_PRINT_BLACKONWHITE=BLACK_ON_WHITE +ali SC_PRINT_COLOURONWHITE=COLOUR_ON_WHITE +ali SC_PRINT_COLOURONWHITEDEFAULTBG=COLOUR_ON_WHITE_DEFAULT_B_G +ali SC_PRINT_SCREENCOLOURS=SCREEN_COLOURS + # Modify colours when printing for clearer printed text. -set void SetPrintColourMode=2148(int mode,) +set void SetPrintColourMode=2148(PrintOption mode,) # Returns the print colour mode. -get int GetPrintColourMode=2149(,) +get PrintOption GetPrintColourMode=2149(,) enu FindOption=SCFIND_ +val SCFIND_NONE=0x0 val SCFIND_WHOLEWORD=0x2 val SCFIND_MATCHCASE=0x4 val SCFIND_WORDSTART=0x00100000 @@ -961,21 +1084,27 @@ val SCFIND_REGEXP=0x00200000 val SCFIND_POSIX=0x00400000 val SCFIND_CXX11REGEX=0x00800000 +ali SCFIND_WHOLEWORD=WHOLE_WORD +ali SCFIND_MATCHCASE=MATCH_CASE +ali SCFIND_WORDSTART=WORD_START +ali SCFIND_REGEXP=REG_EXP +ali SCFIND_CXX11REGEX=CXX11_REG_EX + # Find some text in the document. -fun position FindText=2150(int searchFlags, findtext ft) +fun position FindText=2150(FindOption searchFlags, findtext ft) # On Windows, will draw the document into a display context such as a printer. fun position FormatRange=2151(bool draw, formatrange fr) # Retrieve the display line at the top of the display. -get int GetFirstVisibleLine=2152(,) +get line GetFirstVisibleLine=2152(,) # Retrieve the contents of a line. # Returns the length of the line. -fun int GetLine=2153(int line, stringresult text) +fun position GetLine=2153(line line, stringresult text) # Returns the number of lines in the document. There is always at least one. -get int GetLineCount=2154(,) +get line GetLineCount=2154(,) # Sets the size in pixels of the left margin. set void SetMarginLeft=2155(, int pixelWidth) @@ -998,11 +1127,11 @@ fun void SetSel=2160(position anchor, position caret) # Retrieve the selected text. # Return the length of the text. # Result is NUL-terminated. -fun int GetSelText=2161(, stringresult text) +fun position GetSelText=2161(, stringresult text) # Retrieve a range of text. # Return the length of the text. -fun int GetTextRange=2162(, textrange tr) +fun position GetTextRange=2162(, textrange tr) # Draw the selection either highlighted or in normal (non-highlighted) style. fun void HideSelection=2163(bool hide,) @@ -1014,13 +1143,13 @@ fun int PointXFromPosition=2164(, position pos) fun int PointYFromPosition=2165(, position pos) # Retrieve the line containing a position. -fun int LineFromPosition=2166(position pos,) +fun line LineFromPosition=2166(position pos,) # Retrieve the position at the start of a line. -fun position PositionFromLine=2167(int line,) +fun position PositionFromLine=2167(line line,) # Scroll horizontally and vertically. -fun void LineScroll=2168(int columns, int lines) +fun void LineScroll=2168(position columns, line lines) # Ensure the caret is visible. fun void ScrollCaret=2169(,) @@ -1069,17 +1198,17 @@ fun void SetText=2181(, string text) # Retrieve all the text in the document. # Returns number of characters retrieved. # Result is NUL-terminated. -fun int GetText=2182(int length, stringresult text) +fun position GetText=2182(position length, stringresult text) # Retrieve the number of characters in the document. -get int GetTextLength=2183(,) +get position GetTextLength=2183(,) # Retrieve a pointer to a function that processes messages for this Scintilla. -get int GetDirectFunction=2184(,) +get pointer GetDirectFunction=2184(,) # Retrieve a pointer value to use as the first argument when calling # the function returned by GetDirectFunction. -get int GetDirectPointer=2185(,) +get pointer GetDirectPointer=2185(,) # Set to overtype (true) or insert mode. set void SetOvertype=2186(bool overType,) @@ -1100,6 +1229,12 @@ set void SetTargetStart=2190(position start,) # Get the position that starts the target. get position GetTargetStart=2191(,) +# Sets the virtual space of the target start +set void SetTargetStartVirtualSpace=2728(position space,) + +# Get the virtual space of the target start +get position GetTargetStartVirtualSpace=2729(,) + # Sets the position that ends the target which is used for updating the # document without affecting the scroll position. set void SetTargetEnd=2192(position end,) @@ -1107,11 +1242,17 @@ set void SetTargetEnd=2192(position end,) # Get the position that ends the target. get position GetTargetEnd=2193(,) +# Sets the virtual space of the target end +set void SetTargetEndVirtualSpace=2730(position space,) + +# Get the virtual space of the target end +get position GetTargetEndVirtualSpace=2731(,) + # Sets both the start and end of the target in one call. fun void SetTargetRange=2686(position start, position end) # Retrieve the text in the target. -get int GetTargetText=2687(, stringresult text) +get position GetTargetText=2687(, stringresult text) # Make the target range start and end be the same as the selection range start and end. fun void TargetFromSelection=2287(,) @@ -1122,7 +1263,7 @@ fun void TargetWholeDocument=2690(,) # Replace the target text with the argument text. # Text is counted so it can contain NULs. # Returns the length of the replacement text. -fun int ReplaceTarget=2194(int length, string text) +fun position ReplaceTarget=2194(position length, string text) # Replace the target text with the argument text after \d processing. # Text is counted so it can contain NULs. @@ -1130,18 +1271,18 @@ fun int ReplaceTarget=2194(int length, string text) # matched in the last search operation which were surrounded by \( and \). # Returns the length of the replacement text including any change # caused by processing the \d patterns. -fun int ReplaceTargetRE=2195(int length, string text) +fun position ReplaceTargetRE=2195(position length, string text) # Search for a counted string in the target and set the target to the found # range. Text is counted so it can contain NULs. -# Returns length of range or -1 for failure in which case target is not moved. -fun int SearchInTarget=2197(int length, string text) +# Returns start of found range or -1 for failure in which case target is not moved. +fun position SearchInTarget=2197(position length, string text) # Set the search flags used by SearchInTarget. -set void SetSearchFlags=2198(int searchFlags,) +set void SetSearchFlags=2198(FindOption searchFlags,) # Get the search flags used by SearchInTarget. -get int GetSearchFlags=2199(,) +get FindOption GetSearchFlags=2199(,) # Show a call tip containing a definition near position pos. fun void CallTipShow=2200(position pos, string definition) @@ -1156,10 +1297,10 @@ fun bool CallTipActive=2202(,) fun position CallTipPosStart=2203(,) # Set the start position in order to change when backspacing removes the calltip. -set void CallTipSetPosStart=2214(int posStart,) +set void CallTipSetPosStart=2214(position posStart,) # Highlight a segment of the definition. -fun void CallTipSetHlt=2204(int highlightStart, int highlightEnd) +fun void CallTipSetHlt=2204(position highlightStart, position highlightEnd) # Set the background colour for the call tip. set void CallTipSetBack=2205(colour back,) @@ -1177,13 +1318,13 @@ set void CallTipUseStyle=2212(int tabSize,) set void CallTipSetPosition=2213(bool above,) # Find the display line of a document line taking hidden lines into account. -fun int VisibleFromDocLine=2220(int docLine,) +fun line VisibleFromDocLine=2220(line docLine,) # Find the document line of a display line taking hidden lines into account. -fun int DocLineFromVisible=2221(int displayLine,) +fun line DocLineFromVisible=2221(line displayLine,) # The number of display lines needed to wrap a document line -fun int WrapCount=2235(int docLine,) +fun line WrapCount=2235(line docLine,) enu FoldLevel=SC_FOLDLEVEL val SC_FOLDLEVELBASE=0x400 @@ -1191,43 +1332,47 @@ val SC_FOLDLEVELWHITEFLAG=0x1000 val SC_FOLDLEVELHEADERFLAG=0x2000 val SC_FOLDLEVELNUMBERMASK=0x0FFF +ali SC_FOLDLEVELWHITEFLAG=WHITE_FLAG +ali SC_FOLDLEVELHEADERFLAG=HEADER_FLAG +ali SC_FOLDLEVELNUMBERMASK=NUMBER_MASK + # Set the fold level of a line. # This encodes an integer level along with flags indicating whether the # line is a header and whether it is effectively white space. -set void SetFoldLevel=2222(int line, int level) +set void SetFoldLevel=2222(line line, FoldLevel level) # Retrieve the fold level of a line. -get int GetFoldLevel=2223(int line,) +get FoldLevel GetFoldLevel=2223(line line,) # Find the last child line of a header line. -get int GetLastChild=2224(int line, int level) +get line GetLastChild=2224(line line, FoldLevel level) # Find the parent line of a child line. -get int GetFoldParent=2225(int line,) +get line GetFoldParent=2225(line line,) # Make a range of lines visible. -fun void ShowLines=2226(int lineStart, int lineEnd) +fun void ShowLines=2226(line lineStart, line lineEnd) # Make a range of lines invisible. -fun void HideLines=2227(int lineStart, int lineEnd) +fun void HideLines=2227(line lineStart, line lineEnd) # Is a line visible? -get bool GetLineVisible=2228(int line,) +get bool GetLineVisible=2228(line line,) # Are all lines visible? get bool GetAllLinesVisible=2236(,) # Show the children of a header line. -set void SetFoldExpanded=2229(int line, bool expanded) +set void SetFoldExpanded=2229(line line, bool expanded) # Is a header line expanded? -get bool GetFoldExpanded=2230(int line,) +get bool GetFoldExpanded=2230(line line,) # Switch a header line between expanded and contracted. -fun void ToggleFold=2231(int line,) +fun void ToggleFold=2231(line line,) # Switch a header line between expanded and contracted and show some text after the line. -fun void ToggleFoldShowText=2700(int line, string text) +fun void ToggleFoldShowText=2700(line line, string text) enu FoldDisplayTextStyle=SC_FOLDDISPLAYTEXT_ val SC_FOLDDISPLAYTEXT_HIDDEN=0 @@ -1235,10 +1380,10 @@ val SC_FOLDDISPLAYTEXT_STANDARD=1 val SC_FOLDDISPLAYTEXT_BOXED=2 # Set the style of fold display text. -set void FoldDisplayTextSetStyle=2701(int style,) +set void FoldDisplayTextSetStyle=2701(FoldDisplayTextStyle style,) # Get the style of fold display text. -get int FoldDisplayTextGetStyle=2707(,) +get FoldDisplayTextStyle FoldDisplayTextGetStyle=2707(,) # Set the default fold display text. fun void SetDefaultFoldDisplayText=2722(, string text) @@ -1252,19 +1397,19 @@ val SC_FOLDACTION_EXPAND=1 val SC_FOLDACTION_TOGGLE=2 # Expand or contract a fold header. -fun void FoldLine=2237(int line, int action) +fun void FoldLine=2237(line line, FoldAction action) # Expand or contract a fold header and its children. -fun void FoldChildren=2238(int line, int action) +fun void FoldChildren=2238(line line, FoldAction action) # Expand a fold header and all children. Use the level argument instead of the line's current level. -fun void ExpandChildren=2239(int line, int level) +fun void ExpandChildren=2239(line line, FoldLevel level) # Expand or contract all fold headers. -fun void FoldAll=2662(int action,) +fun void FoldAll=2662(FoldAction action,) # Ensure a particular line is visible by expanding any header line hiding it. -fun void EnsureVisible=2232(int line,) +fun void EnsureVisible=2232(line line,) enu AutomaticFold=SC_AUTOMATICFOLD_ val SC_AUTOMATICFOLD_SHOW=0x0001 @@ -1272,10 +1417,10 @@ val SC_AUTOMATICFOLD_CLICK=0x0002 val SC_AUTOMATICFOLD_CHANGE=0x0004 # Set automatic folding behaviours. -set void SetAutomaticFold=2663(int automaticFold,) +set void SetAutomaticFold=2663(AutomaticFold automaticFold,) # Get automatic folding behaviours. -get int GetAutomaticFold=2664(,) +get AutomaticFold GetAutomaticFold=2664(,) enu FoldFlag=SC_FOLDFLAG_ val SC_FOLDFLAG_LINEBEFORE_EXPANDED=0x0002 @@ -1285,12 +1430,19 @@ val SC_FOLDFLAG_LINEAFTER_CONTRACTED=0x0010 val SC_FOLDFLAG_LEVELNUMBERS=0x0040 val SC_FOLDFLAG_LINESTATE=0x0080 +ali SC_FOLDFLAG_LINEBEFORE_EXPANDED=LINE_BEFORE_EXPANDED +ali SC_FOLDFLAG_LINEBEFORE_CONTRACTED=LINE_BEFORE_CONTRACTED +ali SC_FOLDFLAG_LINEAFTER_EXPANDED=LINE_AFTER_EXPANDED +ali SC_FOLDFLAG_LINEAFTER_CONTRACTED=LINE_AFTER_CONTRACTED +ali SC_FOLDFLAG_LEVELNUMBERS=LEVEL_NUMBERS +ali SC_FOLDFLAG_LINESTATE=LINE_STATE + # Set some style options for folding. -set void SetFoldFlags=2233(int flags,) +set void SetFoldFlags=2233(FoldFlag flags,) # Ensure a particular line is visible by expanding any header line hiding it. # Use the currently set visibility policy to determine which range to display. -fun void EnsureVisibleEnforcePolicy=2234(int line,) +fun void EnsureVisibleEnforcePolicy=2234(line line,) # Sets whether a tab pressed when caret is within indentation indents. set void SetTabIndents=2260(bool tabIndents,) @@ -1313,10 +1465,10 @@ set void SetMouseDwellTime=2264(int periodMilliseconds,) get int GetMouseDwellTime=2265(,) # Get position of start of word. -fun int WordStartPosition=2266(position pos, bool onlyWordCharacters) +fun position WordStartPosition=2266(position pos, bool onlyWordCharacters) # Get position of end of word. -fun int WordEndPosition=2267(position pos, bool onlyWordCharacters) +fun position WordEndPosition=2267(position pos, bool onlyWordCharacters) # Is the range start..end considered a word? fun bool IsRangeWord=2691(position start, position end) @@ -1327,11 +1479,14 @@ val SC_IDLESTYLING_TOVISIBLE=1 val SC_IDLESTYLING_AFTERVISIBLE=2 val SC_IDLESTYLING_ALL=3 +ali SC_IDLESTYLING_TOVISIBLE=TO_VISIBLE +ali SC_IDLESTYLING_AFTERVISIBLE=AFTER_VISIBLE + # Sets limits to idle styling. -set void SetIdleStyling=2692(int idleStyling,) +set void SetIdleStyling=2692(IdleStyling idleStyling,) # Retrieve the limits to idle styling. -get int GetIdleStyling=2693(,) +get IdleStyling GetIdleStyling=2693(,) enu Wrap=SC_WRAP_ val SC_WRAP_NONE=0 @@ -1339,11 +1494,13 @@ val SC_WRAP_WORD=1 val SC_WRAP_CHAR=2 val SC_WRAP_WHITESPACE=3 +ali SC_WRAP_WHITESPACE=WHITE_SPACE + # Sets whether text is word wrapped. -set void SetWrapMode=2268(int wrapMode,) +set void SetWrapMode=2268(Wrap wrapMode,) # Retrieve whether text is word wrapped. -get int GetWrapMode=2269(,) +get Wrap GetWrapMode=2269(,) enu WrapVisualFlag=SC_WRAPVISUALFLAG_ val SC_WRAPVISUALFLAG_NONE=0x0000 @@ -1352,10 +1509,10 @@ val SC_WRAPVISUALFLAG_START=0x0002 val SC_WRAPVISUALFLAG_MARGIN=0x0004 # Set the display mode of visual flags for wrapped lines. -set void SetWrapVisualFlags=2460(int wrapVisualFlags,) +set void SetWrapVisualFlags=2460(WrapVisualFlag wrapVisualFlags,) # Retrive the display mode of visual flags for wrapped lines. -get int GetWrapVisualFlags=2461(,) +get WrapVisualFlag GetWrapVisualFlags=2461(,) enu WrapVisualLocation=SC_WRAPVISUALFLAGLOC_ val SC_WRAPVISUALFLAGLOC_DEFAULT=0x0000 @@ -1363,10 +1520,10 @@ val SC_WRAPVISUALFLAGLOC_END_BY_TEXT=0x0001 val SC_WRAPVISUALFLAGLOC_START_BY_TEXT=0x0002 # Set the location of visual flags for wrapped lines. -set void SetWrapVisualFlagsLocation=2462(int wrapVisualFlagsLocation,) +set void SetWrapVisualFlagsLocation=2462(WrapVisualLocation wrapVisualFlagsLocation,) # Retrive the location of visual flags for wrapped lines. -get int GetWrapVisualFlagsLocation=2463(,) +get WrapVisualLocation GetWrapVisualFlagsLocation=2463(,) # Set the start indent for wrapped lines. set void SetWrapStartIndent=2464(int indent,) @@ -1380,11 +1537,13 @@ val SC_WRAPINDENT_SAME=1 val SC_WRAPINDENT_INDENT=2 val SC_WRAPINDENT_DEEPINDENT=3 +ali SC_WRAPINDENT_DEEPINDENT=DEEP_INDENT + # Sets how wrapped sublines are placed. Default is fixed. -set void SetWrapIndentMode=2472(int wrapIndentMode,) +set void SetWrapIndentMode=2472(WrapIndentMode wrapIndentMode,) # Retrieve how wrapped sublines are placed. Default is fixed. -get int GetWrapIndentMode=2473(,) +get WrapIndentMode GetWrapIndentMode=2473(,) enu LineCache=SC_CACHE_ val SC_CACHE_NONE=0 @@ -1393,10 +1552,10 @@ val SC_CACHE_PAGE=2 val SC_CACHE_DOCUMENT=3 # Sets the degree of caching of layout information. -set void SetLayoutCache=2272(int cacheMode,) +set void SetLayoutCache=2272(LineCache cacheMode,) # Retrieve the degree of caching of layout information. -get int GetLayoutCache=2273(,) +get LineCache GetLayoutCache=2273(,) # Sets the document width assumed for scrolling. set void SetScrollWidth=2274(int pixelWidth,) @@ -1425,7 +1584,7 @@ set void SetEndAtLastLine=2277(bool endAtLastLine,) get bool GetEndAtLastLine=2278(,) # Retrieve the height of a particular line of text in pixels. -fun int TextHeight=2279(int line,) +fun int TextHeight=2279(line line,) # Show or hide the vertical scroll bar. set void SetVScrollBar=2280(bool visible,) @@ -1434,7 +1593,7 @@ set void SetVScrollBar=2280(bool visible,) get bool GetVScrollBar=2281(,) # Append a string to the end of the document without changing the selection. -fun void AppendText=2282(int length, string text) +fun void AppendText=2282(position length, string text) # Is drawing done in two phases with backgrounds drawn before foregrounds? get bool GetTwoPhaseDraw=2283(,) @@ -1449,13 +1608,13 @@ val SC_PHASES_TWO=1 val SC_PHASES_MULTIPLE=2 # How many phases is drawing done in? -get int GetPhasesDraw=2673(,) +get PhasesDraw GetPhasesDraw=2673(,) # In one phase draw, text is drawn in a series of rectangular blocks with no overlap. # In two phase draw, text is drawn in a series of lines allowing runs to overlap horizontally. # In multiple phase draw, each element is drawn over the whole drawing area, allowing text # to overlap from one line to the next. -set void SetPhasesDraw=2674(int phases,) +set void SetPhasesDraw=2674(PhasesDraw phases,) # Control font anti-aliasing. @@ -1467,23 +1626,23 @@ val SC_EFF_QUALITY_ANTIALIASED=2 val SC_EFF_QUALITY_LCD_OPTIMIZED=3 # Choose the quality level for text from the FontQuality enumeration. -set void SetFontQuality=2611(int fontQuality,) +set void SetFontQuality=2611(FontQuality fontQuality,) # Retrieve the quality level for text. -get int GetFontQuality=2612(,) +get FontQuality GetFontQuality=2612(,) # Scroll so that a display line is at the top of the display. -set void SetFirstVisibleLine=2613(int displayLine,) +set void SetFirstVisibleLine=2613(line displayLine,) enu MultiPaste=SC_MULTIPASTE_ val SC_MULTIPASTE_ONCE=0 val SC_MULTIPASTE_EACH=1 # Change the effect of pasting when there are multiple selections. -set void SetMultiPaste=2614(int multiPaste,) +set void SetMultiPaste=2614(MultiPaste multiPaste,) # Retrieve the effect of pasting when there are multiple selections. -get int GetMultiPaste=2615(,) +get MultiPaste GetMultiPaste=2615(,) # Retrieve the value of a tag from a regular expression search. # Result is NUL-terminated. @@ -1506,10 +1665,10 @@ val SC_ACCESSIBILITY_DISABLED=0 val SC_ACCESSIBILITY_ENABLED=1 # Enable or disable accessibility. -set void SetAccessibility=2702(int accessibility,) +set void SetAccessibility=2702(Accessibility accessibility,) # Report accessibility status. -get int GetAccessibility=2703(,) +get Accessibility GetAccessibility=2703(,) ## New messages go here @@ -1706,7 +1865,7 @@ fun void LineCopy=2455(,) fun void MoveCaretInsideView=2401(,) # How many characters are on a line, including end of line characters? -fun int LineLength=2350(int line,) +fun position LineLength=2350(line line,) # Highlight the characters at two positions. fun void BraceHighlight=2351(position posA, position posB) @@ -1724,6 +1883,9 @@ fun void BraceBadLightIndicator=2499(bool useSetting, int indicator) # The maxReStyle must be 0 for now. It may be defined in a future release. fun position BraceMatch=2353(position pos, int maxReStyle) +# Similar to BraceMatch, but matching starts at the explicit start position. +fun position BraceMatchNext=2369(position pos, position startPos) + # Are the end of line characters visible? get bool GetViewEOL=2355(,) @@ -1731,13 +1893,13 @@ get bool GetViewEOL=2355(,) set void SetViewEOL=2356(bool visible,) # Retrieve a pointer to the document object. -get int GetDocPointer=2357(,) +get pointer GetDocPointer=2357(,) # Change the document object used. -set void SetDocPointer=2358(, int doc) +set void SetDocPointer=2358(, pointer doc) # Set which document modification events are sent to the container. -set void SetModEventMask=2359(int eventMask,) +set void SetModEventMask=2359(ModificationFlags eventMask,) enu EdgeVisualStyle=EDGE_ val EDGE_NONE=0 @@ -1745,19 +1907,21 @@ val EDGE_LINE=1 val EDGE_BACKGROUND=2 val EDGE_MULTILINE=3 +ali EDGE_MULTILINE=MULTI_LINE + # Retrieve the column number which text should be kept within. -get int GetEdgeColumn=2360(,) +get position GetEdgeColumn=2360(,) # Set the column number of the edge. # If text goes past the edge then it is highlighted. -set void SetEdgeColumn=2361(int column,) +set void SetEdgeColumn=2361(position column,) # Retrieve the edge highlight mode. -get int GetEdgeMode=2362(,) +get EdgeVisualStyle GetEdgeMode=2362(,) # The edge may be displayed by a line (EDGE_LINE/EDGE_MULTILINE) or by highlighting text that # goes beyond it (EDGE_BACKGROUND) or not displayed at all (EDGE_NONE). -set void SetEdgeMode=2363(int edgeMode,) +set void SetEdgeMode=2363(EdgeVisualStyle edgeMode,) # Retrieve the colour used in edge indication. get colour GetEdgeColour=2364(,) @@ -1766,24 +1930,27 @@ get colour GetEdgeColour=2364(,) set void SetEdgeColour=2365(colour edgeColour,) # Add a new vertical edge to the view. -fun void MultiEdgeAddLine=2694(int column, colour edgeColour) +fun void MultiEdgeAddLine=2694(position column, colour edgeColour) # Clear all vertical edges. fun void MultiEdgeClearAll=2695(,) +# Get multi edge positions. +get position GetMultiEdgeColumn=2749(int which,) + # Sets the current caret position to be the search anchor. fun void SearchAnchor=2366(,) # Find some text starting at the search anchor. # Does not ensure the selection is visible. -fun int SearchNext=2367(int searchFlags, string text) +fun position SearchNext=2367(FindOption searchFlags, string text) # Find some text starting at the search anchor and moving backwards. # Does not ensure the selection is visible. -fun int SearchPrev=2368(int searchFlags, string text) +fun position SearchPrev=2368(FindOption searchFlags, string text) # Retrieves the number of lines completely visible. -get int LinesOnScreen=2370(,) +get line LinesOnScreen=2370(,) enu PopUp=SC_POPUP_ val SC_POPUP_NEVER=0 @@ -1792,7 +1959,7 @@ val SC_POPUP_TEXT=2 # Set whether a pop up menu is displayed automatically when the user presses # the wrong mouse button on certain areas. -fun void UsePopUp=2371(int popUpMode,) +fun void UsePopUp=2371(PopUp popUpMode,) # Is the selection rectangular? The alternative is the more common stream selection. get bool SelectionIsRectangle=2372(,) @@ -1810,17 +1977,17 @@ val SC_DOCUMENTOPTION_TEXT_LARGE=0x100 # Create a new document object. # Starts with reference count of 1 and not selected into editor. -fun int CreateDocument=2375(int bytes, int documentOptions) +fun pointer CreateDocument=2375(position bytes, DocumentOption documentOptions) # Extend life of document. -fun void AddRefDocument=2376(, int doc) +fun void AddRefDocument=2376(, pointer doc) # Release a reference to the document, deleting document if it fades to black. -fun void ReleaseDocument=2377(, int doc) +fun void ReleaseDocument=2377(, pointer doc) # Get which document options are set. -get int GetDocumentOptions=2379(,) +get DocumentOption GetDocumentOptions=2379(,) # Get which document modification events are sent to the container. -get int GetModEventMask=2378(,) +get ModificationFlags GetModEventMask=2378(,) # Set whether command events are sent to the container. set void SetCommandEvents=2717(bool commandEvents,) @@ -1840,10 +2007,13 @@ val SC_STATUS_BADALLOC=2 val SC_STATUS_WARN_START=1000 val SC_STATUS_WARN_REGEX=1001 +ali SC_STATUS_BADALLOC=BAD_ALLOC +ali SC_STATUS_WARN_REGEX=REG_EX + # Change error status - 0 = OK. -set void SetStatus=2382(int status,) +set void SetStatus=2382(Status status,) # Get error status. -get int GetStatus=2383(,) +get Status GetStatus=2383(,) # Set whether the mouse is captured when its button is pressed. set void SetMouseDownCaptures=2384(bool captures,) @@ -1855,15 +2025,10 @@ set void SetMouseWheelCaptures=2696(bool captures,) # Get whether mouse wheel can be active outside the window. get bool GetMouseWheelCaptures=2697(,) -enu CursorShape=SC_CURSOR -val SC_CURSORNORMAL=-1 -val SC_CURSORARROW=2 -val SC_CURSORWAIT=4 -val SC_CURSORREVERSEARROW=7 # Sets the cursor to one of the SC_CURSOR* values. -set void SetCursor=2386(int cursorType,) +set void SetCursor=2386(CursorShape cursorType,) # Get cursor type. -get int GetCursor=2387(,) +get CursorShape GetCursor=2387(,) # Change the way control characters are displayed: # If symbol is < 32, keep the drawn way, else, use the given character. @@ -1886,9 +2051,10 @@ fun void WordPartRightExtend=2393(,) enu VisiblePolicy=VISIBLE_ val VISIBLE_SLOP=0x01 val VISIBLE_STRICT=0x04 + # Set the way the display area is determined when a particular line # is to be moved to by Find, FindNext, GotoLine, etc. -fun void SetVisiblePolicy=2394(int visiblePolicy, int visibleSlop) +fun void SetVisiblePolicy=2394(VisiblePolicy visiblePolicy, int visibleSlop) # Delete back from the current position to the start of the line. fun void DelLineLeft=2395(,) @@ -1934,17 +2100,17 @@ val CARET_EVEN=0x08 # Set the way the caret is kept visible when going sideways. # The exclusion zone is given in pixels. -fun void SetXCaretPolicy=2402(int caretPolicy, int caretSlop) +fun void SetXCaretPolicy=2402(CaretPolicy caretPolicy, int caretSlop) # Set the way the line the caret is on is kept visible. # The exclusion zone is given in lines. -fun void SetYCaretPolicy=2403(int caretPolicy, int caretSlop) +fun void SetYCaretPolicy=2403(CaretPolicy caretPolicy, int caretSlop) # Set printing to line wrapped (SC_WRAP_WORD) or not line wrapped (SC_WRAP_NONE). -set void SetPrintWrapMode=2406(int wrapMode,) +set void SetPrintWrapMode=2406(Wrap wrapMode,) # Is printing line wrapped? -get int GetPrintWrapMode=2407(,) +get Wrap GetPrintWrapMode=2407(,) # Set a fore colour for active hotspots. set void SetHotspotActiveFore=2410(bool useSetting, colour fore) @@ -1972,10 +2138,13 @@ get bool GetHotspotSingleLine=2497(,) # Move caret down one paragraph (delimited by empty lines). fun void ParaDown=2413(,) + # Extend selection down one paragraph (delimited by empty lines). fun void ParaDownExtend=2414(,) + # Move caret up one paragraph (delimited by empty lines). fun void ParaUp=2415(,) + # Extend selection up one paragraph (delimited by empty lines). fun void ParaUpExtend=2416(,) @@ -1989,18 +2158,18 @@ fun position PositionAfter=2418(position pos,) # Given a valid document position, return a position that differs in a number # of characters. Returned value is always between 0 and last position in document. -fun position PositionRelative=2670(position pos, int relative) +fun position PositionRelative=2670(position pos, position relative) # Given a valid document position, return a position that differs in a number # of UTF-16 code units. Returned value is always between 0 and last position in document. # The result may point half way (2 bytes) inside a non-BMP character. -fun position PositionRelativeCodeUnits=2716(position pos, int relative) +fun position PositionRelativeCodeUnits=2716(position pos, position relative) # Copy a range of text to the clipboard. Positions are clipped into the document. fun void CopyRange=2419(position start, position end) # Copy argument text to the clipboard. -fun void CopyText=2420(int length, string text) +fun void CopyText=2420(position length, string text) enu SelectionMode=SC_SEL_ val SC_SEL_STREAM=0 @@ -2010,19 +2179,19 @@ val SC_SEL_THIN=3 # Set the selection mode to stream (SC_SEL_STREAM) or rectangular (SC_SEL_RECTANGLE/SC_SEL_THIN) or # by lines (SC_SEL_LINES). -set void SetSelectionMode=2422(int selectionMode,) +set void SetSelectionMode=2422(SelectionMode selectionMode,) # Get the mode of the current selection. -get int GetSelectionMode=2423(,) +get SelectionMode GetSelectionMode=2423(,) # Get whether or not regular caret moves will extend or reduce the selection. get bool GetMoveExtendsSelection=2706(,) # Retrieve the position of the start of the selection at the given line (INVALID_POSITION if no selection on this line). -fun position GetLineSelStartPosition=2424(int line,) +fun position GetLineSelStartPosition=2424(line line,) # Retrieve the position of the end of the selection at the given line (INVALID_POSITION if no selection on this line). -fun position GetLineSelEndPosition=2425(int line,) +fun position GetLineSelEndPosition=2425(line line,) ## RectExtended rectangular selection moves # Move caret down one line, extending rectangular selection to new caret position. @@ -2109,64 +2278,72 @@ enu CaseInsensitiveBehaviour=SC_CASEINSENSITIVEBEHAVIOUR_ val SC_CASEINSENSITIVEBEHAVIOUR_RESPECTCASE=0 val SC_CASEINSENSITIVEBEHAVIOUR_IGNORECASE=1 +ali SC_CASEINSENSITIVEBEHAVIOUR_RESPECTCASE=RESPECT_CASE +ali SC_CASEINSENSITIVEBEHAVIOUR_IGNORECASE=IGNORE_CASE + # Set auto-completion case insensitive behaviour to either prefer case-sensitive matches or have no preference. -set void AutoCSetCaseInsensitiveBehaviour=2634(int behaviour,) +set void AutoCSetCaseInsensitiveBehaviour=2634(CaseInsensitiveBehaviour behaviour,) # Get auto-completion case insensitive behaviour. -get int AutoCGetCaseInsensitiveBehaviour=2635(,) +get CaseInsensitiveBehaviour AutoCGetCaseInsensitiveBehaviour=2635(,) enu MultiAutoComplete=SC_MULTIAUTOC_ val SC_MULTIAUTOC_ONCE=0 val SC_MULTIAUTOC_EACH=1 # Change the effect of autocompleting when there are multiple selections. -set void AutoCSetMulti=2636(int multi,) +set void AutoCSetMulti=2636(MultiAutoComplete multi,) # Retrieve the effect of autocompleting when there are multiple selections. -get int AutoCGetMulti=2637(,) +get MultiAutoComplete AutoCGetMulti=2637(,) enu Ordering=SC_ORDER_ val SC_ORDER_PRESORTED=0 val SC_ORDER_PERFORMSORT=1 val SC_ORDER_CUSTOM=2 +ali SC_ORDER_PRESORTED=PRE_SORTED +ali SC_ORDER_PERFORMSORT=PERFORM_SORT + # Set the way autocompletion lists are ordered. -set void AutoCSetOrder=2660(int order,) +set void AutoCSetOrder=2660(Ordering order,) # Get the way autocompletion lists are ordered. -get int AutoCGetOrder=2661(,) +get Ordering AutoCGetOrder=2661(,) # Enlarge the document to a particular size of text bytes. -fun void Allocate=2446(int bytes,) +fun void Allocate=2446(position bytes,) # Returns the target converted to UTF8. # Return the length in bytes. -fun int TargetAsUTF8=2447(, stringresult s) +fun position TargetAsUTF8=2447(, stringresult s) # Set the length of the utf8 argument for calling EncodedFromUTF8. # Set to -1 and the string will be measured to the first nul. -fun void SetLengthForEncode=2448(int bytes,) +fun void SetLengthForEncode=2448(position bytes,) # Translates a UTF8 string into the document encoding. # Return the length of the result in bytes. # On error return 0. -fun int EncodedFromUTF8=2449(string utf8, stringresult encoded) +fun position EncodedFromUTF8=2449(string utf8, stringresult encoded) # Find the position of a column on a line taking into account tabs and # multi-byte characters. If beyond end of line, return line end position. -fun int FindColumn=2456(int line, int column) - -# Can the caret preferred x position only be changed by explicit movement commands? -get int GetCaretSticky=2457(,) - -# Stop the caret preferred x position changing when the user types. -set void SetCaretSticky=2458(int useCaretStickyBehaviour,) +fun position FindColumn=2456(line line, position column) enu CaretSticky=SC_CARETSTICKY_ val SC_CARETSTICKY_OFF=0 val SC_CARETSTICKY_ON=1 val SC_CARETSTICKY_WHITESPACE=2 +ali SC_CARETSTICKY_WHITESPACE=WHITE_SPACE + +# Can the caret preferred x position only be changed by explicit movement commands? +get CaretSticky GetCaretSticky=2457(,) + +# Stop the caret preferred x position changing when the user types. +set void SetCaretSticky=2458(CaretSticky useCaretStickyBehaviour,) + # Switch between sticky and non-sticky: meant to be bound to a key. fun void ToggleCaretSticky=2459(,) @@ -2179,30 +2356,26 @@ get bool GetPasteConvertEndings=2468(,) # Duplicate the selection. If selection empty duplicate the line containing the caret. fun void SelectionDuplicate=2469(,) -enu Alpha=SC_ALPHA_ -val SC_ALPHA_TRANSPARENT=0 -val SC_ALPHA_OPAQUE=255 -val SC_ALPHA_NOALPHA=256 - # Set background alpha of the caret line. -set void SetCaretLineBackAlpha=2470(int alpha,) +set void SetCaretLineBackAlpha=2470(Alpha alpha,) # Get the background alpha of the caret line. -get int GetCaretLineBackAlpha=2471(,) +get Alpha GetCaretLineBackAlpha=2471(,) enu CaretStyle=CARETSTYLE_ val CARETSTYLE_INVISIBLE=0 val CARETSTYLE_LINE=1 val CARETSTYLE_BLOCK=2 val CARETSTYLE_OVERSTRIKE_BAR=0 -val CARETSTYLE_OVERSTRIKE_BLOCK=16 +val CARETSTYLE_OVERSTRIKE_BLOCK=0x10 val CARETSTYLE_INS_MASK=0xF +val CARETSTYLE_BLOCK_AFTER=0x100 # Set the style of the caret to be drawn. -set void SetCaretStyle=2512(int caretStyle,) +set void SetCaretStyle=2512(CaretStyle caretStyle,) # Returns the current style of the caret. -get int GetCaretStyle=2513(,) +get CaretStyle GetCaretStyle=2513(,) # Set the indicator used for IndicatorFillRange and IndicatorClearRange set void SetIndicatorCurrent=2500(int indicator,) @@ -2217,10 +2390,10 @@ set void SetIndicatorValue=2502(int value,) get int GetIndicatorValue=2503(,) # Turn a indicator on over a range. -fun void IndicatorFillRange=2504(position start, int lengthFill) +fun void IndicatorFillRange=2504(position start, position lengthFill) # Turn a indicator off over a range. -fun void IndicatorClearRange=2505(position start, int lengthClear) +fun void IndicatorClearRange=2505(position start, position lengthClear) # Are any indicators present at pos? fun int IndicatorAllOnFor=2506(position pos,) @@ -2229,10 +2402,10 @@ fun int IndicatorAllOnFor=2506(position pos,) fun int IndicatorValueAt=2507(int indicator, position pos) # Where does a particular indicator start? -fun int IndicatorStart=2508(int indicator, position pos) +fun position IndicatorStart=2508(int indicator, position pos) # Where does a particular indicator end? -fun int IndicatorEnd=2509(int indicator, position pos) +fun position IndicatorEnd=2509(int indicator, position pos) # Set number of entries in position cache set void SetPositionCache=2514(int size,) @@ -2245,28 +2418,28 @@ fun void CopyAllowLine=2519(,) # Compact the document buffer and return a read-only pointer to the # characters in the document. -get int GetCharacterPointer=2520(,) +get pointer GetCharacterPointer=2520(,) # Return a read-only pointer to a range of characters in the document. # May move the gap so that the range is contiguous, but will only move up # to lengthRange bytes. -get int GetRangePointer=2643(position start, int lengthRange) +get pointer GetRangePointer=2643(position start, position lengthRange) # Return a position which, to avoid performance costs, should not be within # the range of a call to GetRangePointer. get position GetGapPosition=2644(,) # Set the alpha fill colour of the given indicator. -set void IndicSetAlpha=2523(int indicator, int alpha) +set void IndicSetAlpha=2523(int indicator, Alpha alpha) # Get the alpha fill colour of the given indicator. -get int IndicGetAlpha=2524(int indicator,) +get Alpha IndicGetAlpha=2524(int indicator,) # Set the alpha outline colour of the given indicator. -set void IndicSetOutlineAlpha=2558(int indicator, int alpha) +set void IndicSetOutlineAlpha=2558(int indicator, Alpha alpha) # Get the alpha outline colour of the given indicator. -get int IndicGetOutlineAlpha=2559(int indicator,) +get Alpha IndicGetOutlineAlpha=2559(int indicator,) # Set extra ascent for each line set void SetExtraAscent=2525(int extraAscent,) @@ -2284,22 +2457,22 @@ get int GetExtraDescent=2528(,) fun int MarkerSymbolDefined=2529(int markerNumber,) # Set the text in the text margin for a line -set void MarginSetText=2530(int line, string text) +set void MarginSetText=2530(line line, string text) # Get the text in the text margin for a line -get int MarginGetText=2531(int line, stringresult text) +get int MarginGetText=2531(line line, stringresult text) # Set the style number for the text margin for a line -set void MarginSetStyle=2532(int line, int style) +set void MarginSetStyle=2532(line line, int style) # Get the style number for the text margin for a line -get int MarginGetStyle=2533(int line,) +get int MarginGetStyle=2533(line line,) # Set the style in the text margin for a line -set void MarginSetStyles=2534(int line, string styles) +set void MarginSetStyles=2534(line line, string styles) # Get the styles in the text margin for a line -get int MarginGetStyles=2535(int line, stringresult styles) +get int MarginGetStyles=2535(line line, stringresult styles) # Clear the margin text on all lines fun void MarginTextClearAll=2536(,) @@ -2314,32 +2487,34 @@ enu MarginOption=SC_MARGINOPTION_ val SC_MARGINOPTION_NONE=0 val SC_MARGINOPTION_SUBLINESELECT=1 +ali SC_MARGINOPTION_SUBLINESELECT=SUB_LINE_SELECT + # Set the margin options. -set void SetMarginOptions=2539(int marginOptions,) +set void SetMarginOptions=2539(MarginOption marginOptions,) # Get the margin options. -get int GetMarginOptions=2557(,) +get MarginOption GetMarginOptions=2557(,) # Set the annotation text for a line -set void AnnotationSetText=2540(int line, string text) +set void AnnotationSetText=2540(line line, string text) # Get the annotation text for a line -get int AnnotationGetText=2541(int line, stringresult text) +get int AnnotationGetText=2541(line line, stringresult text) # Set the style number for the annotations for a line -set void AnnotationSetStyle=2542(int line, int style) +set void AnnotationSetStyle=2542(line line, int style) # Get the style number for the annotations for a line -get int AnnotationGetStyle=2543(int line,) +get int AnnotationGetStyle=2543(line line,) # Set the annotation styles for a line -set void AnnotationSetStyles=2544(int line, string styles) +set void AnnotationSetStyles=2544(line line, string styles) # Get the annotation styles for a line -get int AnnotationGetStyles=2545(int line, stringresult styles) +get int AnnotationGetStyles=2545(line line, stringresult styles) # Get the number of annotation lines for a line -get int AnnotationGetLines=2546(int line,) +get int AnnotationGetLines=2546(line line,) # Clear the annotations from all lines fun void AnnotationClearAll=2547(,) @@ -2351,10 +2526,10 @@ val ANNOTATION_BOXED=2 val ANNOTATION_INDENTED=3 # Set the visibility for the annotations for a view -set void AnnotationSetVisible=2548(int visible,) +set void AnnotationSetVisible=2548(AnnotationVisible visible,) # Get the visibility for the annotations for a view -get int AnnotationGetVisible=2549(,) +get AnnotationVisible AnnotationGetVisible=2549(,) # Get the start of the range of style numbers used for annotations set void AnnotationSetStyleOffset=2550(int style,) @@ -2368,10 +2543,12 @@ fun void ReleaseAllExtendedStyles=2552(,) # Allocate some extended (>255) style numbers and return the start of the range fun int AllocateExtendedStyles=2553(int numberStyles,) +enu UndoFlags=UNDO_ +val UNDO_NONE=0 val UNDO_MAY_COALESCE=1 # Add a container action to the undo stack -fun void AddUndoAction=2560(int token, int flags) +fun void AddUndoAction=2560(int token, UndoFlags flags) # Find the position of a character from a point within the window. fun position CharPositionFromPoint=2561(int x, int y) @@ -2436,20 +2613,27 @@ get int GetMainSelection=2575(,) # Set the caret position of the nth selection. set void SetSelectionNCaret=2576(int selection, position caret) + # Return the caret position of the nth selection. get position GetSelectionNCaret=2577(int selection,) + # Set the anchor position of the nth selection. set void SetSelectionNAnchor=2578(int selection, position anchor) + # Return the anchor position of the nth selection. get position GetSelectionNAnchor=2579(int selection,) + # Set the virtual space of the caret of the nth selection. -set void SetSelectionNCaretVirtualSpace=2580(int selection, int space) +set void SetSelectionNCaretVirtualSpace=2580(int selection, position space) + # Return the virtual space of the caret of the nth selection. -get int GetSelectionNCaretVirtualSpace=2581(int selection,) +get position GetSelectionNCaretVirtualSpace=2581(int selection,) + # Set the virtual space of the anchor of the nth selection. -set void SetSelectionNAnchorVirtualSpace=2582(int selection, int space) +set void SetSelectionNAnchorVirtualSpace=2582(int selection, position space) + # Return the virtual space of the anchor of the nth selection. -get int GetSelectionNAnchorVirtualSpace=2583(int selection,) +get position GetSelectionNAnchorVirtualSpace=2583(int selection,) # Sets the position that starts the selection - this becomes the anchor. set void SetSelectionNStart=2584(int selection, position anchor) @@ -2457,28 +2641,41 @@ set void SetSelectionNStart=2584(int selection, position anchor) # Returns the position at the start of the selection. get position GetSelectionNStart=2585(int selection,) +# Returns the virtual space at the start of the selection. +get position GetSelectionNStartVirtualSpace=2726(int selection,) + # Sets the position that ends the selection - this becomes the currentPosition. set void SetSelectionNEnd=2586(int selection, position caret) +# Returns the virtual space at the end of the selection. +get position GetSelectionNEndVirtualSpace=2727(int selection,) + # Returns the position at the end of the selection. get position GetSelectionNEnd=2587(int selection,) # Set the caret position of the rectangular selection. set void SetRectangularSelectionCaret=2588(position caret,) + # Return the caret position of the rectangular selection. get position GetRectangularSelectionCaret=2589(,) + # Set the anchor position of the rectangular selection. set void SetRectangularSelectionAnchor=2590(position anchor,) + # Return the anchor position of the rectangular selection. get position GetRectangularSelectionAnchor=2591(,) + # Set the virtual space of the caret of the rectangular selection. -set void SetRectangularSelectionCaretVirtualSpace=2592(int space,) +set void SetRectangularSelectionCaretVirtualSpace=2592(position space,) + # Return the virtual space of the caret of the rectangular selection. -get int GetRectangularSelectionCaretVirtualSpace=2593(,) +get position GetRectangularSelectionCaretVirtualSpace=2593(,) + # Set the virtual space of the anchor of the rectangular selection. -set void SetRectangularSelectionAnchorVirtualSpace=2594(int space,) +set void SetRectangularSelectionAnchorVirtualSpace=2594(position space,) + # Return the virtual space of the anchor of the rectangular selection. -get int GetRectangularSelectionAnchorVirtualSpace=2595(,) +get position GetRectangularSelectionAnchorVirtualSpace=2595(,) enu VirtualSpace=SCVS_ val SCVS_NONE=0 @@ -2486,12 +2683,17 @@ val SCVS_RECTANGULARSELECTION=1 val SCVS_USERACCESSIBLE=2 val SCVS_NOWRAPLINESTART=4 +ali SCVS_RECTANGULARSELECTION=RECTANGULAR_SELECTION +ali SCVS_USERACCESSIBLE=USER_ACCESSIBLE +ali SCVS_NOWRAPLINESTART=NO_WRAP_LINE_START + # Set options for virtual space behaviour. -set void SetVirtualSpaceOptions=2596(int virtualSpaceOptions,) +set void SetVirtualSpaceOptions=2596(VirtualSpace virtualSpaceOptions,) + # Return options for virtual space behaviour. -get int GetVirtualSpaceOptions=2597(,) +get VirtualSpace GetVirtualSpaceOptions=2597(,) -# On GTK+, allow selecting the modifier key to use for mouse-based +# On GTK, allow selecting the modifier key to use for mouse-based # rectangular selection. Often the window manager requires Alt+Mouse Drag # for moving windows. # Valid values are SCMOD_CTRL(default), SCMOD_ALT, or SCMOD_SUPER. @@ -2510,10 +2712,10 @@ set void SetAdditionalSelFore=2600(colour fore,) set void SetAdditionalSelBack=2601(colour back,) # Set the alpha of the selection. -set void SetAdditionalSelAlpha=2602(int alpha,) +set void SetAdditionalSelAlpha=2602(Alpha alpha,) # Get the alpha of the selection. -get int GetAdditionalSelAlpha=2603(,) +get Alpha GetAdditionalSelAlpha=2603(,) # Set the foreground colour of additional carets. set void SetAdditionalCaretFore=2604(colour fore,) @@ -2541,7 +2743,7 @@ fun int ChangeLexerState=2617(position start, position end) # Find the next line at or after lineStart that is a contracted fold header line. # Return -1 when no more lines. -fun int ContractedFoldNext=2618(int lineStart,) +fun line ContractedFoldNext=2618(line lineStart,) # Centre current line in window. fun void VerticalCentreCaret=2619(,) @@ -2587,14 +2789,18 @@ val SC_TECHNOLOGY_DIRECTWRITE=1 val SC_TECHNOLOGY_DIRECTWRITERETAIN=2 val SC_TECHNOLOGY_DIRECTWRITEDC=3 +ali SC_TECHNOLOGY_DIRECTWRITE=DIRECT_WRITE +ali SC_TECHNOLOGY_DIRECTWRITERETAIN=DIRECT_WRITE_RETAIN +ali SC_TECHNOLOGY_DIRECTWRITEDC=DIRECT_WRITE_D_C + # Set the technology used. -set void SetTechnology=2630(int technology,) +set void SetTechnology=2630(Technology technology,) # Get the tech. -get int GetTechnology=2631(,) +get Technology GetTechnology=2631(,) # Create an ILoader*. -fun int CreateLoader=2632(int bytes, int documentOptions) +fun pointer CreateLoader=2632(position bytes, DocumentOption documentOptions) # On OS X, show a find indicator. fun void FindIndicatorShow=2640(position start, position end) @@ -2626,13 +2832,13 @@ val SC_LINE_END_TYPE_DEFAULT=0 val SC_LINE_END_TYPE_UNICODE=1 # Set the line end types that the application wants to use. May not be used if incompatible with lexer or encoding. -set void SetLineEndTypesAllowed=2656(int lineEndBitSet,) +set void SetLineEndTypesAllowed=2656(LineEndType lineEndBitSet,) # Get the line end types currently allowed. -get int GetLineEndTypesAllowed=2657(,) +get LineEndType GetLineEndTypesAllowed=2657(,) # Get the line end types currently recognised. May be a subset of the allowed types due to lexer limitation. -get int GetLineEndTypesActive=2658(,) +get LineEndType GetLineEndTypesActive=2658(,) # Set the way a character is drawn. set void SetRepresentation=2665(string encodedCharacter, string representation) @@ -2644,6 +2850,38 @@ get int GetRepresentation=2666(string encodedCharacter, stringresult representat # Remove a character representation. fun void ClearRepresentation=2667(string encodedCharacter,) +# Set the end of line annotation text for a line +set void EOLAnnotationSetText=2740(line line, string text) + +# Get the end of line annotation text for a line +get int EOLAnnotationGetText=2741(line line, stringresult text) + +# Set the style number for the end of line annotations for a line +set void EOLAnnotationSetStyle=2742(line line, int style) + +# Get the style number for the end of line annotations for a line +get int EOLAnnotationGetStyle=2743(line line,) + +# Clear the end of annotations from all lines +fun void EOLAnnotationClearAll=2744(,) + +enu EOLAnnotationVisible=EOLANNOTATION_ +val EOLANNOTATION_HIDDEN=0 +val EOLANNOTATION_STANDARD=1 +val EOLANNOTATION_BOXED=2 + +# Set the visibility for the end of line annotations for a view +set void EOLAnnotationSetVisible=2745(EOLAnnotationVisible visible,) + +# Get the visibility for the end of line annotations for a view +get EOLAnnotationVisible EOLAnnotationGetVisible=2746(,) + +# Get the start of the range of style numbers used for end of line annotations +set void EOLAnnotationSetStyleOffset=2747(int style,) + +# Get the start of the range of style numbers used for end of line annotations +get int EOLAnnotationGetStyleOffset=2748(,) + # Start notifying the container of all key presses and commands. fun void StartRecord=3001(,) @@ -2693,7 +2931,7 @@ get int GetPropertyInt=4010(string key, int defaultValue) get int GetLexerLanguage=4012(, stringresult language) # For private communication between an application and a known lexer. -fun int PrivateLexerCall=4013(int operation, int pointer) +fun pointer PrivateLexerCall=4013(int operation, pointer pointer) # Retrieve a '\n' separated list of properties understood by the current lexer. # Result is NUL-terminated. @@ -2705,7 +2943,7 @@ val SC_TYPE_INTEGER=1 val SC_TYPE_STRING=2 # Retrieve the type of a property. -fun int PropertyType=4015(string name,) +fun TypeProperty PropertyType=4015(string name,) # Describe a property. # Result is NUL-terminated. @@ -2768,6 +3006,7 @@ fun int DescriptionOfStyle=4032(int style, stringresult description) # These are defined as a bit mask to make it easy to specify which notifications are wanted. # One bit is set from each of SC_MOD_* and SC_PERFORMED_*. enu ModificationFlags=SC_MOD_ SC_PERFORMED_ SC_MULTISTEPUNDOREDO SC_LASTSTEPINUNDOREDO SC_MULTILINEUNDOREDO SC_STARTACTION SC_MODEVENTMASKALL +val SC_MOD_NONE=0x0 val SC_MOD_INSERTTEXT=0x1 val SC_MOD_DELETETEXT=0x2 val SC_MOD_CHANGESTYLE=0x4 @@ -2790,7 +3029,29 @@ val SC_MOD_CONTAINER=0x40000 val SC_MOD_LEXERSTATE=0x80000 val SC_MOD_INSERTCHECK=0x100000 val SC_MOD_CHANGETABSTOPS=0x200000 -val SC_MODEVENTMASKALL=0x3FFFFF +val SC_MOD_CHANGEEOLANNOTATION=0x400000 +val SC_MODEVENTMASKALL=0x7FFFFF + +ali SC_MOD_INSERTTEXT=INSERT_TEXT +ali SC_MOD_DELETETEXT=DELETE_TEXT +ali SC_MOD_CHANGESTYLE=CHANGE_STYLE +ali SC_MOD_CHANGEFOLD=CHANGE_FOLD +ali SC_MULTISTEPUNDOREDO=MULTI_STEP_UNDO_REDO +ali SC_LASTSTEPINUNDOREDO=LAST_STEP_IN_UNDO_REDO +ali SC_MOD_CHANGEMARKER=CHANGE_MARKER +ali SC_MOD_BEFOREINSERT=BEFORE_INSERT +ali SC_MOD_BEFOREDELETE=BEFORE_DELETE +ali SC_MULTILINEUNDOREDO=MULTILINE_UNDO_REDO +ali SC_STARTACTION=START_ACTION +ali SC_MOD_CHANGEINDICATOR=CHANGE_INDICATOR +ali SC_MOD_CHANGELINESTATE=CHANGE_LINE_STATE +ali SC_MOD_CHANGEMARGIN=CHANGE_MARGIN +ali SC_MOD_CHANGEANNOTATION=CHANGE_ANNOTATION +ali SC_MOD_LEXERSTATE=LEXER_STATE +ali SC_MOD_INSERTCHECK=INSERT_CHECK +ali SC_MOD_CHANGETABSTOPS=CHANGE_TAB_STOPS +ali SC_MOD_CHANGEEOLANNOTATION=CHANGE_E_O_L_ANNOTATION +ali SC_MODEVENTMASKALL=EVENT_MASK_ALL enu Update=SC_UPDATE_ val SC_UPDATE_CONTENT=0x1 @@ -2832,6 +3093,8 @@ val SCK_WIN=313 val SCK_RWIN=314 val SCK_MENU=315 +ali SCK_RWIN=R_WIN + enu KeyMod=SCMOD_ val SCMOD_NORM=0 val SCMOD_SHIFT=1 @@ -2847,6 +3110,18 @@ val SC_AC_TAB=3 val SC_AC_NEWLINE=4 val SC_AC_COMMAND=5 +ali SC_AC_FILLUP=FILL_UP +ali SC_AC_DOUBLECLICK=DOUBLE_CLICK + +# characterSource for SCN_CHARADDED +enu CharacterSource=SC_CHARACTERSOURCE_ +# Direct input characters. +val SC_CHARACTERSOURCE_DIRECT_INPUT=0 +# IME (inline mode) or dead key tentative input characters. +val SC_CHARACTERSOURCE_TENTATIVE_INPUT=1 +# IME (either inline or windowed mode) full composited string. +val SC_CHARACTERSOURCE_IME_RESULT=2 + ################################################ # For SciLexer.h enu Lexer=SCLEX_ @@ -2976,6 +3251,10 @@ val SCLEX_STATA=124 val SCLEX_SAS=125 val SCLEX_NIM=126 val SCLEX_CIL=127 +val SCLEX_X12=128 +val SCLEX_DATAFLEX=129 +val SCLEX_HOLLYWOOD=130 +val SCLEX_RAKU=131 val SCLEX_LPEG=999 # When a lexer specifies its language as SCLEX_AUTOMATIC it receives a @@ -3403,6 +3682,7 @@ val SCE_ERR_VALUE=21 val SCE_ERR_GCC_INCLUDED_FROM=22 val SCE_ERR_ESCSEQ=23 val SCE_ERR_ESCSEQ_UNKNOWN=24 +val SCE_ERR_GCC_EXCERPT=25 val SCE_ERR_ES_BLACK=40 val SCE_ERR_ES_RED=41 val SCE_ERR_ES_GREEN=42 @@ -4930,7 +5210,7 @@ val SCE_SAS_MACRO_KEYWORD=12 val SCE_SAS_BLOCK_KEYWORD=13 val SCE_SAS_MACRO_FUNCTION=14 val SCE_SAS_STATEMENT=15 -# Lexical states for SCLEX_NIM +# Lexical states for SCLEX_NIM lex Nim=SCLEX_NIM SCE_NIM_ val SCE_NIM_DEFAULT=0 val SCE_NIM_COMMENT=1 @@ -4962,15 +5242,91 @@ val SCE_CIL_LABEL=7 val SCE_CIL_OPERATOR=8 val SCE_CIL_IDENTIFIER=9 val SCE_CIL_STRINGEOL=10 +# Lexical states for SCLEX_X12 +lex X12=SCLEX_X12 SCE_X12_ +val SCE_X12_DEFAULT=0 +val SCE_X12_BAD=1 +val SCE_X12_ENVELOPE=2 +val SCE_X12_FUNCTIONGROUP=3 +val SCE_X12_TRANSACTIONSET=4 +val SCE_X12_SEGMENTHEADER=5 +val SCE_X12_SEGMENTEND=6 +val SCE_X12_SEP_ELEMENT=7 +val SCE_X12_SEP_SUBELEMENT=8 +# Lexical states for SCLEX_DATAFLEX +lex Dataflex=SCLEX_DATAFLEX SCE_DF_ +val SCE_DF_DEFAULT=0 +val SCE_DF_IDENTIFIER=1 +val SCE_DF_METATAG=2 +val SCE_DF_IMAGE=3 +val SCE_DF_COMMENTLINE=4 +val SCE_DF_PREPROCESSOR=5 +val SCE_DF_PREPROCESSOR2=6 +val SCE_DF_NUMBER=7 +val SCE_DF_HEXNUMBER=8 +val SCE_DF_WORD=9 +val SCE_DF_STRING=10 +val SCE_DF_STRINGEOL=11 +val SCE_DF_SCOPEWORD=12 +val SCE_DF_OPERATOR=13 +val SCE_DF_ICODE=14 +# Lexical states for SCLEX_HOLLYWOOD +lex Hollywood=SCLEX_HOLLYWOOD SCE_HOLLYWOOD_ +val SCE_HOLLYWOOD_DEFAULT=0 +val SCE_HOLLYWOOD_COMMENT=1 +val SCE_HOLLYWOOD_COMMENTBLOCK=2 +val SCE_HOLLYWOOD_NUMBER=3 +val SCE_HOLLYWOOD_KEYWORD=4 +val SCE_HOLLYWOOD_STDAPI=5 +val SCE_HOLLYWOOD_PLUGINAPI=6 +val SCE_HOLLYWOOD_PLUGINMETHOD=7 +val SCE_HOLLYWOOD_STRING=8 +val SCE_HOLLYWOOD_STRINGBLOCK=9 +val SCE_HOLLYWOOD_PREPROCESSOR=10 +val SCE_HOLLYWOOD_OPERATOR=11 +val SCE_HOLLYWOOD_IDENTIFIER=12 +val SCE_HOLLYWOOD_CONSTANT=13 +val SCE_HOLLYWOOD_HEXNUMBER=14 +# Lexical states for SCLEX_RAKU +lex Raku=SCLEX_RAKU SCE_RAKU_ +val SCE_RAKU_DEFAULT=0 +val SCE_RAKU_ERROR=1 +val SCE_RAKU_COMMENTLINE=2 +val SCE_RAKU_COMMENTEMBED=3 +val SCE_RAKU_POD=4 +val SCE_RAKU_CHARACTER=5 +val SCE_RAKU_HEREDOC_Q=6 +val SCE_RAKU_HEREDOC_QQ=7 +val SCE_RAKU_STRING=8 +val SCE_RAKU_STRING_Q=9 +val SCE_RAKU_STRING_QQ=10 +val SCE_RAKU_STRING_Q_LANG=11 +val SCE_RAKU_STRING_VAR=12 +val SCE_RAKU_REGEX=13 +val SCE_RAKU_REGEX_VAR=14 +val SCE_RAKU_ADVERB=15 +val SCE_RAKU_NUMBER=16 +val SCE_RAKU_PREPROCESSOR=17 +val SCE_RAKU_OPERATOR=18 +val SCE_RAKU_WORD=19 +val SCE_RAKU_FUNCTION=20 +val SCE_RAKU_IDENTIFIER=21 +val SCE_RAKU_TYPEDEF=22 +val SCE_RAKU_MU=23 +val SCE_RAKU_POSITIONAL=24 +val SCE_RAKU_ASSOCIATIVE=25 +val SCE_RAKU_CALLABLE=26 +val SCE_RAKU_GRAMMAR=27 +val SCE_RAKU_CLASS=28 # Events evt void StyleNeeded=2000(int position) -evt void CharAdded=2001(int ch) +evt void CharAdded=2001(int ch, int characterSource) evt void SavePointReached=2002(void) evt void SavePointLeft=2003(void) evt void ModifyAttemptRO=2004(void) -# GTK+ Specific to work around focus and accelerator problems: +# GTK Specific to work around focus and accelerator problems: evt void Key=2005(int ch, int modifiers) evt void DoubleClick=2006(int modifiers, int position, int line) evt void UpdateUI=2007(int updated) @@ -5007,19 +5363,19 @@ val SC_LINECHARACTERINDEX_UTF32=1 val SC_LINECHARACTERINDEX_UTF16=2 # Retrieve line character index state. -get int GetLineCharacterIndex=2710(,) +get LineCharacterIndexType GetLineCharacterIndex=2710(,) # Request line character index be created or its use count increased. -fun void AllocateLineCharacterIndex=2711(int lineCharacterIndex,) +fun void AllocateLineCharacterIndex=2711(LineCharacterIndexType lineCharacterIndex,) # Decrease use count of line character index and remove if 0. -fun void ReleaseLineCharacterIndex=2712(int lineCharacterIndex,) +fun void ReleaseLineCharacterIndex=2712(LineCharacterIndexType lineCharacterIndex,) # Retrieve the document line containing a position measured in index units. -fun int LineFromIndexPosition=2713(position pos, int lineCharacterIndex) +fun line LineFromIndexPosition=2713(position pos, LineCharacterIndexType lineCharacterIndex) # Retrieve the position measured in index units at the start of a document line. -fun position IndexPositionFromLine=2714(int line, int lineCharacterIndex) +fun position IndexPositionFromLine=2714(line line, LineCharacterIndexType lineCharacterIndex) cat Deprecated @@ -5041,3 +5397,8 @@ set void SetKeysUnicode=2521(bool keysUnicode,) # Are keys always interpreted as Unicode? get bool GetKeysUnicode=2522(,) + +val INDIC0_MASK=0x20 +val INDIC1_MASK=0x40 +val INDIC2_MASK=0x80 +val INDICS_MASK=0xE0 diff --git a/scintilla/lexers/LexAbaqus.cxx b/scintilla/lexers/LexAbaqus.cxx index 96a7b886e2..0b9bfb62a7 100644 --- a/scintilla/lexers/LexAbaqus.cxx +++ b/scintilla/lexers/LexAbaqus.cxx @@ -1,5 +1,5 @@ // Scintilla source code edit control -/** @file LexABAQUS.cxx +/** @file LexAbaqus.cxx ** Lexer for ABAQUS. Based on the lexer for APDL by Hadar Raz. ** By Sergio Lucato. ** Sort of completely rewritten by Gertjan Kloosterman diff --git a/scintilla/lexers/LexAsm.cxx b/scintilla/lexers/LexAsm.cxx index bd82b16219..7f9c7d50b4 100644 --- a/scintilla/lexers/LexAsm.cxx +++ b/scintilla/lexers/LexAsm.cxx @@ -80,6 +80,7 @@ struct OptionsAsm { std::string foldExplicitEnd; bool foldExplicitAnywhere; bool foldCompact; + std::string commentChar; OptionsAsm() { delimiter = ""; fold = false; @@ -90,6 +91,7 @@ struct OptionsAsm { foldExplicitEnd = ""; foldExplicitAnywhere = false; foldCompact = true; + commentChar = ""; } }; @@ -134,6 +136,9 @@ struct OptionSetAsm : public OptionSet { DefineProperty("fold.compact", &OptionsAsm::foldCompact); + DefineProperty("lexer.as.comment.character", &OptionsAsm::commentChar, + "Overrides the default comment character (which is ';' for asm and '#' for as)."); + DefineWordListSets(asmWordListDesc); } }; @@ -151,7 +156,7 @@ class LexerAsm : public DefaultLexer { OptionSetAsm osAsm; int commentChar; public: - LexerAsm(int commentChar_) { + LexerAsm(const char *languageName_, int language_, int commentChar_) : DefaultLexer(languageName_, language_) { commentChar = commentChar_; } virtual ~LexerAsm() { @@ -160,7 +165,7 @@ class LexerAsm : public DefaultLexer { delete this; } int SCI_METHOD Version() const override { - return lvOriginal; + return lvIdentity; } const char * SCI_METHOD PropertyNames() override { return osAsm.PropertyNames(); @@ -172,6 +177,9 @@ class LexerAsm : public DefaultLexer { return osAsm.DescribeProperty(name); } Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override; + const char * SCI_METHOD PropertyGet(const char *key) override { + return osAsm.PropertyGet(key); + } const char * SCI_METHOD DescribeWordListSets() override { return osAsm.DescribeWordListSets(); } @@ -184,11 +192,11 @@ class LexerAsm : public DefaultLexer { } static ILexer *LexerFactoryAsm() { - return new LexerAsm(';'); + return new LexerAsm("asm", SCLEX_ASM, ';'); } static ILexer *LexerFactoryAs() { - return new LexerAsm('#'); + return new LexerAsm("as", SCLEX_AS, '#'); } }; @@ -242,6 +250,9 @@ Sci_Position SCI_METHOD LexerAsm::WordListSet(int n, const char *wl) { void SCI_METHOD LexerAsm::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) { LexAccessor styler(pAccess); + const char commentCharacter = options.commentChar.empty() ? + commentChar : options.commentChar.front(); + // Do not leak onto next line if (initStyle == SCE_ASM_STRINGEOL) initStyle = SCE_ASM_DEFAULT; @@ -347,7 +358,7 @@ void SCI_METHOD LexerAsm::Lex(Sci_PositionU startPos, Sci_Position length, int i // Determine if a new state should be entered. if (sc.state == SCE_ASM_DEFAULT) { - if (sc.ch == commentChar){ + if (sc.ch == commentCharacter) { sc.SetState(SCE_ASM_COMMENT); } else if (IsASCII(sc.ch) && (isdigit(sc.ch) || (sc.ch == '.' && IsASCII(sc.chNext) && isdigit(sc.chNext)))) { sc.SetState(SCE_ASM_NUMBER); diff --git a/scintilla/lexers/LexBash.cxx b/scintilla/lexers/LexBash.cxx index 45832b77d4..66bec38469 100644 --- a/scintilla/lexers/LexBash.cxx +++ b/scintilla/lexers/LexBash.cxx @@ -201,7 +201,7 @@ class LexerBash : public DefaultLexer { SubStyles subStyles; public: LexerBash() : - DefaultLexer(lexicalClasses, ELEMENTS(lexicalClasses)), + DefaultLexer("bash", SCLEX_BASH, lexicalClasses, ELEMENTS(lexicalClasses)), subStyles(styleSubable, 0x80, 0x40, 0) { } virtual ~LexerBash() { @@ -210,7 +210,7 @@ class LexerBash : public DefaultLexer { delete this; } int SCI_METHOD Version() const override { - return lvMetaData; + return lvIdentity; } const char * SCI_METHOD PropertyNames() override { return osBash.PropertyNames(); @@ -222,6 +222,9 @@ class LexerBash : public DefaultLexer { return osBash.DescribeProperty(name); } Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override; + const char * SCI_METHOD PropertyGet(const char* key) override { + return osBash.PropertyGet(key); + } const char * SCI_METHOD DescribeWordListSets() override { return osBash.DescribeWordListSets(); } diff --git a/scintilla/lexers/LexBasic.cxx b/scintilla/lexers/LexBasic.cxx index 4ec58dcdde..a288f9daa7 100644 --- a/scintilla/lexers/LexBasic.cxx +++ b/scintilla/lexers/LexBasic.cxx @@ -232,7 +232,9 @@ class LexerBasic : public DefaultLexer { OptionsBasic options; OptionSetBasic osBasic; public: - LexerBasic(char comment_char_, int (*CheckFoldPoint_)(char const *, int &), const char * const wordListDescriptions[]) : + LexerBasic(const char *languageName_, int language_, char comment_char_, + int (*CheckFoldPoint_)(char const *, int &), const char * const wordListDescriptions[]) : + DefaultLexer(languageName_, language_), comment_char(comment_char_), CheckFoldPoint(CheckFoldPoint_), osBasic(wordListDescriptions) { @@ -243,7 +245,7 @@ class LexerBasic : public DefaultLexer { delete this; } int SCI_METHOD Version() const override { - return lvOriginal; + return lvIdentity; } const char * SCI_METHOD PropertyNames() override { return osBasic.PropertyNames(); @@ -255,6 +257,9 @@ class LexerBasic : public DefaultLexer { return osBasic.DescribeProperty(name); } Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override; + const char * SCI_METHOD PropertyGet(const char *key) override { + return osBasic.PropertyGet(key); + } const char * SCI_METHOD DescribeWordListSets() override { return osBasic.DescribeWordListSets(); } @@ -266,13 +271,13 @@ class LexerBasic : public DefaultLexer { return 0; } static ILexer *LexerFactoryBlitzBasic() { - return new LexerBasic(';', CheckBlitzFoldPoint, blitzbasicWordListDesc); + return new LexerBasic("blitzbasic", SCLEX_BLITZBASIC, ';', CheckBlitzFoldPoint, blitzbasicWordListDesc); } static ILexer *LexerFactoryPureBasic() { - return new LexerBasic(';', CheckPureFoldPoint, purebasicWordListDesc); + return new LexerBasic("purebasic", SCLEX_PUREBASIC, ';', CheckPureFoldPoint, purebasicWordListDesc); } static ILexer *LexerFactoryFreeBasic() { - return new LexerBasic('\'', CheckFreeFoldPoint, freebasicWordListDesc ); + return new LexerBasic("freebasic", SCLEX_FREEBASIC, '\'', CheckFreeFoldPoint, freebasicWordListDesc ); } }; diff --git a/scintilla/lexers/LexBatch.cxx b/scintilla/lexers/LexBatch.cxx index db7e37688c..857b60ce69 100644 --- a/scintilla/lexers/LexBatch.cxx +++ b/scintilla/lexers/LexBatch.cxx @@ -41,7 +41,8 @@ static inline bool AtEOL(Accessor &styler, Sci_PositionU i) { // Tests for BATCH Operators static bool IsBOperator(char ch) { return (ch == '=') || (ch == '+') || (ch == '>') || (ch == '<') || - (ch == '|') || (ch == '?') || (ch == '*'); + (ch == '|') || (ch == '?') || (ch == '*')|| + (ch == '&') || (ch == '(') || (ch == ')'); } // Tests for BATCH Separators @@ -50,218 +51,198 @@ static bool IsBSeparator(char ch) { (ch == '\"') || (ch == '\'') || (ch == '/'); } -static void ColouriseBatchLine( - char *lineBuffer, - Sci_PositionU lengthLine, - Sci_PositionU startLine, - Sci_PositionU endPos, +// Tests for escape character +static bool IsEscaped(char* wordStr, Sci_PositionU pos) { + bool isQoted=false; + while (pos>0){ + pos--; + if (wordStr[pos]=='^') + isQoted=!isQoted; + else + break; + } + return isQoted; +} + +// Tests for quote character +static bool textQuoted(char *lineBuffer, Sci_PositionU endPos) { + char strBuffer[1024]; + strncpy(strBuffer, lineBuffer, endPos); + strBuffer[endPos] = '\0'; + char *pQuote; + pQuote = strchr(strBuffer, '"'); + bool CurrentStatus = false; + while (pQuote != NULL) + { + if (!IsEscaped(strBuffer, pQuote - strBuffer)) { + CurrentStatus = !CurrentStatus; + } + pQuote = strchr(pQuote + 1, '"'); + } + return CurrentStatus; +} + +static void ColouriseBatchDoc( + Sci_PositionU startPos, + Sci_Position length, + int /*initStyle*/, WordList *keywordlists[], Accessor &styler) { + // Always backtracks to the start of a line that is not a continuation + // of the previous line + if (startPos > 0) { + Sci_Position ln = styler.GetLine(startPos); // Current line number + while (startPos > 0) { + ln--; + if ((styler.SafeGetCharAt(startPos-3) == '^' && styler.SafeGetCharAt(startPos-2) == '\r' && styler.SafeGetCharAt(startPos-1) == '\n') + || styler.SafeGetCharAt(startPos-2) == '^') { // handle '^' line continuation + // When the line continuation is found, + // set the Start Position to the Start of the previous line + length+=startPos-styler.LineStart(ln); + startPos=styler.LineStart(ln); + } + else + break; + } + } - Sci_PositionU offset = 0; // Line Buffer Offset - Sci_PositionU cmdLoc; // External Command / Program Location - char wordBuffer[81]; // Word Buffer - large to catch long paths - Sci_PositionU wbl; // Word Buffer Length - Sci_PositionU wbo; // Word Buffer Offset - also Special Keyword Buffer Length - WordList &keywords = *keywordlists[0]; // Internal Commands - WordList &keywords2 = *keywordlists[1]; // External Commands (optional) + char lineBuffer[1024]; - // CHOICE, ECHO, GOTO, PROMPT and SET have Default Text that may contain Regular Keywords - // Toggling Regular Keyword Checking off improves readability - // Other Regular Keywords and External Commands / Programs might also benefit from toggling - // Need a more robust algorithm to properly toggle Regular Keyword Checking + styler.StartAt(startPos); + styler.StartSegment(startPos); + Sci_PositionU linePos = 0; + Sci_PositionU startLine = startPos; bool continueProcessing = true; // Used to toggle Regular Keyword Checking - // Special Keywords are those that allow certain characters without whitespace after the command - // Examples are: cd. cd\ md. rd. dir| dir> echo: echo. path= - // Special Keyword Buffer used to determine if the first n characters is a Keyword - char sKeywordBuffer[10]; // Special Keyword Buffer - bool sKeywordFound; // Exit Special Keyword for-loop if found - - // Skip initial spaces - while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) { - offset++; - } - // Colorize Default Text - styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT); - // Set External Command / Program Location - cmdLoc = offset; + bool isNotAssigned=false; // Used to flag Assignment in Set operation - // Check for Fake Label (Comment) or Real Label - return if found - if (lineBuffer[offset] == ':') { - if (lineBuffer[offset + 1] == ':') { - // Colorize Fake Label (Comment) - :: is similar to REM, see http://content.techweb.com/winmag/columns/explorer/2000/21.htm - styler.ColourTo(endPos, SCE_BAT_COMMENT); - } else { - // Colorize Real Label - styler.ColourTo(endPos, SCE_BAT_LABEL); - } - return; - // Check for Drive Change (Drive Change is internal command) - return if found - } else if ((IsAlphabetic(lineBuffer[offset])) && - (lineBuffer[offset + 1] == ':') && - ((isspacechar(lineBuffer[offset + 2])) || - (((lineBuffer[offset + 2] == '\\')) && - (isspacechar(lineBuffer[offset + 3]))))) { - // Colorize Regular Keyword - styler.ColourTo(endPos, SCE_BAT_WORD); - return; - } + for (Sci_PositionU i = startPos; i < startPos + length; i++) { + lineBuffer[linePos++] = styler[i]; + if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1) || (i==startPos + length-1)) { + // End of line (or of line buffer) (or End of Last Line) met, colourise it + lineBuffer[linePos] = '\0'; + Sci_PositionU lengthLine=linePos; + Sci_PositionU endPos=i; + Sci_PositionU offset = 0; // Line Buffer Offset + Sci_PositionU cmdLoc; // External Command / Program Location + char wordBuffer[81]; // Word Buffer - large to catch long paths + Sci_PositionU wbl; // Word Buffer Length + Sci_PositionU wbo; // Word Buffer Offset - also Special Keyword Buffer Length + WordList &keywords = *keywordlists[0]; // Internal Commands + WordList &keywords2 = *keywordlists[1]; // External Commands (optional) - // Check for Hide Command (@ECHO OFF/ON) - if (lineBuffer[offset] == '@') { - styler.ColourTo(startLine + offset, SCE_BAT_HIDE); - offset++; - } - // Skip next spaces - while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) { - offset++; - } + // CHOICE, ECHO, GOTO, PROMPT and SET have Default Text that may contain Regular Keywords + // Toggling Regular Keyword Checking off improves readability + // Other Regular Keywords and External Commands / Programs might also benefit from toggling + // Need a more robust algorithm to properly toggle Regular Keyword Checking + bool stopLineProcessing=false; // Used to stop line processing if Comment or Drive Change found + // Special Keywords are those that allow certain characters without whitespace after the command + // Examples are: cd. cd\ md. rd. dir| dir> echo: echo. path= + // Special Keyword Buffer used to determine if the first n characters is a Keyword + char sKeywordBuffer[10]; // Special Keyword Buffer + bool sKeywordFound; // Exit Special Keyword for-loop if found - // Read remainder of line word-at-a-time or remainder-of-word-at-a-time - while (offset < lengthLine) { - if (offset > startLine) { + // Skip initial spaces + while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) { + offset++; + } // Colorize Default Text styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT); - } - // Copy word from Line Buffer into Word Buffer - wbl = 0; - for (; offset < lengthLine && wbl < 80 && - !isspacechar(lineBuffer[offset]); wbl++, offset++) { - wordBuffer[wbl] = static_cast(tolower(lineBuffer[offset])); - } - wordBuffer[wbl] = '\0'; - wbo = 0; + // Set External Command / Program Location + cmdLoc = offset; - // Check for Comment - return if found - if (CompareCaseInsensitive(wordBuffer, "rem") == 0) { - styler.ColourTo(endPos, SCE_BAT_COMMENT); - return; - } - // Check for Separator - if (IsBSeparator(wordBuffer[0])) { - // Check for External Command / Program - if ((cmdLoc == offset - wbl) && - ((wordBuffer[0] == ':') || - (wordBuffer[0] == '\\') || - (wordBuffer[0] == '.'))) { - // Reset Offset to re-process remainder of word - offset -= (wbl - 1); - // Colorize External Command / Program - if (!keywords2) { - styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND); - } else if (keywords2.InList(wordBuffer)) { - styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND); + // Check for Fake Label (Comment) or Real Label - return if found + if (lineBuffer[offset] == ':') { + if (lineBuffer[offset + 1] == ':') { + // Colorize Fake Label (Comment) - :: is similar to REM, see http://content.techweb.com/winmag/columns/explorer/2000/21.htm + styler.ColourTo(endPos, SCE_BAT_COMMENT); } else { - styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT); + // Colorize Real Label + styler.ColourTo(endPos, SCE_BAT_LABEL); } - // Reset External Command / Program Location - cmdLoc = offset; - } else { - // Reset Offset to re-process remainder of word - offset -= (wbl - 1); - // Colorize Default Text - styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT); + stopLineProcessing=true; + // Check for Drive Change (Drive Change is internal command) - return if found + } else if ((IsAlphabetic(lineBuffer[offset])) && + (lineBuffer[offset + 1] == ':') && + ((isspacechar(lineBuffer[offset + 2])) || + (((lineBuffer[offset + 2] == '\\')) && + (isspacechar(lineBuffer[offset + 3]))))) { + // Colorize Regular Keyword + styler.ColourTo(endPos, SCE_BAT_WORD); + stopLineProcessing=true; } - // Check for Regular Keyword in list - } else if ((keywords.InList(wordBuffer)) && - (continueProcessing)) { - // ECHO, GOTO, PROMPT and SET require no further Regular Keyword Checking - if ((CompareCaseInsensitive(wordBuffer, "echo") == 0) || - (CompareCaseInsensitive(wordBuffer, "goto") == 0) || - (CompareCaseInsensitive(wordBuffer, "prompt") == 0) || - (CompareCaseInsensitive(wordBuffer, "set") == 0)) { - continueProcessing = false; + + // Check for Hide Command (@ECHO OFF/ON) + if (lineBuffer[offset] == '@') { + styler.ColourTo(startLine + offset, SCE_BAT_HIDE); + offset++; } - // Identify External Command / Program Location for ERRORLEVEL, and EXIST - if ((CompareCaseInsensitive(wordBuffer, "errorlevel") == 0) || - (CompareCaseInsensitive(wordBuffer, "exist") == 0)) { - // Reset External Command / Program Location - cmdLoc = offset; - // Skip next spaces - while ((cmdLoc < lengthLine) && - (isspacechar(lineBuffer[cmdLoc]))) { - cmdLoc++; - } - // Skip comparison - while ((cmdLoc < lengthLine) && - (!isspacechar(lineBuffer[cmdLoc]))) { - cmdLoc++; - } - // Skip next spaces - while ((cmdLoc < lengthLine) && - (isspacechar(lineBuffer[cmdLoc]))) { - cmdLoc++; + // Skip next spaces + while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) { + offset++; + } + + // Read remainder of line word-at-a-time or remainder-of-word-at-a-time + while (offset < lengthLine && !stopLineProcessing) { + if (offset > startLine) { + // Colorize Default Text + styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT); } - // Identify External Command / Program Location for CALL, DO, LOADHIGH and LH - } else if ((CompareCaseInsensitive(wordBuffer, "call") == 0) || - (CompareCaseInsensitive(wordBuffer, "do") == 0) || - (CompareCaseInsensitive(wordBuffer, "loadhigh") == 0) || - (CompareCaseInsensitive(wordBuffer, "lh") == 0)) { - // Reset External Command / Program Location - cmdLoc = offset; - // Skip next spaces - while ((cmdLoc < lengthLine) && - (isspacechar(lineBuffer[cmdLoc]))) { - cmdLoc++; + // Copy word from Line Buffer into Word Buffer + wbl = 0; + for (; offset < lengthLine && wbl < 80 && + !isspacechar(lineBuffer[offset]); wbl++, offset++) { + wordBuffer[wbl] = static_cast(tolower(lineBuffer[offset])); } - } - // Colorize Regular keyword - styler.ColourTo(startLine + offset - 1, SCE_BAT_WORD); - // No need to Reset Offset - // Check for Special Keyword in list, External Command / Program, or Default Text - } else if ((wordBuffer[0] != '%') && - (wordBuffer[0] != '!') && - (!IsBOperator(wordBuffer[0])) && - (continueProcessing)) { - // Check for Special Keyword - // Affected Commands are in Length range 2-6 - // Good that ERRORLEVEL, EXIST, CALL, DO, LOADHIGH, and LH are unaffected - sKeywordFound = false; - for (Sci_PositionU keywordLength = 2; keywordLength < wbl && keywordLength < 7 && !sKeywordFound; keywordLength++) { + wordBuffer[wbl] = '\0'; wbo = 0; - // Copy Keyword Length from Word Buffer into Special Keyword Buffer - for (; wbo < keywordLength; wbo++) { - sKeywordBuffer[wbo] = static_cast(wordBuffer[wbo]); + + // Check for Comment - return if found + if ((CompareCaseInsensitive(wordBuffer, "rem") == 0) && continueProcessing) { + styler.ColourTo(endPos, SCE_BAT_COMMENT); + break; } - sKeywordBuffer[wbo] = '\0'; - // Check for Special Keyword in list - if ((keywords.InList(sKeywordBuffer)) && - ((IsBOperator(wordBuffer[wbo])) || - (IsBSeparator(wordBuffer[wbo])))) { - sKeywordFound = true; - // ECHO requires no further Regular Keyword Checking - if (CompareCaseInsensitive(sKeywordBuffer, "echo") == 0) { - continueProcessing = false; + // Check for Separator + if (IsBSeparator(wordBuffer[0])) { + // Check for External Command / Program + if ((cmdLoc == offset - wbl) && + ((wordBuffer[0] == ':') || + (wordBuffer[0] == '\\') || + (wordBuffer[0] == '.'))) { + // Reset Offset to re-process remainder of word + offset -= (wbl - 1); + // Colorize External Command / Program + if (!keywords2) { + styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND); + } else if (keywords2.InList(wordBuffer)) { + styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND); + } else { + styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT); + } + // Reset External Command / Program Location + cmdLoc = offset; + } else { + // Reset Offset to re-process remainder of word + offset -= (wbl - 1); + // Colorize Default Text + styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT); } - // Colorize Special Keyword as Regular Keyword - styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_WORD); - // Reset Offset to re-process remainder of word - offset -= (wbl - wbo); - } - } - // Check for External Command / Program or Default Text - if (!sKeywordFound) { - wbo = 0; - // Check for External Command / Program - if (cmdLoc == offset - wbl) { - // Read up to %, Operator or Separator - while ((wbo < wbl) && - (wordBuffer[wbo] != '%') && - (wordBuffer[wbo] != '!') && - (!IsBOperator(wordBuffer[wbo])) && - (!IsBSeparator(wordBuffer[wbo]))) { - wbo++; + // Check for Regular Keyword in list + } else if ((keywords.InList(wordBuffer)) && + (continueProcessing)) { + // ECHO, GOTO, PROMPT and SET require no further Regular Keyword Checking + if ((CompareCaseInsensitive(wordBuffer, "echo") == 0) || + (CompareCaseInsensitive(wordBuffer, "goto") == 0) || + (CompareCaseInsensitive(wordBuffer, "prompt") == 0)) { + continueProcessing = false; } - // Reset External Command / Program Location - cmdLoc = offset - (wbl - wbo); - // Reset Offset to re-process remainder of word - offset -= (wbl - wbo); - // CHOICE requires no further Regular Keyword Checking - if (CompareCaseInsensitive(wordBuffer, "choice") == 0) { + // SET requires additional processing for the assignment operator + if (CompareCaseInsensitive(wordBuffer, "set") == 0) { continueProcessing = false; + isNotAssigned=true; } - // Check for START (and its switches) - What follows is External Command \ Program - if (CompareCaseInsensitive(wordBuffer, "start") == 0) { + // Identify External Command / Program Location for ERRORLEVEL, and EXIST + if ((CompareCaseInsensitive(wordBuffer, "errorlevel") == 0) || + (CompareCaseInsensitive(wordBuffer, "exist") == 0)) { // Reset External Command / Program Location cmdLoc = offset; // Skip next spaces @@ -269,37 +250,284 @@ static void ColouriseBatchLine( (isspacechar(lineBuffer[cmdLoc]))) { cmdLoc++; } - // Reset External Command / Program Location if command switch detected - if (lineBuffer[cmdLoc] == '/') { - // Skip command switch - while ((cmdLoc < lengthLine) && - (!isspacechar(lineBuffer[cmdLoc]))) { - cmdLoc++; + // Skip comparison + while ((cmdLoc < lengthLine) && + (!isspacechar(lineBuffer[cmdLoc]))) { + cmdLoc++; + } + // Skip next spaces + while ((cmdLoc < lengthLine) && + (isspacechar(lineBuffer[cmdLoc]))) { + cmdLoc++; + } + // Identify External Command / Program Location for CALL, DO, LOADHIGH and LH + } else if ((CompareCaseInsensitive(wordBuffer, "call") == 0) || + (CompareCaseInsensitive(wordBuffer, "do") == 0) || + (CompareCaseInsensitive(wordBuffer, "loadhigh") == 0) || + (CompareCaseInsensitive(wordBuffer, "lh") == 0)) { + // Reset External Command / Program Location + cmdLoc = offset; + // Skip next spaces + while ((cmdLoc < lengthLine) && + (isspacechar(lineBuffer[cmdLoc]))) { + cmdLoc++; + } + } + // Colorize Regular keyword + styler.ColourTo(startLine + offset - 1, SCE_BAT_WORD); + // No need to Reset Offset + // Check for Special Keyword in list, External Command / Program, or Default Text + } else if ((wordBuffer[0] != '%') && + (wordBuffer[0] != '!') && + (!IsBOperator(wordBuffer[0])) && + (continueProcessing)) { + // Check for Special Keyword + // Affected Commands are in Length range 2-6 + // Good that ERRORLEVEL, EXIST, CALL, DO, LOADHIGH, and LH are unaffected + sKeywordFound = false; + for (Sci_PositionU keywordLength = 2; keywordLength < wbl && keywordLength < 7 && !sKeywordFound; keywordLength++) { + wbo = 0; + // Copy Keyword Length from Word Buffer into Special Keyword Buffer + for (; wbo < keywordLength; wbo++) { + sKeywordBuffer[wbo] = static_cast(wordBuffer[wbo]); + } + sKeywordBuffer[wbo] = '\0'; + // Check for Special Keyword in list + if ((keywords.InList(sKeywordBuffer)) && + ((IsBOperator(wordBuffer[wbo])) || + (IsBSeparator(wordBuffer[wbo])))) { + sKeywordFound = true; + // ECHO requires no further Regular Keyword Checking + if (CompareCaseInsensitive(sKeywordBuffer, "echo") == 0) { + continueProcessing = false; } - // Skip next spaces - while ((cmdLoc < lengthLine) && - (isspacechar(lineBuffer[cmdLoc]))) { - cmdLoc++; + // Colorize Special Keyword as Regular Keyword + styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_WORD); + // Reset Offset to re-process remainder of word + offset -= (wbl - wbo); + } + } + // Check for External Command / Program or Default Text + if (!sKeywordFound) { + wbo = 0; + // Check for External Command / Program + if (cmdLoc == offset - wbl) { + // Read up to %, Operator or Separator + while ((wbo < wbl) && + (((wordBuffer[wbo] != '%') && + (wordBuffer[wbo] != '!') && + (!IsBOperator(wordBuffer[wbo])) && + (!IsBSeparator(wordBuffer[wbo]))))) { + wbo++; + } + // Reset External Command / Program Location + cmdLoc = offset - (wbl - wbo); + // Reset Offset to re-process remainder of word + offset -= (wbl - wbo); + // CHOICE requires no further Regular Keyword Checking + if (CompareCaseInsensitive(wordBuffer, "choice") == 0) { + continueProcessing = false; + } + // Check for START (and its switches) - What follows is External Command \ Program + if (CompareCaseInsensitive(wordBuffer, "start") == 0) { + // Reset External Command / Program Location + cmdLoc = offset; + // Skip next spaces + while ((cmdLoc < lengthLine) && + (isspacechar(lineBuffer[cmdLoc]))) { + cmdLoc++; + } + // Reset External Command / Program Location if command switch detected + if (lineBuffer[cmdLoc] == '/') { + // Skip command switch + while ((cmdLoc < lengthLine) && + (!isspacechar(lineBuffer[cmdLoc]))) { + cmdLoc++; + } + // Skip next spaces + while ((cmdLoc < lengthLine) && + (isspacechar(lineBuffer[cmdLoc]))) { + cmdLoc++; + } + } + } + // Colorize External Command / Program + if (!keywords2) { + styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND); + } else if (keywords2.InList(wordBuffer)) { + styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND); + } else { + styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT); } + // No need to Reset Offset + // Check for Default Text + } else { + // Read up to %, Operator or Separator + while ((wbo < wbl) && + (((wordBuffer[wbo] != '%') && + (wordBuffer[wbo] != '!') && + (!IsBOperator(wordBuffer[wbo])) && + (!IsBSeparator(wordBuffer[wbo]))))) { + wbo++; + } + // Colorize Default Text + styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_DEFAULT); + // Reset Offset to re-process remainder of word + offset -= (wbl - wbo); + } + } + // Check for Argument (%n), Environment Variable (%x...%) or Local Variable (%%a) + } else if (wordBuffer[0] == '%') { + // Colorize Default Text + styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT); + wbo++; + // Search to end of word for second % (can be a long path) + while ((wbo < wbl) && + (wordBuffer[wbo] != '%')) { + wbo++; + } + // Check for Argument (%n) or (%*) + if (((Is0To9(wordBuffer[1])) || (wordBuffer[1] == '*')) && + (wordBuffer[wbo] != '%')) { + // Check for External Command / Program + if (cmdLoc == offset - wbl) { + cmdLoc = offset - (wbl - 2); + } + // Colorize Argument + styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_IDENTIFIER); + // Reset Offset to re-process remainder of word + offset -= (wbl - 2); + // Check for Expanded Argument (%~...) / Variable (%%~...) + } else if (((wbl > 1) && (wordBuffer[1] == '~')) || + ((wbl > 2) && (wordBuffer[1] == '%') && (wordBuffer[2] == '~'))) { + // Check for External Command / Program + if (cmdLoc == offset - wbl) { + cmdLoc = offset - (wbl - wbo); + } + // Colorize Expanded Argument / Variable + styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER); + // Reset Offset to re-process remainder of word + offset -= (wbl - wbo); + // Check for Environment Variable (%x...%) + } else if ((wordBuffer[1] != '%') && + (wordBuffer[wbo] == '%')) { + wbo++; + // Check for External Command / Program + if (cmdLoc == offset - wbl) { + cmdLoc = offset - (wbl - wbo); } + // Colorize Environment Variable + styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER); + // Reset Offset to re-process remainder of word + offset -= (wbl - wbo); + // Check for Local Variable (%%a) + } else if ( + (wbl > 2) && + (wordBuffer[1] == '%') && + (wordBuffer[2] != '%') && + (!IsBOperator(wordBuffer[2])) && + (!IsBSeparator(wordBuffer[2]))) { + // Check for External Command / Program + if (cmdLoc == offset - wbl) { + cmdLoc = offset - (wbl - 3); + } + // Colorize Local Variable + styler.ColourTo(startLine + offset - 1 - (wbl - 3), SCE_BAT_IDENTIFIER); + // Reset Offset to re-process remainder of word + offset -= (wbl - 3); + } + // Check for Environment Variable (!x...!) + } else if (wordBuffer[0] == '!') { + // Colorize Default Text + styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT); + wbo++; + // Search to end of word for second ! (can be a long path) + while ((wbo < wbl) && + (wordBuffer[wbo] != '!')) { + wbo++; } - // Colorize External Command / Program - if (!keywords2) { - styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND); - } else if (keywords2.InList(wordBuffer)) { - styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND); + if (wordBuffer[wbo] == '!') { + wbo++; + // Check for External Command / Program + if (cmdLoc == offset - wbl) { + cmdLoc = offset - (wbl - wbo); + } + // Colorize Environment Variable + styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER); + // Reset Offset to re-process remainder of word + offset -= (wbl - wbo); + } + // Check for Operator + } else if (IsBOperator(wordBuffer[0])) { + // Colorize Default Text + styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT); + // Check for Comparison Operator + if ((wordBuffer[0] == '=') && (wordBuffer[1] == '=')) { + // Identify External Command / Program Location for IF + cmdLoc = offset; + // Skip next spaces + while ((cmdLoc < lengthLine) && + (isspacechar(lineBuffer[cmdLoc]))) { + cmdLoc++; + } + // Colorize Comparison Operator + if (continueProcessing) + styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_OPERATOR); + else + styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_DEFAULT); + // Reset Offset to re-process remainder of word + offset -= (wbl - 2); + // Check for Pipe Operator + } else if ((wordBuffer[0] == '|') && + !(IsEscaped(lineBuffer,offset - wbl + wbo) || textQuoted(lineBuffer, offset - wbl) )) { + // Reset External Command / Program Location + cmdLoc = offset - wbl + 1; + // Skip next spaces + while ((cmdLoc < lengthLine) && + (isspacechar(lineBuffer[cmdLoc]))) { + cmdLoc++; + } + // Colorize Pipe Operator + styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_BAT_OPERATOR); + // Reset Offset to re-process remainder of word + offset -= (wbl - 1); + continueProcessing = true; + // Check for Other Operator } else { - styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT); + // Check for Operators: >, |, & + if (((wordBuffer[0] == '>')|| + (wordBuffer[0] == ')')|| + (wordBuffer[0] == '(')|| + (wordBuffer[0] == '&' )) && + !(!continueProcessing && (IsEscaped(lineBuffer,offset - wbl + wbo) + || textQuoted(lineBuffer, offset - wbl) ))){ + // Turn Keyword and External Command / Program checking back on + continueProcessing = true; + isNotAssigned=false; + } + // Colorize Other Operators + // Do not Colorize Paranthesis, quoted text and escaped operators + if (((wordBuffer[0] != ')') && (wordBuffer[0] != '(') + && !textQuoted(lineBuffer, offset - wbl) && !IsEscaped(lineBuffer,offset - wbl + wbo)) + && !((wordBuffer[0] == '=') && !isNotAssigned )) + styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_BAT_OPERATOR); + else + styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_BAT_DEFAULT); + // Reset Offset to re-process remainder of word + offset -= (wbl - 1); + + if ((wordBuffer[0] == '=') && isNotAssigned ){ + isNotAssigned=false; + } } - // No need to Reset Offset // Check for Default Text } else { // Read up to %, Operator or Separator while ((wbo < wbl) && - (wordBuffer[wbo] != '%') && + ((wordBuffer[wbo] != '%') && (wordBuffer[wbo] != '!') && (!IsBOperator(wordBuffer[wbo])) && - (!IsBSeparator(wordBuffer[wbo]))) { + (!IsBSeparator(wordBuffer[wbo])))) { wbo++; } // Colorize Default Text @@ -307,186 +535,36 @@ static void ColouriseBatchLine( // Reset Offset to re-process remainder of word offset -= (wbl - wbo); } - } - // Check for Argument (%n), Environment Variable (%x...%) or Local Variable (%%a) - } else if (wordBuffer[0] == '%') { - // Colorize Default Text - styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT); - wbo++; - // Search to end of word for second % (can be a long path) - while ((wbo < wbl) && - (wordBuffer[wbo] != '%') && - (!IsBOperator(wordBuffer[wbo])) && - (!IsBSeparator(wordBuffer[wbo]))) { - wbo++; - } - // Check for Argument (%n) or (%*) - if (((Is0To9(wordBuffer[1])) || (wordBuffer[1] == '*')) && - (wordBuffer[wbo] != '%')) { - // Check for External Command / Program - if (cmdLoc == offset - wbl) { - cmdLoc = offset - (wbl - 2); - } - // Colorize Argument - styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_IDENTIFIER); - // Reset Offset to re-process remainder of word - offset -= (wbl - 2); - // Check for Expanded Argument (%~...) / Variable (%%~...) - } else if (((wbl > 1) && (wordBuffer[1] == '~')) || - ((wbl > 2) && (wordBuffer[1] == '%') && (wordBuffer[2] == '~'))) { - // Check for External Command / Program - if (cmdLoc == offset - wbl) { - cmdLoc = offset - (wbl - wbo); - } - // Colorize Expanded Argument / Variable - styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER); - // Reset Offset to re-process remainder of word - offset -= (wbl - wbo); - // Check for Environment Variable (%x...%) - } else if ((wordBuffer[1] != '%') && - (wordBuffer[wbo] == '%')) { - wbo++; - // Check for External Command / Program - if (cmdLoc == offset - wbl) { - cmdLoc = offset - (wbl - wbo); - } - // Colorize Environment Variable - styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER); - // Reset Offset to re-process remainder of word - offset -= (wbl - wbo); - // Check for Local Variable (%%a) - } else if ( - (wbl > 2) && - (wordBuffer[1] == '%') && - (wordBuffer[2] != '%') && - (!IsBOperator(wordBuffer[2])) && - (!IsBSeparator(wordBuffer[2]))) { - // Check for External Command / Program - if (cmdLoc == offset - wbl) { - cmdLoc = offset - (wbl - 3); - } - // Colorize Local Variable - styler.ColourTo(startLine + offset - 1 - (wbl - 3), SCE_BAT_IDENTIFIER); - // Reset Offset to re-process remainder of word - offset -= (wbl - 3); - } - // Check for Environment Variable (!x...!) - } else if (wordBuffer[0] == '!') { - // Colorize Default Text - styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT); - wbo++; - // Search to end of word for second ! (can be a long path) - while ((wbo < wbl) && - (wordBuffer[wbo] != '!') && - (!IsBOperator(wordBuffer[wbo])) && - (!IsBSeparator(wordBuffer[wbo]))) { - wbo++; - } - if (wordBuffer[wbo] == '!') { - wbo++; - // Check for External Command / Program - if (cmdLoc == offset - wbl) { - cmdLoc = offset - (wbl - wbo); + // Skip next spaces - nothing happens if Offset was Reset + while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) { + offset++; } - // Colorize Environment Variable - styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER); - // Reset Offset to re-process remainder of word - offset -= (wbl - wbo); } - // Check for Operator - } else if (IsBOperator(wordBuffer[0])) { - // Colorize Default Text - styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT); - // Check for Comparison Operator - if ((wordBuffer[0] == '=') && (wordBuffer[1] == '=')) { - // Identify External Command / Program Location for IF - cmdLoc = offset; - // Skip next spaces - while ((cmdLoc < lengthLine) && - (isspacechar(lineBuffer[cmdLoc]))) { - cmdLoc++; - } - // Colorize Comparison Operator - styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_OPERATOR); - // Reset Offset to re-process remainder of word - offset -= (wbl - 2); - // Check for Pipe Operator - } else if (wordBuffer[0] == '|') { - // Reset External Command / Program Location - cmdLoc = offset - wbl + 1; - // Skip next spaces - while ((cmdLoc < lengthLine) && - (isspacechar(lineBuffer[cmdLoc]))) { - cmdLoc++; - } - // Colorize Pipe Operator - styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_BAT_OPERATOR); - // Reset Offset to re-process remainder of word - offset -= (wbl - 1); - // Check for Other Operator - } else { - // Check for > Operator - if (wordBuffer[0] == '>') { - // Turn Keyword and External Command / Program checking back on - continueProcessing = true; + // Colorize Default Text for remainder of line - currently not lexed + styler.ColourTo(endPos, SCE_BAT_DEFAULT); + + // handle line continuation for SET and ECHO commands except the last line + if (!continueProcessing && (i2) && lineBuffer[linePos-2]=='\r') // Windows EOL + lineContinuationPos=linePos-3; + else + lineContinuationPos=linePos-2; // Unix or Mac EOL + // Reset continueProcessing if line continuation was not found + if ((lineBuffer[lineContinuationPos]!='^') + || IsEscaped(lineBuffer, lineContinuationPos) + || textQuoted(lineBuffer, lineContinuationPos)) + continueProcessing=true; } - // Colorize Other Operator - styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_BAT_OPERATOR); - // Reset Offset to re-process remainder of word - offset -= (wbl - 1); - } - // Check for Default Text - } else { - // Read up to %, Operator or Separator - while ((wbo < wbl) && - (wordBuffer[wbo] != '%') && - (wordBuffer[wbo] != '!') && - (!IsBOperator(wordBuffer[wbo])) && - (!IsBSeparator(wordBuffer[wbo]))) { - wbo++; } - // Colorize Default Text - styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_DEFAULT); - // Reset Offset to re-process remainder of word - offset -= (wbl - wbo); - } - // Skip next spaces - nothing happens if Offset was Reset - while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) { - offset++; - } - } - // Colorize Default Text for remainder of line - currently not lexed - styler.ColourTo(endPos, SCE_BAT_DEFAULT); -} - -static void ColouriseBatchDoc( - Sci_PositionU startPos, - Sci_Position length, - int /*initStyle*/, - WordList *keywordlists[], - Accessor &styler) { - char lineBuffer[1024]; - - styler.StartAt(startPos); - styler.StartSegment(startPos); - Sci_PositionU linePos = 0; - Sci_PositionU startLine = startPos; - for (Sci_PositionU i = startPos; i < startPos + length; i++) { - lineBuffer[linePos++] = styler[i]; - if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) { - // End of line (or of line buffer) met, colourise it - lineBuffer[linePos] = '\0'; - ColouriseBatchLine(lineBuffer, linePos, startLine, i, keywordlists, styler); linePos = 0; startLine = i + 1; } } - if (linePos > 0) { // Last line does not have ending characters - lineBuffer[linePos] = '\0'; - ColouriseBatchLine(lineBuffer, linePos, startLine, startPos + length - 1, - keywordlists, styler); - } } static const char *const batchWordListDesc[] = { diff --git a/scintilla/lexers/LexCPP.cxx b/scintilla/lexers/LexCPP.cxx index 06d4c0265a..c7d09a7a3b 100644 --- a/scintilla/lexers/LexCPP.cxx +++ b/scintilla/lexers/LexCPP.cxx @@ -6,12 +6,9 @@ // Copyright 1998-2005 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. -#include -#include -#include -#include -#include -#include +#include +#include +#include #include #include @@ -144,10 +141,10 @@ BracketPair FindBracketPair(std::vector &tokens) { void highlightTaskMarker(StyleContext &sc, LexAccessor &styler, int activity, const WordList &markerList, bool caseSensitive){ if ((isoperator(sc.chPrev) || IsASpace(sc.chPrev)) && markerList.Length()) { - const int lengthMarker = 50; + constexpr Sci_PositionU lengthMarker = 50; char marker[lengthMarker+1] = ""; - const Sci_Position currPos = sc.currentPos; - int i = 0; + const Sci_PositionU currPos = sc.currentPos; + Sci_PositionU i = 0; while (i < lengthMarker) { const char ch = styler.SafeGetCharAt(currPos + i); if (IsASpace(ch) || isoperator(ch)) { @@ -166,18 +163,14 @@ void highlightTaskMarker(StyleContext &sc, LexAccessor &styler, } } -struct EscapeSequence { - int digitsLeft; - CharacterSet setHexDigits; - CharacterSet setOctDigits; - CharacterSet setNoneNumeric; - CharacterSet *escapeSetValid; - EscapeSequence() { - digitsLeft = 0; - escapeSetValid = nullptr; - setHexDigits = CharacterSet(CharacterSet::setDigits, "ABCDEFabcdef"); - setOctDigits = CharacterSet(CharacterSet::setNone, "01234567"); - } +class EscapeSequence { + const CharacterSet setHexDigits = CharacterSet(CharacterSet::setDigits, "ABCDEFabcdef"); + const CharacterSet setOctDigits = CharacterSet(CharacterSet::setNone, "01234567"); + const CharacterSet setNoneNumeric; + const CharacterSet *escapeSetValid = nullptr; + int digitsLeft = 0; +public: + EscapeSequence() = default; void resetEscapeState(int nextChar) { digitsLeft = 0; escapeSetValid = &setNoneNumeric; @@ -198,6 +191,9 @@ struct EscapeSequence { bool atEscapeEnd(int currChar) const { return (digitsLeft <= 0) || !escapeSetValid->Contains(currChar); } + void consumeDigit() noexcept { + digitsLeft--; + } }; std::string GetRestOfLine(LexAccessor &styler, Sci_Position start, bool allowSpace) { @@ -245,7 +241,7 @@ struct PPDefinition { } }; -const int inactiveFlag = 0x40; +constexpr int inactiveFlag = 0x40; class LinePPState { // Track the state of preprocessor conditionals to allow showing active and inactive @@ -318,7 +314,7 @@ class LinePPState { class PPStates { std::vector vlls; public: - LinePPState ForLine(Sci_Position line) const { + LinePPState ForLine(Sci_Position line) const noexcept { if ((line > 0) && (vlls.size() > static_cast(line))) { return vlls[line]; } else { @@ -497,9 +493,11 @@ LexicalClass lexicalClasses[] = { 27, "SCE_C_ESCAPESEQUENCE", "literal string escapesequence", "Escape sequence", }; +const int sizeLexicalClasses = static_cast(Sci::size(lexicalClasses)); + } -class LexerCPP : public ILexerWithMetaData { +class LexerCPP : public ILexerWithIdentity { bool caseSensitive; CharacterSet setWord; CharacterSet setNegationOp; @@ -562,7 +560,7 @@ class LexerCPP : public ILexerWithMetaData { delete this; } int SCI_METHOD Version() const noexcept override { - return lvMetaData; + return lvIdentity; } const char * SCI_METHOD PropertyNames() override { return osCPP.PropertyNames(); @@ -620,13 +618,13 @@ class LexerCPP : public ILexerWithMetaData { } int SCI_METHOD NamedStyles() override { return std::max(subStyles.LastAllocated() + 1, - static_cast(ELEMENTS(lexicalClasses))) + + sizeLexicalClasses) + inactiveFlag; } const char * SCI_METHOD NameOfStyle(int style) override { if (style >= NamedStyles()) return ""; - if (style < static_cast(ELEMENTS(lexicalClasses))) + if (style < sizeLexicalClasses) return lexicalClasses[style].name; // TODO: inactive and substyles return ""; @@ -650,12 +648,12 @@ class LexerCPP : public ILexerWithMetaData { return returnBuffer.c_str(); } } - if (style < static_cast(ELEMENTS(lexicalClasses))) + if (style < sizeLexicalClasses) return lexicalClasses[style].tags; if (style >= inactiveFlag) { returnBuffer = "inactive "; const int styleActive = style - inactiveFlag; - if (styleActive < static_cast(ELEMENTS(lexicalClasses))) + if (styleActive < sizeLexicalClasses) returnBuffer += lexicalClasses[styleActive].tags; else returnBuffer = ""; @@ -666,12 +664,21 @@ class LexerCPP : public ILexerWithMetaData { const char * SCI_METHOD DescriptionOfStyle(int style) override { if (style >= NamedStyles()) return ""; - if (style < static_cast(ELEMENTS(lexicalClasses))) + if (style < sizeLexicalClasses) return lexicalClasses[style].description; // TODO: inactive and substyles return ""; } + // ILexerWithIdentity methods + const char * SCI_METHOD GetName() override { + return caseSensitive ? "cpp" : "cppnocase"; + } + int SCI_METHOD GetIdentifier() override { + return caseSensitive ? SCLEX_CPP : SCLEX_CPPNOCASE; + } + const char * SCI_METHOD PropertyGet(const char *key) override; + static ILexer *LexerFactoryCPP() { return new LexerCPP(true); } @@ -699,6 +706,10 @@ Sci_Position SCI_METHOD LexerCPP::PropertySet(const char *key, const char *val) return -1; } +const char * SCI_METHOD LexerCPP::PropertyGet(const char *key) { + return osCPP.PropertyGet(key); +} + Sci_Position SCI_METHOD LexerCPP::WordListSet(int n, const char *wl) { WordList *wordListN = nullptr; switch (n) { @@ -820,7 +831,7 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i ppDefineHistory.clear(); std::vector::iterator itInvalid = std::find_if(ppDefineHistory.begin(), ppDefineHistory.end(), - [lineCurrent](const PPDefinition &p) { return p.line >= lineCurrent; }); + [lineCurrent](const PPDefinition &p) noexcept { return p.line >= lineCurrent; }); if (itInvalid != ppDefineHistory.end()) { ppDefineHistory.erase(itInvalid, ppDefineHistory.end()); definitionsChanged = true; @@ -1095,7 +1106,7 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i } break; case SCE_C_ESCAPESEQUENCE: - escapeSeq.digitsLeft--; + escapeSeq.consumeDigit(); if (!escapeSeq.atEscapeEnd(sc.ch)) { break; } @@ -1147,9 +1158,9 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i case SCE_C_REGEX: if (sc.atLineStart) { sc.SetState(SCE_C_DEFAULT|activitySet); - } else if (! inRERange && sc.ch == '/') { + } else if (!inRERange && sc.ch == '/') { sc.Forward(); - while ((sc.ch < 0x80) && islower(sc.ch)) + while (IsLowerCase(sc.ch)) sc.Forward(); // gobble regex flags sc.SetState(SCE_C_DEFAULT|activitySet); } else if (sc.ch == '\\' && ((sc.currentPos+1) < lineEndNext)) { @@ -1575,7 +1586,7 @@ void LexerCPP::EvaluateTokens(std::vector &tokens, const SymbolTabl } // Evaluate identifiers - const size_t maxIterations = 100; + constexpr size_t maxIterations = 100; size_t iterations = 0; // Limit number of iterations in case there is a recursive macro. for (size_t i = 0; (i &nonFoldingTags) { std::string tag; - // Copy after the '<' + // Copy after the '<' and stop before ' ' for (Sci_PositionU cPos = start; cPos <= end; cPos++) { const char ch = styler[cPos]; + if (IsASpace(ch)) { + break; + } if ((ch != '<') && (ch != '/')) { tag.push_back(caseSensitive ? ch : MakeLowerCase(ch)); } @@ -289,8 +305,12 @@ int classifyTagHTML(Sci_PositionU start, Sci_PositionU end, chAttr = SCE_H_SGML_DEFAULT; } else if (!keywords || keywords.InList(tag.c_str())) { chAttr = SCE_H_TAG; + } else if (!isXml && isHTMLCustomElement(tag)) { + chAttr = SCE_H_TAG; + } + if (chAttr != SCE_H_TAGUNKNOWN) { + styler.ColourTo(end, chAttr); } - styler.ColourTo(end, chAttr); if (chAttr == SCE_H_TAG) { if (allowScripts && (tag == "script")) { // check to see if this is a self-closing tag by sniffing ahead @@ -563,6 +583,7 @@ struct OptionsHTML { bool foldCompact = true; bool foldComment = false; bool foldHeredoc = false; + bool foldXmlAtTagOpen = false; OptionsHTML() noexcept { } }; @@ -627,6 +648,10 @@ struct OptionSetHTML : public OptionSet { "Allow folding for heredocs in scripts embedded in HTML. " "The default is off."); + DefineProperty("fold.xml.at.tag.open", &OptionsHTML::foldXmlAtTagOpen, + "Enable folding for XML at the start of open tag. " + "The default is off."); + DefineWordListSets(isPHPScript_ ? phpscriptWordListDesc : htmlWordListDesc); } }; @@ -822,6 +847,7 @@ const char *tagsThatDoNotFold[] = { }; } + class LexerHTML : public DefaultLexer { bool isXml; bool isPHPScript; @@ -836,8 +862,11 @@ class LexerHTML : public DefaultLexer { std::set nonFoldingTags; public: explicit LexerHTML(bool isXml_, bool isPHPScript_) : - DefaultLexer(isXml_ ? lexicalClassesHTML : lexicalClassesXML, - isXml_ ? ELEMENTS(lexicalClassesHTML) : ELEMENTS(lexicalClassesXML)), + DefaultLexer( + isXml_ ? "xml" : (isPHPScript_ ? "phpscript" : "hypertext"), + isXml_ ? SCLEX_XML : (isPHPScript_ ? SCLEX_PHPSCRIPT : SCLEX_HTML), + isXml_ ? lexicalClassesHTML : lexicalClassesXML, + isXml_ ? Sci::size(lexicalClassesHTML) : Sci::size(lexicalClassesXML)), isXml(isXml_), isPHPScript(isPHPScript_), osHTML(isPHPScript_), @@ -858,6 +887,9 @@ class LexerHTML : public DefaultLexer { return osHTML.DescribeProperty(name); } Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override; + const char * SCI_METHOD PropertyGet(const char *key) override { + return osHTML.PropertyGet(key); + } const char *SCI_METHOD DescribeWordListSets() override { return osHTML.DescribeWordListSets(); } @@ -992,6 +1024,7 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int const bool foldCompact = options.foldCompact; const bool foldComment = fold && options.foldComment; const bool foldHeredoc = fold && options.foldHeredoc; + const bool foldXmlAtTagOpen = isXml && fold && options.foldXmlAtTagOpen; const bool caseSensitive = options.caseSensitive; const bool allowScripts = options.allowScripts; const bool isMako = options.isMako; @@ -1207,6 +1240,9 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int i += 2; visibleChars += 2; tagClosing = true; + if (foldXmlAtTagOpen) { + levelCurrent--; + } continue; } } @@ -1532,6 +1568,12 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int // in HTML, fold on tag open and unfold on tag close tagOpened = true; tagClosing = (chNext == '/'); + if (foldXmlAtTagOpen && !(chNext == '/' || chNext == '?' || chNext == '!' || chNext == '-' || chNext == '%')) { + levelCurrent++; + } + if (foldXmlAtTagOpen && chNext == '/') { + levelCurrent--; + } styler.ColourTo(i - 1, StateToPrint); if (chNext != '!') state = SCE_H_TAGUNKNOWN; @@ -1728,7 +1770,7 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int state = SCE_H_DEFAULT; } tagOpened = false; - if (!tagDontFold) { + if (!(foldXmlAtTagOpen || tagDontFold)) { if (tagClosing) { levelCurrent--; } else { @@ -1747,6 +1789,9 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int ch = chNext; state = SCE_H_DEFAULT; tagOpened = false; + if (foldXmlAtTagOpen) { + levelCurrent--; + } } else { if (eClass != SCE_H_TAGUNKNOWN) { if (eClass == SCE_H_SGML_DEFAULT) { @@ -1776,7 +1821,7 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int state = SCE_H_DEFAULT; } tagOpened = false; - if (!tagDontFold) { + if (!(foldXmlAtTagOpen || tagDontFold)) { if (tagClosing) { levelCurrent--; } else { @@ -1802,7 +1847,7 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int state = SCE_H_DEFAULT; } tagOpened = false; - if (!tagDontFold) { + if (!(foldXmlAtTagOpen || tagDontFold)) { if (tagClosing) { levelCurrent--; } else { @@ -1826,6 +1871,9 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int ch = chNext; state = SCE_H_DEFAULT; tagOpened = false; + if (foldXmlAtTagOpen) { + levelCurrent--; + } } else if (ch == '?' && chNext == '>') { styler.ColourTo(i - 1, StateToPrint); styler.ColourTo(i + 1, SCE_H_XMLEND); diff --git a/scintilla/lexers/LexHaskell.cxx b/scintilla/lexers/LexHaskell.cxx index bf81995483..93c670a0cd 100644 --- a/scintilla/lexers/LexHaskell.cxx +++ b/scintilla/lexers/LexHaskell.cxx @@ -390,7 +390,8 @@ class LexerHaskell : public DefaultLexer { public: LexerHaskell(bool literate_) - : literate(literate_) + : DefaultLexer(literate_ ? "literatehaskell" : "haskell", literate_ ? SCLEX_LITERATEHASKELL : SCLEX_HASKELL) + , literate(literate_) , firstImportLine(-1) , firstImportIndent(0) {} @@ -401,7 +402,7 @@ class LexerHaskell : public DefaultLexer { } int SCI_METHOD Version() const override { - return lvOriginal; + return lvIdentity; } const char * SCI_METHOD PropertyNames() override { @@ -418,6 +419,10 @@ class LexerHaskell : public DefaultLexer { Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override; + const char * SCI_METHOD PropertyGet(const char *key) override { + return osHaskell.PropertyGet(key); + } + const char * SCI_METHOD DescribeWordListSets() override { return osHaskell.DescribeWordListSets(); } diff --git a/scintilla/lexers/LexLaTeX.cxx b/scintilla/lexers/LexLaTeX.cxx index ed9e6a6b36..4b6cbdc6e2 100644 --- a/scintilla/lexers/LexLaTeX.cxx +++ b/scintilla/lexers/LexLaTeX.cxx @@ -26,6 +26,7 @@ #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" +#include "DefaultLexer.h" #include "LexerBase.h" using namespace Scintilla; @@ -39,6 +40,13 @@ struct latexFoldSave { latexFoldSave(const latexFoldSave &save) : structLev(save.structLev) { for (int i = 0; i < 8; ++i) openBegins[i] = save.openBegins[i]; } + latexFoldSave &operator=(const latexFoldSave &save) { + if (this != &save) { + structLev = save.structLev; + for (int i = 0; i < 8; ++i) openBegins[i] = save.openBegins[i]; + } + return *this; + } int openBegins[8]; Sci_Position structLev; }; @@ -81,6 +89,14 @@ class LexerLaTeX : public LexerBase { } void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override; void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override; + + // ILexerWithIdentity methods + const char * SCI_METHOD GetName() override { + return "latex"; + } + int SCI_METHOD GetIdentifier() override { + return SCLEX_LATEX; + } }; static bool latexIsSpecial(int ch) { @@ -289,6 +305,8 @@ void SCI_METHOD LexerLaTeX::Lex(Sci_PositionU startPos, Sci_Position length, int latexStateReset(mode, state); if (latexLastWordIs(i, styler, "{verbatim}")) { state = SCE_L_VERBATIM; + } else if (latexLastWordIs(i, styler, "{lstlisting}")) { + state = SCE_L_VERBATIM; } else if (latexLastWordIs(i, styler, "{comment}")) { state = SCE_L_COMMENT2; } else if (latexLastWordIs(i, styler, "{math}") && mode == 0) { @@ -437,6 +455,9 @@ void SCI_METHOD LexerLaTeX::Lex(Sci_PositionU startPos, Sci_Position length, int if (latexLastWordIs(match, styler, "{verbatim}")) { styler.ColourTo(i - 1, state); state = SCE_L_COMMAND; + } else if (latexLastWordIs(match, styler, "{lstlisting}")) { + styler.ColourTo(i - 1, state); + state = SCE_L_COMMAND; } } } diff --git a/scintilla/lexers/LexMatlab.cxx b/scintilla/lexers/LexMatlab.cxx index a36a995028..3d08c9a33e 100644 --- a/scintilla/lexers/LexMatlab.cxx +++ b/scintilla/lexers/LexMatlab.cxx @@ -155,7 +155,7 @@ static void ColouriseMatlabOctaveDoc( } else if (sc.state == SCE_MATLAB_KEYWORD) { if (!isalnum(sc.ch) && sc.ch != '_') { char s[100]; - sc.GetCurrentLowered(s, sizeof(s)); + sc.GetCurrent(s, sizeof(s)); if (keywords.InList(s)) { if (strcmp ("end", s) == 0 && allow_end_op) { diff --git a/scintilla/lexers/LexPerl.cxx b/scintilla/lexers/LexPerl.cxx index 3bf205f704..dab7eb6f37 100644 --- a/scintilla/lexers/LexPerl.cxx +++ b/scintilla/lexers/LexPerl.cxx @@ -37,6 +37,8 @@ using namespace Scintilla; // Following a << you specify a string to terminate the quoted material, and // all lines following the current line down to the terminating string are // the value of the item. +// Prefixing the terminating string with a "~" specifies that you want to +// use "Indented Here-docs" (see below). // * The terminating string may be either an identifier (a word), or some // quoted text. // * If quoted, the type of quotes you use determines the treatment of the @@ -48,6 +50,18 @@ using namespace Scintilla; // (This is deprecated, -w warns of this syntax) // * The terminating string must appear by itself (unquoted and // with no surrounding whitespace) on the terminating line. +// +// Indented Here-docs +// ------------------ +// The here-doc modifier "~" allows you to indent your here-docs to +// make the code more readable. +// The delimiter is used to determine the exact whitespace to remove +// from the beginning of each line. All lines must have at least the +// same starting whitespace (except lines only containing a newline) +// or perl will croak. Tabs and spaces can be mixed, but are matched +// exactly. One tab will not be equal to 8 spaces! +// Additional beginning whitespace (beyond what preceded the +// delimiter) will be preserved. #define HERE_DELIM_MAX 256 // maximum length of HERE doc delimiter @@ -409,6 +423,7 @@ class LexerPerl : public DefaultLexer { OptionSetPerl osPerl; public: LexerPerl() : + DefaultLexer("perl", SCLEX_PERL), setWordStart(CharacterSet::setAlpha, "_", 0x80, true), setWord(CharacterSet::setAlphaNum, "_", 0x80, true), setSpecialVar(CharacterSet::setNone, "\"$;<>&`'+,./\\%:=~!?@[]"), @@ -420,7 +435,7 @@ class LexerPerl : public DefaultLexer { delete this; } int SCI_METHOD Version() const override { - return lvOriginal; + return lvIdentity; } const char *SCI_METHOD PropertyNames() override { return osPerl.PropertyNames(); @@ -432,6 +447,9 @@ class LexerPerl : public DefaultLexer { return osPerl.DescribeProperty(name); } Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override; + const char * SCI_METHOD PropertyGet(const char *key) override { + return osPerl.PropertyGet(key); + } const char *SCI_METHOD DescribeWordListSets() override { return osPerl.DescribeWordListSets(); } @@ -619,12 +637,14 @@ void SCI_METHOD LexerPerl::Lex(Sci_PositionU startPos, Sci_Position length, int // 2: here doc text (lines after the delimiter) int Quote; // the char after '<<' bool Quoted; // true if Quote in ('\'','"','`') + bool StripIndent; // true if '<<~' requested to strip leading whitespace int DelimiterLength; // strlen(Delimiter) char Delimiter[HERE_DELIM_MAX]; // the Delimiter HereDocCls() { State = 0; Quote = 0; Quoted = false; + StripIndent = false; DelimiterLength = 0; Delimiter[0] = '\0'; } @@ -885,7 +905,7 @@ void SCI_METHOD LexerPerl::Lex(Sci_PositionU startPos, Sci_Position length, int sc.SetState(SCE_PL_DEFAULT); break; case SCE_PL_COMMENTLINE: - if (sc.atLineEnd) { + if (sc.atLineStart) { sc.SetState(SCE_PL_DEFAULT); } break; @@ -896,8 +916,14 @@ void SCI_METHOD LexerPerl::Lex(Sci_PositionU startPos, Sci_Position length, int HereDoc.State = 1; // pre-init HERE doc class HereDoc.Quote = sc.chNext; HereDoc.Quoted = false; + HereDoc.StripIndent = false; HereDoc.DelimiterLength = 0; HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0'; + if (delim_ch == '~') { // was actually '<<~' + sc.Forward(); + HereDoc.StripIndent = true; + HereDoc.Quote = delim_ch = sc.chNext; + } if (IsASpaceOrTab(delim_ch)) { // skip whitespace; legal only for quoted delimiters Sci_PositionU i = sc.currentPos + 1; @@ -964,6 +990,11 @@ void SCI_METHOD LexerPerl::Lex(Sci_PositionU startPos, Sci_Position length, int case SCE_PL_HERE_QX: // also implies HereDoc.State == 2 sc.Complete(); + if (HereDoc.StripIndent) { + // skip whitespace + while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd) + sc.Forward(); + } if (HereDoc.DelimiterLength == 0 || sc.Match(HereDoc.Delimiter)) { int c = sc.GetRelative(HereDoc.DelimiterLength); if (c == '\r' || c == '\n') { // peek first, do not consume match @@ -1701,6 +1732,12 @@ void SCI_METHOD LexerPerl::Fold(Sci_PositionU startPos, Sci_Position length, int } else if (ch == ']') { levelCurrent--; } + } else if (style == SCE_PL_STRING_QW) { + // qw + if (stylePrevCh != style) + levelCurrent++; + else if (styleNext != style) + levelCurrent--; } // POD folding if (options.foldPOD && atLineStart) { diff --git a/scintilla/lexers/LexProps.cxx b/scintilla/lexers/LexProps.cxx index 1aebdbb066..328033dd51 100644 --- a/scintilla/lexers/LexProps.cxx +++ b/scintilla/lexers/LexProps.cxx @@ -12,6 +12,8 @@ #include #include +#include + #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" @@ -79,10 +81,9 @@ static void ColourisePropsLine( } static void ColourisePropsDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) { - char lineBuffer[1024]; + std::string lineBuffer; styler.StartAt(startPos); styler.StartSegment(startPos); - Sci_PositionU linePos = 0; Sci_PositionU startLine = startPos; // property lexer.props.allow.initial.spaces @@ -92,17 +93,16 @@ static void ColourisePropsDoc(Sci_PositionU startPos, Sci_Position length, int, const bool allowInitialSpaces = styler.GetPropertyInt("lexer.props.allow.initial.spaces", 1) != 0; for (Sci_PositionU i = startPos; i < startPos + length; i++) { - lineBuffer[linePos++] = styler[i]; - if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) { + lineBuffer.push_back(styler[i]); + if (AtEOL(styler, i)) { // End of line (or of line buffer) met, colourise it - lineBuffer[linePos] = '\0'; - ColourisePropsLine(lineBuffer, linePos, startLine, i, styler, allowInitialSpaces); - linePos = 0; + ColourisePropsLine(lineBuffer.c_str(), lineBuffer.length(), startLine, i, styler, allowInitialSpaces); + lineBuffer.clear(); startLine = i + 1; } } - if (linePos > 0) { // Last line does not have ending characters - ColourisePropsLine(lineBuffer, linePos, startLine, startPos + length - 1, styler, allowInitialSpaces); + if (lineBuffer.length() > 0) { // Last line does not have ending characters + ColourisePropsLine(lineBuffer.c_str(), lineBuffer.length(), startLine, startPos + length - 1, styler, allowInitialSpaces); } } diff --git a/scintilla/lexers/LexPython.cxx b/scintilla/lexers/LexPython.cxx index 6cfb03b5ed..ec19149f8f 100644 --- a/scintilla/lexers/LexPython.cxx +++ b/scintilla/lexers/LexPython.cxx @@ -5,12 +5,9 @@ // Copyright 1998-2002 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. -#include -#include -#include -#include -#include -#include +#include +#include +#include #include #include @@ -65,20 +62,20 @@ enum kwType { kwOther, kwClass, kwDef, kwImport, kwCDef, kwCTypeName, kwCPDef }; enum literalsAllowed { litNone = 0, litU = 1, litB = 2, litF = 4 }; -const int indicatorWhitespace = 1; +constexpr int indicatorWhitespace = 1; bool IsPyComment(Accessor &styler, Sci_Position pos, Sci_Position len) { return len > 0 && styler[pos] == '#'; } -bool IsPyStringTypeChar(int ch, literalsAllowed allowed) { +bool IsPyStringTypeChar(int ch, literalsAllowed allowed) noexcept { return ((allowed & litB) && (ch == 'b' || ch == 'B')) || ((allowed & litU) && (ch == 'u' || ch == 'U')) || ((allowed & litF) && (ch == 'f' || ch == 'F')); } -bool IsPyStringStart(int ch, int chNext, int chNext2, literalsAllowed allowed) { +bool IsPyStringStart(int ch, int chNext, int chNext2, literalsAllowed allowed) noexcept { if (ch == '\'' || ch == '"') return true; if (IsPyStringTypeChar(ch, allowed)) { @@ -93,22 +90,22 @@ bool IsPyStringStart(int ch, int chNext, int chNext2, literalsAllowed allowed) { return false; } -bool IsPyFStringState(int st) { +bool IsPyFStringState(int st) noexcept { return ((st == SCE_P_FCHARACTER) || (st == SCE_P_FSTRING) || (st == SCE_P_FTRIPLE) || (st == SCE_P_FTRIPLEDOUBLE)); } -bool IsPySingleQuoteStringState(int st) { +bool IsPySingleQuoteStringState(int st) noexcept { return ((st == SCE_P_CHARACTER) || (st == SCE_P_STRING) || (st == SCE_P_FCHARACTER) || (st == SCE_P_FSTRING)); } -bool IsPyTripleQuoteStringState(int st) { +bool IsPyTripleQuoteStringState(int st) noexcept { return ((st == SCE_P_TRIPLE) || (st == SCE_P_TRIPLEDOUBLE) || (st == SCE_P_FTRIPLE) || (st == SCE_P_FTRIPLEDOUBLE)); } -char GetPyStringQuoteChar(int st) { +char GetPyStringQuoteChar(int st) noexcept { if ((st == SCE_P_CHARACTER) || (st == SCE_P_FCHARACTER) || (st == SCE_P_TRIPLE) || (st == SCE_P_FTRIPLE)) return '\''; @@ -126,7 +123,7 @@ void PushStateToStack(int state, std::vector &stack, Sing currentFStringExp = &stack.back(); } -int PopFromStateStack(std::vector &stack, SingleFStringExpState *¤tFStringExp) { +int PopFromStateStack(std::vector &stack, SingleFStringExpState *¤tFStringExp) noexcept { int state = 0; if (!stack.empty()) { @@ -135,7 +132,7 @@ int PopFromStateStack(std::vector &stack, SingleFStringEx } if (stack.empty()) { - currentFStringExp = NULL; + currentFStringExp = nullptr; } else { currentFStringExp = &stack.back(); } @@ -186,30 +183,30 @@ int GetPyStringState(Accessor &styler, Sci_Position i, Sci_PositionU *nextIndex, } inline bool IsAWordChar(int ch, bool unicodeIdentifiers) { - if (ch < 0x80) - return (isalnum(ch) || ch == '.' || ch == '_'); + if (IsASCII(ch)) + return (IsAlphaNumeric(ch) || ch == '.' || ch == '_'); if (!unicodeIdentifiers) return false; - // Python uses the XID_Continue set from unicode data + // Python uses the XID_Continue set from Unicode data return IsXidContinue(ch); } inline bool IsAWordStart(int ch, bool unicodeIdentifiers) { - if (ch < 0x80) - return (isalpha(ch) || ch == '_'); + if (IsASCII(ch)) + return (IsUpperOrLowerCase(ch) || ch == '_'); if (!unicodeIdentifiers) return false; - // Python uses the XID_Start set from unicode data + // Python uses the XID_Start set from Unicode data return IsXidStart(ch); } -static bool IsFirstNonWhitespace(Sci_Position pos, Accessor &styler) { - Sci_Position line = styler.GetLine(pos); - Sci_Position start_pos = styler.LineStart(line); +bool IsFirstNonWhitespace(Sci_Position pos, Accessor &styler) { + const Sci_Position line = styler.GetLine(pos); + const Sci_Position start_pos = styler.LineStart(line); for (Sci_Position i = start_pos; i < pos; i++) { const char ch = styler[i]; if (!(ch == ' ' || ch == '\t')) @@ -246,7 +243,7 @@ struct OptionsPython { unicodeIdentifiers = true; } - literalsAllowed AllowedLiterals() const { + literalsAllowed AllowedLiterals() const noexcept { literalsAllowed allowedLiterals = stringsU ? litU : litNone; if (stringsB) allowedLiterals = static_cast(allowedLiterals | litB); @@ -256,10 +253,10 @@ struct OptionsPython { } }; -static const char *const pythonWordListDesc[] = { +const char *const pythonWordListDesc[] = { "Keywords", "Highlighted identifiers", - 0 + nullptr }; struct OptionSetPython : public OptionSet { @@ -300,7 +297,7 @@ struct OptionSetPython : public OptionSet { DefineProperty("fold.compact", &OptionsPython::foldCompact); DefineProperty("lexer.python.unicode.identifiers", &OptionsPython::unicodeIdentifiers, - "Set to 0 to not recognise Python 3 unicode identifiers."); + "Set to 0 to not recognise Python 3 Unicode identifiers."); DefineWordListSets(pythonWordListDesc); } @@ -344,7 +341,7 @@ class LexerPython : public DefaultLexer { std::map > ftripleStateAtEol; public: explicit LexerPython() : - DefaultLexer(lexicalClasses, ELEMENTS(lexicalClasses)), + DefaultLexer("python", SCLEX_PYTHON, lexicalClasses, ELEMENTS(lexicalClasses)), subStyles(styleSubable, 0x80, 0x40, 0) { } ~LexerPython() override { @@ -353,7 +350,7 @@ class LexerPython : public DefaultLexer { delete this; } int SCI_METHOD Version() const override { - return lvSubStyles; + return lvIdentity; } const char *SCI_METHOD PropertyNames() override { return osPython.PropertyNames(); @@ -365,6 +362,9 @@ class LexerPython : public DefaultLexer { return osPython.DescribeProperty(name); } Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override; + const char * SCI_METHOD PropertyGet(const char *key) override { + return osPython.PropertyGet(key); + } const char *SCI_METHOD DescribeWordListSets() override { return osPython.DescribeWordListSets(); } @@ -373,7 +373,7 @@ class LexerPython : public DefaultLexer { void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override; void *SCI_METHOD PrivateCall(int, void *) override { - return 0; + return nullptr; } int SCI_METHOD LineEndTypesSupported() override { @@ -425,7 +425,7 @@ Sci_Position SCI_METHOD LexerPython::PropertySet(const char *key, const char *va } Sci_Position SCI_METHOD LexerPython::WordListSet(int n, const char *wl) { - WordList *wordListN = 0; + WordList *wordListN = nullptr; switch (n) { case 0: wordListN = &keywords; @@ -489,12 +489,12 @@ void LexerPython::ProcessLineEnd(StyleContext &sc, std::vector fstringStateStack; - SingleFStringExpState *currentFStringExp = NULL; + SingleFStringExpState *currentFStringExp = nullptr; const Sci_Position endPos = startPos + length; @@ -505,7 +505,7 @@ void SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, in lineCurrent--; // Look for backslash-continued lines while (lineCurrent > 0) { - Sci_Position eolPos = styler.LineStart(lineCurrent) - 1; + const Sci_Position eolPos = styler.LineStart(lineCurrent) - 1; const int eolStyle = styler.StyleAt(eolPos); if (eolStyle == SCE_P_STRING || eolStyle == SCE_P_CHARACTER @@ -625,7 +625,7 @@ void SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, in // We don't want to highlight keywords2 // that are used as a sub-identifier, // i.e. not open in "foo.open". - Sci_Position pos = styler.GetStartSegment() - 1; + const Sci_Position pos = styler.GetStartSegment() - 1; if (pos < 0 || (styler.SafeGetCharAt(pos, '\0') != '.')) style = SCE_P_WORD2; } else { @@ -767,7 +767,7 @@ void SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, in } // If in f-string expression, check for }, :, ! to resume f-string state or update nesting count - if (currentFStringExp != NULL && !IsPySingleQuoteStringState(sc.state) && !IsPyTripleQuoteStringState(sc.state)) { + if (currentFStringExp && !IsPySingleQuoteStringState(sc.state) && !IsPyTripleQuoteStringState(sc.state)) { if (currentFStringExp->nestingCount == 0 && (sc.ch == '}' || sc.ch == ':' || (sc.ch == '!' && sc.chNext != '='))) { sc.SetState(PopFromStateStack(fstringStateStack, currentFStringExp)); } else { @@ -798,7 +798,7 @@ void SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, in base_n_number = false; sc.SetState(SCE_P_NUMBER); } - } else if ((IsASCII(sc.ch) && isoperator(static_cast(sc.ch))) || sc.ch == '`') { + } else if (isoperator(sc.ch) || sc.ch == '`') { sc.SetState(SCE_P_OPERATOR); } else if (sc.ch == '#') { sc.SetState(sc.chNext == '#' ? SCE_P_COMMENTBLOCK : SCE_P_COMMENTLINE); @@ -823,7 +823,7 @@ void SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, in } static bool IsCommentLine(Sci_Position line, Accessor &styler) { - Sci_Position pos = styler.LineStart(line); + const Sci_Position pos = styler.LineStart(line); const Sci_Position eol_pos = styler.LineStart(line + 1) - 1; for (Sci_Position i = pos; i < eol_pos; i++) { const char ch = styler[i]; @@ -845,7 +845,7 @@ void SCI_METHOD LexerPython::Fold(Sci_PositionU startPos, Sci_Position length, i if (!options.fold) return; - Accessor styler(pAccess, NULL); + Accessor styler(pAccess, nullptr); const Sci_Position maxPos = startPos + length; const Sci_Position maxLines = (maxPos == styler.Length()) ? styler.GetLine(maxPos) : styler.GetLine(maxPos - 1); // Requested last line @@ -857,10 +857,10 @@ void SCI_METHOD LexerPython::Fold(Sci_PositionU startPos, Sci_Position length, i // at least one line in all cases) int spaceFlags = 0; Sci_Position lineCurrent = styler.GetLine(startPos); - int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL); + int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, nullptr); while (lineCurrent > 0) { lineCurrent--; - indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL); + indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, nullptr); if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG) && (!IsCommentLine(lineCurrent, styler)) && (!IsQuoteLine(lineCurrent, styler))) @@ -887,8 +887,8 @@ void SCI_METHOD LexerPython::Fold(Sci_PositionU startPos, Sci_Position length, i int quote = false; if (lineNext <= docLines) { // Information about next line is only available if not at end of document - indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL); - Sci_Position lookAtPos = (styler.LineStart(lineNext) == styler.Length()) ? styler.Length() - 1 : styler.LineStart(lineNext); + indentNext = styler.IndentAmount(lineNext, &spaceFlags, nullptr); + const Sci_Position lookAtPos = (styler.LineStart(lineNext) == styler.Length()) ? styler.Length() - 1 : styler.LineStart(lineNext); const int style = styler.StyleAt(lookAtPos) & 31; quote = options.foldQuotes && IsPyTripleQuoteStringState(style); } @@ -926,7 +926,7 @@ void SCI_METHOD LexerPython::Fold(Sci_PositionU startPos, Sci_Position length, i } lineNext++; - indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL); + indentNext = styler.IndentAmount(lineNext, &spaceFlags, nullptr); } const int levelAfterComments = ((lineNext < docLines) ? indentNext & SC_FOLDLEVELNUMBERMASK : minCommentLevel); @@ -941,13 +941,13 @@ void SCI_METHOD LexerPython::Fold(Sci_PositionU startPos, Sci_Position length, i int skipLevel = levelAfterComments; while (--skipLine > lineCurrent) { - const int skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, NULL); + const int skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, nullptr); if (options.foldCompact) { if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments) skipLevel = levelBeforeComments; - int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG; + const int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG; styler.SetLevel(skipLine, skipLevel | whiteFlag); } else { diff --git a/scintilla/lexers/LexR.cxx b/scintilla/lexers/LexR.cxx index ead0dba18c..a3821fa3c7 100644 --- a/scintilla/lexers/LexR.cxx +++ b/scintilla/lexers/LexR.cxx @@ -1,5 +1,5 @@ // Scintilla source code edit control -/** @file Lexr.cxx +/** @file LexR.cxx ** Lexer for R, S, SPlus Statistics Program (Heavily derived from CPP Lexer). ** **/ diff --git a/scintilla/lexers/LexRuby.cxx b/scintilla/lexers/LexRuby.cxx index 2affffe65f..6f7c344048 100644 --- a/scintilla/lexers/LexRuby.cxx +++ b/scintilla/lexers/LexRuby.cxx @@ -562,7 +562,7 @@ static bool sureThisIsNotHeredoc(Sci_Position lt2StartPos, bool allow_indent; Sci_Position target_start, target_end; // From this point on no more styling, since we're looking ahead - if (styler[j] == '-') { + if (styler[j] == '-' || styler[j] == '~') { allow_indent = true; j++; } else { @@ -888,7 +888,7 @@ static void ColouriseRbDoc(Sci_PositionU startPos, Sci_Position length, int init chNext = chNext2; styler.ColourTo(i, SCE_RB_OPERATOR); - if (!(strchr("\"\'`_-", chNext2) || isSafeAlpha(chNext2))) { + if (!(strchr("\"\'`_-~", chNext2) || isSafeAlpha(chNext2))) { // It's definitely not a here-doc, // based on Ruby's lexer/parser in the // heredoc_identifier routine. @@ -1234,7 +1234,7 @@ static void ColouriseRbDoc(Sci_PositionU startPos, Sci_Position length, int init if (HereDoc.State == 0) { // '<<' encountered HereDoc.State = 1; HereDoc.DelimiterLength = 0; - if (ch == '-') { + if (ch == '-' || ch == '~') { HereDoc.CanBeIndented = true; advance_char(i, ch, chNext, chNext2); // pass by ref } else { diff --git a/scintilla/lexers/LexRust.cxx b/scintilla/lexers/LexRust.cxx index a866203db8..f0360b605b 100644 --- a/scintilla/lexers/LexRust.cxx +++ b/scintilla/lexers/LexRust.cxx @@ -120,13 +120,15 @@ class LexerRust : public DefaultLexer { OptionsRust options; OptionSetRust osRust; public: + LexerRust() : DefaultLexer("rust", SCLEX_RUST) { + } virtual ~LexerRust() { } void SCI_METHOD Release() override { delete this; } int SCI_METHOD Version() const override { - return lvOriginal; + return lvIdentity; } const char * SCI_METHOD PropertyNames() override { return osRust.PropertyNames(); @@ -138,6 +140,9 @@ class LexerRust : public DefaultLexer { return osRust.DescribeProperty(name); } Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override; + const char * SCI_METHOD PropertyGet(const char *key) override { + return osRust.PropertyGet(key); + } const char * SCI_METHOD DescribeWordListSets() override { return osRust.DescribeWordListSets(); } diff --git a/scintilla/lexers/LexSQL.cxx b/scintilla/lexers/LexSQL.cxx index aeb7f4772c..87b852bfde 100644 --- a/scintilla/lexers/LexSQL.cxx +++ b/scintilla/lexers/LexSQL.cxx @@ -303,12 +303,12 @@ struct OptionSetSQL : public OptionSet { class LexerSQL : public DefaultLexer { public : - LexerSQL() {} + LexerSQL() : DefaultLexer("sql", SCLEX_SQL) {} virtual ~LexerSQL() {} int SCI_METHOD Version () const override { - return lvOriginal; + return lvIdentity; } void SCI_METHOD Release() override { @@ -334,13 +334,17 @@ public : return -1; } + const char * SCI_METHOD PropertyGet(const char *key) override { + return osSQL.PropertyGet(key); + } + const char * SCI_METHOD DescribeWordListSets() override { return osSQL.DescribeWordListSets(); } Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override; - void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) override; - void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) override; + void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override; + void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override; void * SCI_METHOD PrivateCall(int, void *) override { return 0; @@ -442,9 +446,8 @@ void SCI_METHOD LexerSQL::Lex(Sci_PositionU startPos, Sci_Position length, int i LexAccessor styler(pAccess); StyleContext sc(startPos, length, initStyle, styler); int styleBeforeDCKeyword = SCE_SQL_DEFAULT; - Sci_Position offset = 0; - for (; sc.More(); sc.Forward(), offset++) { + for (; sc.More(); sc.Forward()) { // Determine if the current state should terminate. switch (sc.state) { case SCE_SQL_OPERATOR: @@ -537,7 +540,7 @@ void SCI_METHOD LexerSQL::Lex(Sci_PositionU startPos, Sci_Position length, int i if (options.sqlBackslashEscapes && sc.ch == '\\') { sc.Forward(); } else if (sc.ch == '\'') { - if (sc.chNext == '\"') { + if (sc.chNext == '\'') { sc.Forward(); } else { sc.ForwardSetState(SCE_SQL_DEFAULT); diff --git a/scintilla/lexers/LexTCL.cxx b/scintilla/lexers/LexTCL.cxx index 1ea6ecf6e8..5c73fb52ef 100644 --- a/scintilla/lexers/LexTCL.cxx +++ b/scintilla/lexers/LexTCL.cxx @@ -45,7 +45,8 @@ static inline bool IsANumberChar(int ch) { static void ColouriseTCLDoc(Sci_PositionU startPos, Sci_Position length, int , WordList *keywordlists[], Accessor &styler) { #define isComment(s) (s==SCE_TCL_COMMENT || s==SCE_TCL_COMMENTLINE || s==SCE_TCL_COMMENT_BOX || s==SCE_TCL_BLOCK_COMMENT) - bool foldComment = styler.GetPropertyInt("fold.comment") != 0; + const bool foldComment = styler.GetPropertyInt("fold.comment") != 0; + const bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; bool commentLevel = false; bool subBrace = false; // substitution begin with a brace ${.....} enum tLineState {LS_DEFAULT, LS_OPEN_COMMENT, LS_OPEN_DOUBLE_QUOTE, LS_COMMENT_BOX, LS_MASK_STATE = 0xf, @@ -199,7 +200,7 @@ static void ColouriseTCLDoc(Sci_PositionU startPos, Sci_Position length, int , W } } int flag = 0; - if (!visibleChars) + if (!visibleChars && foldCompact) flag = SC_FOLDLEVELWHITEFLAG; if (currentLevel > previousLevel) flag = SC_FOLDLEVELHEADERFLAG; diff --git a/scintilla/lexers/LexVHDL.cxx b/scintilla/lexers/LexVHDL.cxx index 92b18269b6..a1426c815a 100644 --- a/scintilla/lexers/LexVHDL.cxx +++ b/scintilla/lexers/LexVHDL.cxx @@ -252,8 +252,8 @@ static void FoldNoBoxVHDLDoc( if(lineCurrent > 0) levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; //int levelMinCurrent = levelCurrent; - int levelMinCurrentElse = levelCurrent; //< Used for folding at 'else' - int levelMinCurrentBegin = levelCurrent; //< Used for folding at 'begin' + int levelMinCurrentElse = levelCurrent; ///< Used for folding at 'else' + int levelMinCurrentBegin = levelCurrent; ///< Used for folding at 'begin' int levelNext = levelCurrent; /***************************************/ diff --git a/scintilla/lexers/LexVerilog.cxx b/scintilla/lexers/LexVerilog.cxx index 3dc2ac1ef0..d31425e3f7 100644 --- a/scintilla/lexers/LexVerilog.cxx +++ b/scintilla/lexers/LexVerilog.cxx @@ -216,12 +216,13 @@ class LexerVerilog : public DefaultLexer { public: LexerVerilog() : + DefaultLexer("verilog", SCLEX_VERILOG), setWord(CharacterSet::setAlphaNum, "._", 0x80, true), subStyles(styleSubable, 0x80, 0x40, activeFlag) { } virtual ~LexerVerilog() {} int SCI_METHOD Version() const override { - return lvSubStyles; + return lvIdentity; } void SCI_METHOD Release() override { delete this; @@ -238,6 +239,9 @@ class LexerVerilog : public DefaultLexer { Sci_Position SCI_METHOD PropertySet(const char* key, const char* val) override { return osVerilog.PropertySet(&options, key, val); } + const char * SCI_METHOD PropertyGet(const char *key) override { + return osVerilog.PropertyGet(key); + } const char* SCI_METHOD DescribeWordListSets() override { return osVerilog.DescribeWordListSets(); } diff --git a/scintilla/lexlib/CatalogueModules.h b/scintilla/lexlib/CatalogueModules.h new file mode 100644 index 0000000000..b290a74ea2 --- /dev/null +++ b/scintilla/lexlib/CatalogueModules.h @@ -0,0 +1,70 @@ +// Scintilla source code edit control +/** @file CatalogueModules.h + ** Lexer infrastructure. + ** Contains a list of LexerModules which can be searched to find a module appropriate for a + ** particular language. + **/ +// Copyright 1998-2010 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#ifndef CATALOGUEMODULES_H +#define CATALOGUEMODULES_H + +namespace Scintilla { + +class CatalogueModules { + std::vector lexerCatalogue; +public: + const LexerModule *Find(int language) const { + for (const LexerModule *lm : lexerCatalogue) { + if (lm->GetLanguage() == language) { + return lm; + } + } + return nullptr; + } + + const LexerModule *Find(const char *languageName) const noexcept { + if (languageName) { + for (const LexerModule *lm : lexerCatalogue) { + if (lm->languageName && (0 == strcmp(lm->languageName, languageName))) { + return lm; + } + } + } + return nullptr; + } + + void AddLexerModule(LexerModule *plm) { + lexerCatalogue.push_back(plm); + } + + unsigned int Count() const noexcept { + return static_cast(lexerCatalogue.size()); + } + + const char *Name(unsigned int index) const noexcept { + if (index < static_cast(lexerCatalogue.size())) { + return lexerCatalogue[index]->languageName; + } else { + return ""; + } + } + + LexerFactoryFunction Factory(unsigned int index) const noexcept { + // Works for object lexers but not for function lexers + return lexerCatalogue[index]->fnFactory; + } + + ILexer *Create(unsigned int index) const { + const LexerModule *plm = lexerCatalogue[index]; + if (!plm) { + return nullptr; + } + return plm->Create(); + } +}; + +} + +#endif diff --git a/scintilla/lexlib/CharacterCategory.cxx b/scintilla/lexlib/CharacterCategory.cxx index 19c44cabe2..6dc22e21fa 100644 --- a/scintilla/lexlib/CharacterCategory.cxx +++ b/scintilla/lexlib/CharacterCategory.cxx @@ -11,9 +11,9 @@ #include #include -#include "Scintilla.h" // for ptrdiff_t in Position.h #include "CharacterCategory.h" -#include "Position.h" // for Sci::clamp + +#include "Compat.h" namespace Scintilla { @@ -22,7 +22,7 @@ namespace { const int catRanges[] = { //++Autogenerated -- start of section automatically generated -// Created with Python 3.7.0, Unicode 11.0.0 +// Created with Python 3.8.0, Unicode 12.1.0 25, 1046, 1073, @@ -1005,6 +1005,7 @@ const int catRanges[] = { 101533, 101576, 101917, +102129, 102154, 102389, 102404, @@ -1118,30 +1119,16 @@ const int catRanges[] = { 118909, 118916, 118973, -119012, -119101, -119108, +118980, 119165, -119204, -119261, -119428, -119581, -119588, -119837, -119844, +119172, 119965, 119972, 120029, 120036, -120093, -120132, -120221, -120228, 120357, 120388, 120453, -120669, -120677, 120740, 120797, 120836, @@ -1288,7 +1275,8 @@ const int catRanges[] = { 163805, 163852, 163876, -183729, +183733, +183761, 183780, 184342, 184356, @@ -1487,12 +1475,12 @@ const int catRanges[] = { 236836, 236965, 236996, -237126, 237189, 237220, 237286, 237317, -237405, +237380, +237437, 237569, 238979, 240993, @@ -2042,9 +2030,6 @@ const int catRanges[] = { 356053, 357085, 357141, -358717, -358741, -360445, 360448, 361981, 361985, @@ -2247,7 +2232,7 @@ const int catRanges[] = { 378929, 378957, 378993, -379389, +379421, 380949, 381789, 381813, @@ -2333,8 +2318,6 @@ const int catRanges[] = { 414037, 415274, 415765, -417789, -417813, 425988, 636637, 636949, @@ -2578,7 +2561,17 @@ const int catRanges[] = { 1373921, 1373952, 1373985, -1374045, +1374016, +1374049, +1374080, +1374113, +1374144, +1374177, +1374237, +1374272, +1374305, +1374336, +1374461, 1375972, 1376003, 1376065, @@ -2636,7 +2629,7 @@ const int catRanges[] = { 1390277, 1390406, 1390469, -1390502, +1390534, 1390641, 1391069, 1391075, @@ -2713,7 +2706,7 @@ const int catRanges[] = { 1403764, 1403779, 1403905, -1404125, +1404189, 1404417, 1406980, 1408102, @@ -3080,6 +3073,8 @@ const int catRanges[] = { 2222634, 2222769, 2222941, +2227204, +2227965, 2228230, 2228261, 2228294, @@ -3223,7 +3218,8 @@ const int catRanges[] = { 2263965, 2263985, 2264005, -2264061, +2264036, +2264093, 2265092, 2266630, 2266725, @@ -3273,7 +3269,8 @@ const int catRanges[] = { 2283013, 2283206, 2283237, -2283293, +2283268, +2283325, 2283528, 2283869, 2285572, @@ -3303,6 +3300,20 @@ const int catRanges[] = { 2301565, 2301924, 2301981, +2307076, +2307357, +2307396, +2308646, +2308741, +2308893, +2308933, +2308998, +2309125, +2309156, +2309201, +2309220, +2309254, +2309309, 2310148, 2310181, 2310500, @@ -3318,8 +3329,6 @@ const int catRanges[] = { 2312934, 2312997, 2313092, -2314397, -2314436, 2314565, 2314982, 2315013, @@ -3395,6 +3404,12 @@ const int catRanges[] = { 2350758, 2350833, 2350909, +2357258, +2357941, +2358195, +2358325, +2358877, +2359281, 2359300, 2388829, 2392073, @@ -3405,6 +3420,8 @@ const int catRanges[] = { 2402461, 2490372, 2524669, +2524698, +2524989, 2654212, 2672893, 2949124, @@ -3442,21 +3459,28 @@ const int catRanges[] = { 3003121, 3003261, 3006468, -3008701, +3008893, +3008997, 3009028, 3009062, -3010557, +3010845, 3011045, 3011171, 3011613, 3013635, -3013725, +3013713, +3013731, +3013789, 3014660, -3210845, +3211037, 3211268, 3235453, 3538948, 3548157, +3549700, +3549821, +3550340, +3550493, 3550724, 3563421, 3637252, @@ -3614,6 +3638,22 @@ const int catRanges[] = { 3933373, 3933381, 3933565, +3940356, +3941821, +3941893, +3942115, +3942365, +3942408, +3942749, +3942852, +3942901, +3942941, +3954692, +3956101, +3956232, +3956573, +3956723, +3956765, 3997700, 4004029, 4004074, @@ -3622,7 +3662,8 @@ const int catRanges[] = { 4005888, 4006977, 4008069, -4008317, +4008291, +4008349, 4008456, 4008797, 4008913, @@ -3633,6 +3674,10 @@ const int catRanges[] = { 4036115, 4036138, 4036285, +4038698, +4040149, +4040170, +4040669, 4046852, 4047005, 4047012, @@ -3716,7 +3761,7 @@ const int catRanges[] = { 4071434, 4071869, 4071957, -4074909, +4074941, 4075029, 4076989, 4078805, @@ -3732,15 +3777,17 @@ const int catRanges[] = { 4087829, 4095860, 4096021, -4119229, +4119261, 4119573, 4119997, 4120085, -4120413, +4120445, 4120597, 4124317, 4124693, 4127549, +4127765, +4128157, 4128789, 4129181, 4129301, @@ -3753,24 +3800,28 @@ const int catRanges[] = { 4134365, 4136981, 4137373, -4137493, -4139005, -4139029, -4140605, +4137397, +4140637, 4140661, 4140797, 4140885, -4140925, -4140949, 4142205, -4142613, -4142941, -4143125, -4143229, -4143637, -4145181, +4142261, +4142461, +4142549, +4143485, +4143541, +4147869, 4148245, 4148701, +4148757, +4148893, +4149013, +4149117, +4149269, +4149373, +4149781, +4149981, 4194308, 5561085, 5562372, @@ -3797,8 +3848,8 @@ const int catRanges[] = { //--Autogenerated -- end of section automatically generated }; -const int maxUnicode = 0x10ffff; -const int maskCategory = 0x1F; +constexpr int maxUnicode = 0x10ffff; +constexpr int maskCategory = 0x1F; } @@ -3831,7 +3882,7 @@ enum class OtherID { oidNone, oidStart, oidContinue }; // Some characters are treated as valid for identifiers even // though most characters from their category are not. // Values copied from http://www.unicode.org/Public/9.0.0/ucd/PropList.txt -OtherID OtherIDOfCharacter(int character) { +OtherID OtherIDOfCharacter(int character) noexcept { if ( (character == 0x1885) || // MONGOLIAN LETTER ALI GALI BALUDA (character == 0x1886) || // MONGOLIAN LETTER ALI GALI THREE BALUDA @@ -3855,11 +3906,11 @@ OtherID OtherIDOfCharacter(int character) { // Pattern_Syntax|Pattern_White_Space. // As of Unicode 9, only VERTICAL TILDE which is in Lm and has Pattern_Syntax matches. // Should really generate from PropList.txt a list of Pattern_Syntax and Pattern_White_Space. -bool IsIdPattern(int character) { +constexpr bool IsIdPattern(int character) noexcept { return character == 0x2E2F; } -bool OmitXidStart(int character) { +bool OmitXidStart(int character) noexcept { switch (character) { case 0x037A: // GREEK YPOGEGRAMMENI case 0x0E33: // THAI CHARACTER SARA AM @@ -3890,7 +3941,7 @@ bool OmitXidStart(int character) { } } -bool OmitXidContinue(int character) { +bool OmitXidContinue(int character) noexcept { switch (character) { case 0x037A: // GREEK YPOGEGRAMMENI case 0x309B: // KATAKANA-HIRAGANA VOICED SOUND MARK @@ -3967,7 +4018,7 @@ bool IsXidContinue(int character) { } } -CharacterCategoryMap::CharacterCategoryMap() noexcept { +CharacterCategoryMap::CharacterCategoryMap() { Optimize(256); } diff --git a/scintilla/lexlib/CharacterCategory.h b/scintilla/lexlib/CharacterCategory.h index d1ac391526..cd3320dd9f 100644 --- a/scintilla/lexlib/CharacterCategory.h +++ b/scintilla/lexlib/CharacterCategory.h @@ -32,7 +32,7 @@ class CharacterCategoryMap { private: std::vector dense; public: - CharacterCategoryMap() noexcept; + CharacterCategoryMap(); CharacterCategory CategoryFor(int character) const { if (static_cast(character) < dense.size()) { return static_cast(dense[character]); diff --git a/scintilla/lexlib/CharacterSet.cxx b/scintilla/lexlib/CharacterSet.cxx index 2a1dabc1c6..b934c2dd4f 100644 --- a/scintilla/lexlib/CharacterSet.cxx +++ b/scintilla/lexlib/CharacterSet.cxx @@ -15,7 +15,7 @@ using namespace Scintilla; namespace Scintilla { -int CompareCaseInsensitive(const char *a, const char *b) { +int CompareCaseInsensitive(const char *a, const char *b) noexcept { while (*a && *b) { if (*a != *b) { const char upperA = MakeUpperCase(*a); @@ -30,7 +30,7 @@ int CompareCaseInsensitive(const char *a, const char *b) { return *a - *b; } -int CompareNCaseInsensitive(const char *a, const char *b, size_t len) { +int CompareNCaseInsensitive(const char *a, const char *b, size_t len) noexcept { while (*a && *b && len) { if (*a != *b) { const char upperA = MakeUpperCase(*a); diff --git a/scintilla/lexlib/CharacterSet.h b/scintilla/lexlib/CharacterSet.h index 358f6bed3f..4a30ca0f07 100644 --- a/scintilla/lexlib/CharacterSet.h +++ b/scintilla/lexlib/CharacterSet.h @@ -46,7 +46,27 @@ class CharacterSet { bset[i] = other.bset[i]; } } - CharacterSet &operator=(CharacterSet &&other) { + CharacterSet(CharacterSet &&other) noexcept { + size = other.size; + valueAfter = other.valueAfter; + bset = other.bset; + other.size = 0; + other.bset = nullptr; + } + CharacterSet &operator=(const CharacterSet &other) { + if (this != &other) { + bool *bsetNew = new bool[other.size]; + for (int i = 0; i < other.size; i++) { + bsetNew[i] = other.bset[i]; + } + delete[]bset; + size = other.size; + valueAfter = other.valueAfter; + bset = bsetNew; + } + return *this; + } + CharacterSet &operator=(CharacterSet &&other) noexcept { if (this != &other) { delete []bset; size = other.size; @@ -62,19 +82,6 @@ class CharacterSet { bset = nullptr; size = 0; } - CharacterSet &operator=(const CharacterSet &other) { - if (this != &other) { - bool *bsetNew = new bool[other.size]; - for (int i=0; i < other.size; i++) { - bsetNew[i] = other.bset[i]; - } - delete []bset; - size = other.size; - valueAfter = other.valueAfter; - bset = bsetNew; - } - return *this; - } void Add(int val) { assert(val >= 0); assert(val < size); @@ -87,12 +94,12 @@ class CharacterSet { bset[uch] = true; } } - bool Contains(int val) const { + bool Contains(int val) const noexcept { assert(val >= 0); if (val < 0) return false; return (val < size) ? bset[val] : valueAfter; } - bool Contains(char ch) const { + bool Contains(char ch) const noexcept { // Overload char as char may be signed const unsigned char uch = ch; return Contains(uch); @@ -101,19 +108,19 @@ class CharacterSet { // Functions for classifying characters -inline bool IsASpace(int ch) { +constexpr bool IsASpace(int ch) noexcept { return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d)); } -inline bool IsASpaceOrTab(int ch) { +constexpr bool IsASpaceOrTab(int ch) noexcept { return (ch == ' ') || (ch == '\t'); } -inline bool IsADigit(int ch) { +constexpr bool IsADigit(int ch) noexcept { return (ch >= '0') && (ch <= '9'); } -inline bool IsADigit(int ch, int base) { +inline bool IsADigit(int ch, int base) noexcept { if (base <= 10) { return (ch >= '0') && (ch < '0' + base); } else { @@ -123,19 +130,23 @@ inline bool IsADigit(int ch, int base) { } } -inline bool IsASCII(int ch) { +constexpr bool IsASCII(int ch) noexcept { return (ch >= 0) && (ch < 0x80); } -inline bool IsLowerCase(int ch) { +constexpr bool IsLowerCase(int ch) noexcept { return (ch >= 'a') && (ch <= 'z'); } -inline bool IsUpperCase(int ch) { +constexpr bool IsUpperCase(int ch) noexcept { return (ch >= 'A') && (ch <= 'Z'); } -inline bool IsAlphaNumeric(int ch) { +constexpr bool IsUpperOrLowerCase(int ch) noexcept { + return IsUpperCase(ch) || IsLowerCase(ch); +} + +constexpr bool IsAlphaNumeric(int ch) noexcept { return ((ch >= '0') && (ch <= '9')) || ((ch >= 'a') && (ch <= 'z')) || @@ -146,19 +157,19 @@ inline bool IsAlphaNumeric(int ch) { * Check if a character is a space. * This is ASCII specific but is safe with chars >= 0x80. */ -inline bool isspacechar(int ch) { +constexpr bool isspacechar(int ch) noexcept { return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d)); } -inline bool iswordchar(int ch) { +constexpr bool iswordchar(int ch) noexcept { return IsAlphaNumeric(ch) || ch == '.' || ch == '_'; } -inline bool iswordstart(int ch) { +constexpr bool iswordstart(int ch) noexcept { return IsAlphaNumeric(ch) || ch == '_'; } -inline bool isoperator(int ch) { +inline bool isoperator(int ch) noexcept { if (IsAlphaNumeric(ch)) return false; if (ch == '%' || ch == '^' || ch == '&' || ch == '*' || @@ -174,7 +185,7 @@ inline bool isoperator(int ch) { // Simple case functions for ASCII supersets. template -inline T MakeUpperCase(T ch) { +inline T MakeUpperCase(T ch) noexcept { if (ch < 'a' || ch > 'z') return ch; else @@ -182,15 +193,15 @@ inline T MakeUpperCase(T ch) { } template -inline T MakeLowerCase(T ch) { +inline T MakeLowerCase(T ch) noexcept { if (ch < 'A' || ch > 'Z') return ch; else return ch - 'A' + 'a'; } -int CompareCaseInsensitive(const char *a, const char *b); -int CompareNCaseInsensitive(const char *a, const char *b, size_t len); +int CompareCaseInsensitive(const char *a, const char *b) noexcept; +int CompareNCaseInsensitive(const char *a, const char *b, size_t len) noexcept; } diff --git a/scintilla/lexlib/DefaultLexer.cxx b/scintilla/lexlib/DefaultLexer.cxx index 9ca39b44a1..e0f61084e4 100644 --- a/scintilla/lexlib/DefaultLexer.cxx +++ b/scintilla/lexlib/DefaultLexer.cxx @@ -24,8 +24,12 @@ using namespace Scintilla; static const char styleSubable[] = { 0 }; -DefaultLexer::DefaultLexer(const LexicalClass *lexClasses_, size_t nClasses_) : - lexClasses(lexClasses_), nClasses(nClasses_) { +DefaultLexer::DefaultLexer(const char *languageName_, int language_, + const LexicalClass *lexClasses_, size_t nClasses_) : + languageName(languageName_), + language(language_), + lexClasses(lexClasses_), + nClasses(nClasses_) { } DefaultLexer::~DefaultLexer() { @@ -36,7 +40,7 @@ void SCI_METHOD DefaultLexer::Release() { } int SCI_METHOD DefaultLexer::Version() const { - return lvMetaData; + return lvIdentity; } const char * SCI_METHOD DefaultLexer::PropertyNames() { @@ -123,3 +127,13 @@ const char * SCI_METHOD DefaultLexer::TagsOfStyle(int style) { const char * SCI_METHOD DefaultLexer::DescriptionOfStyle(int style) { return (style < NamedStyles()) ? lexClasses[style].description : ""; } + +// ILexerWithIdentity methods +const char * SCI_METHOD DefaultLexer::GetName() { + return languageName; +} + +int SCI_METHOD DefaultLexer::GetIdentifier() { + return language; +} + diff --git a/scintilla/lexlib/DefaultLexer.h b/scintilla/lexlib/DefaultLexer.h index 636bd0690a..7856a1dd19 100644 --- a/scintilla/lexlib/DefaultLexer.h +++ b/scintilla/lexlib/DefaultLexer.h @@ -13,11 +13,14 @@ namespace Scintilla { // A simple lexer with no state -class DefaultLexer : public ILexerWithMetaData { +class DefaultLexer : public ILexerWithIdentity { + const char *languageName; + int language; const LexicalClass *lexClasses; size_t nClasses; public: - DefaultLexer(const LexicalClass *lexClasses_ = nullptr, size_t nClasses_ = 0); + DefaultLexer(const char *languageName_, int language_, + const LexicalClass *lexClasses_ = nullptr, size_t nClasses_ = 0); virtual ~DefaultLexer(); void SCI_METHOD Release() override; int SCI_METHOD Version() const override; @@ -44,6 +47,9 @@ class DefaultLexer : public ILexerWithMetaData { const char * SCI_METHOD NameOfStyle(int style) override; const char * SCI_METHOD TagsOfStyle(int style) override; const char * SCI_METHOD DescriptionOfStyle(int style) override; + // ILexerWithIdentity methods + const char * SCI_METHOD GetName() override; + int SCI_METHOD GetIdentifier() override; }; } diff --git a/scintilla/lexlib/LexAccessor.h b/scintilla/lexlib/LexAccessor.h index f8c180e141..81f5a16aea 100644 --- a/scintilla/lexlib/LexAccessor.h +++ b/scintilla/lexlib/LexAccessor.h @@ -10,7 +10,7 @@ namespace Scintilla { -enum EncodingType { enc8bit, encUnicode, encDBCS }; +enum class EncodingType { eightBit, unicode, dbcs }; class LexAccessor { private: @@ -51,7 +51,7 @@ class LexAccessor { explicit LexAccessor(IDocument *pAccess_) : pAccess(pAccess_), startPos(extremePosition), endPos(0), codePage(pAccess->CodePage()), - encodingType(enc8bit), + encodingType(EncodingType::eightBit), lenDoc(pAccess->Length()), validLen(0), startSeg(0), startPosStyling(0), @@ -61,14 +61,14 @@ class LexAccessor { styleBuf[0] = 0; switch (codePage) { case 65001: - encodingType = encUnicode; + encodingType = EncodingType::unicode; break; case 932: case 936: case 949: case 950: case 1361: - encodingType = encDBCS; + encodingType = EncodingType::dbcs; } } char operator[](Sci_Position position) { @@ -77,7 +77,7 @@ class LexAccessor { } return buf[position - startPos]; } - IDocumentWithLineEnd *MultiByteAccess() const { + IDocumentWithLineEnd *MultiByteAccess() const noexcept { if (documentVersion >= dvLineEnd) { return static_cast(pAccess); } @@ -97,7 +97,7 @@ class LexAccessor { bool IsLeadByte(char ch) const { return pAccess->IsDBCSLeadByte(ch); } - EncodingType Encoding() const { + EncodingType Encoding() const noexcept { return encodingType; } bool Match(Sci_Position pos, const char *s) { diff --git a/scintilla/lexlib/LexerBase.cxx b/scintilla/lexlib/LexerBase.cxx index 7b01beff44..97edc621c4 100644 --- a/scintilla/lexlib/LexerBase.cxx +++ b/scintilla/lexlib/LexerBase.cxx @@ -44,7 +44,7 @@ void SCI_METHOD LexerBase::Release() { } int SCI_METHOD LexerBase::Version() const { - return lvMetaData; + return lvIdentity; } const char * SCI_METHOD LexerBase::PropertyNames() { @@ -69,16 +69,17 @@ Sci_Position SCI_METHOD LexerBase::PropertySet(const char *key, const char *val) } } +const char *SCI_METHOD LexerBase::PropertyGet(const char *key) { + return props.Get(key); +} + const char * SCI_METHOD LexerBase::DescribeWordListSets() { return ""; } Sci_Position SCI_METHOD LexerBase::WordListSet(int n, const char *wl) { if (n < numWordLists) { - WordList wlNew; - wlNew.Set(wl); - if (*keyWordLists[n] != wlNew) { - keyWordLists[n]->Set(wl); + if (keyWordLists[n]->Set(wl)) { return 0; } } @@ -142,3 +143,13 @@ const char * SCI_METHOD LexerBase::TagsOfStyle(int style) { const char * SCI_METHOD LexerBase::DescriptionOfStyle(int style) { return (style < NamedStyles()) ? lexClasses[style].description : ""; } + +// ILexerWithIdentity methods + +const char *SCI_METHOD LexerBase::GetName() { + return ""; +} + +int SCI_METHOD LexerBase::GetIdentifier() { + return SCLEX_AUTOMATIC; +} diff --git a/scintilla/lexlib/LexerBase.h b/scintilla/lexlib/LexerBase.h index afeaa8038a..a023d0fe17 100644 --- a/scintilla/lexlib/LexerBase.h +++ b/scintilla/lexlib/LexerBase.h @@ -11,7 +11,7 @@ namespace Scintilla { // A simple lexer with no state -class LexerBase : public ILexerWithMetaData { +class LexerBase : public ILexerWithIdentity { protected: const LexicalClass *lexClasses; size_t nClasses; @@ -46,6 +46,10 @@ class LexerBase : public ILexerWithMetaData { const char * SCI_METHOD NameOfStyle(int style) override; const char * SCI_METHOD TagsOfStyle(int style) override; const char * SCI_METHOD DescriptionOfStyle(int style) override; + // ILexerWithIdentity methods + const char * SCI_METHOD GetName() override; + int SCI_METHOD GetIdentifier() override; + const char *SCI_METHOD PropertyGet(const char *key) override; }; } diff --git a/scintilla/lexlib/LexerModule.cxx b/scintilla/lexlib/LexerModule.cxx index 30e8cf0411..3ffc781e75 100644 --- a/scintilla/lexlib/LexerModule.cxx +++ b/scintilla/lexlib/LexerModule.cxx @@ -30,7 +30,7 @@ LexerModule::LexerModule(int language_, LexerFunction fnFolder_, const char *const wordListDescriptions_[], const LexicalClass *lexClasses_, - size_t nClasses_) : + size_t nClasses_) noexcept : language(language_), fnLexer(fnLexer_), fnFolder(fnFolder_), @@ -44,7 +44,7 @@ LexerModule::LexerModule(int language_, LexerModule::LexerModule(int language_, LexerFactoryFunction fnFactory_, const char *languageName_, - const char * const wordListDescriptions_[]) : + const char * const wordListDescriptions_[]) noexcept : language(language_), fnLexer(nullptr), fnFolder(nullptr), @@ -55,14 +55,11 @@ LexerModule::LexerModule(int language_, languageName(languageName_) { } -LexerModule::~LexerModule() { -} - -int LexerModule::GetLanguage() const { +int LexerModule::GetLanguage() const noexcept { return language; } -int LexerModule::GetNumWordLists() const { +int LexerModule::GetNumWordLists() const noexcept { if (!wordListDescriptions) { return -1; } else { @@ -76,7 +73,7 @@ int LexerModule::GetNumWordLists() const { } } -const char *LexerModule::GetWordListDescription(int index) const { +const char *LexerModule::GetWordListDescription(int index) const noexcept { assert(index < GetNumWordLists()); if (!wordListDescriptions || (index >= GetNumWordLists())) { return ""; @@ -85,11 +82,11 @@ const char *LexerModule::GetWordListDescription(int index) const { } } -const LexicalClass *LexerModule::LexClasses() const { +const LexicalClass *LexerModule::LexClasses() const noexcept { return lexClasses; } -size_t LexerModule::NamedStyles() const { +size_t LexerModule::NamedStyles() const noexcept { return nClasses; } diff --git a/scintilla/lexlib/LexerModule.h b/scintilla/lexlib/LexerModule.h index ab338bec61..771101a91c 100644 --- a/scintilla/lexlib/LexerModule.h +++ b/scintilla/lexlib/LexerModule.h @@ -43,32 +43,31 @@ class LexerModule { LexerFunction fnFolder_= nullptr, const char * const wordListDescriptions_[]=nullptr, const LexicalClass *lexClasses_=nullptr, - size_t nClasses_=0); + size_t nClasses_=0) noexcept; LexerModule( int language_, LexerFactoryFunction fnFactory_, const char *languageName_, - const char * const wordListDescriptions_[]=nullptr); - virtual ~LexerModule(); - int GetLanguage() const; + const char * const wordListDescriptions_[]=nullptr) noexcept; + int GetLanguage() const noexcept; // -1 is returned if no WordList information is available - int GetNumWordLists() const; - const char *GetWordListDescription(int index) const; - const LexicalClass *LexClasses() const; - size_t NamedStyles() const; + int GetNumWordLists() const noexcept; + const char *GetWordListDescription(int index) const noexcept; + const LexicalClass *LexClasses() const noexcept; + size_t NamedStyles() const noexcept; ILexer *Create() const; - virtual void Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, + void Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, WordList *keywordlists[], Accessor &styler) const; - virtual void Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, + void Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, WordList *keywordlists[], Accessor &styler) const; - friend class Catalogue; + friend class CatalogueModules; }; -inline int Maximum(int a, int b) { +inline int Maximum(int a, int b) noexcept { return (a > b) ? a : b; } @@ -82,6 +81,12 @@ inline int Maximum(int a, int b) { #pragma GCC diagnostic ignored "-Wshadow" #endif +// Clang doesn't like omitting braces in array initialization but they just add +// noise to LexicalClass arrays in lexers +#if defined(__clang__) +#pragma clang diagnostic ignored "-Wmissing-braces" +#endif + } #endif diff --git a/scintilla/lexlib/LexerSimple.cxx b/scintilla/lexlib/LexerSimple.cxx index 0be7d97cab..e69c44ad63 100644 --- a/scintilla/lexlib/LexerSimple.cxx +++ b/scintilla/lexlib/LexerSimple.cxx @@ -51,3 +51,11 @@ void SCI_METHOD LexerSimple::Fold(Sci_PositionU startPos, Sci_Position lengthDoc astyler.Flush(); } } + +const char * SCI_METHOD LexerSimple::GetName() { + return module->languageName; +} + +int SCI_METHOD LexerSimple::GetIdentifier() { + return module->GetLanguage(); +} diff --git a/scintilla/lexlib/LexerSimple.h b/scintilla/lexlib/LexerSimple.h index 87882eaebd..a2589cf443 100644 --- a/scintilla/lexlib/LexerSimple.h +++ b/scintilla/lexlib/LexerSimple.h @@ -19,6 +19,9 @@ class LexerSimple : public LexerBase { const char * SCI_METHOD DescribeWordListSets() override; void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) override; void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) override; + // ILexerWithIdentity methods + const char * SCI_METHOD GetName() override; + int SCI_METHOD GetIdentifier() override; }; } diff --git a/scintilla/lexlib/OptionSet.h b/scintilla/lexlib/OptionSet.h index b6fc07049d..3c282e49b5 100644 --- a/scintilla/lexlib/OptionSet.h +++ b/scintilla/lexlib/OptionSet.h @@ -25,6 +25,7 @@ class OptionSet { plcoi pi; plcos ps; }; + std::string value; std::string description; Option() : opType(SC_TYPE_BOOLEAN), pb(0), description("") { @@ -38,7 +39,8 @@ class OptionSet { Option(plcos ps_, std::string description_) : opType(SC_TYPE_STRING), ps(ps_), description(description_) { } - bool Set(T *base, const char *val) const { + bool Set(T *base, const char *val) { + value = val; switch (opType) { case SC_TYPE_BOOLEAN: { bool option = atoi(val) != 0; @@ -66,6 +68,9 @@ class OptionSet { } return false; } + const char *Get() const noexcept { + return value.c_str(); + } }; typedef std::map OptionMap; OptionMap nameToDef; @@ -78,8 +83,6 @@ class OptionSet { names += name; } public: - virtual ~OptionSet() { - } void DefineProperty(const char *name, plcob pb, std::string description="") { nameToDef[name] = Option(pb, description); AppendName(name); @@ -92,7 +95,7 @@ class OptionSet { nameToDef[name] = Option(ps, description); AppendName(name); } - const char *PropertyNames() const { + const char *PropertyNames() const noexcept { return names.c_str(); } int PropertyType(const char *name) { @@ -118,6 +121,14 @@ class OptionSet { return false; } + const char *PropertyGet(const char *name) { + typename OptionMap::iterator it = nameToDef.find(name); + if (it != nameToDef.end()) { + return it->second.Get(); + } + return nullptr; + } + void DefineWordListSets(const char * const wordListDescriptions[]) { if (wordListDescriptions) { for (size_t wl = 0; wordListDescriptions[wl]; wl++) { @@ -128,7 +139,7 @@ class OptionSet { } } - const char *DescribeWordListSets() const { + const char *DescribeWordListSets() const noexcept { return wordLists.c_str(); } }; diff --git a/scintilla/lexlib/PropSetSimple.cxx b/scintilla/lexlib/PropSetSimple.cxx index 5ce353c717..6ee57d667f 100644 --- a/scintilla/lexlib/PropSetSimple.cxx +++ b/scintilla/lexlib/PropSetSimple.cxx @@ -21,10 +21,14 @@ namespace { typedef std::map mapss; -mapss *PropsFromPointer(void *impl) { +mapss *PropsFromPointer(void *impl) noexcept { return static_cast(impl); } +constexpr bool IsASpaceCharacter(int ch) noexcept { + return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d)); +} + } PropSetSimple::PropSetSimple() { @@ -35,7 +39,7 @@ PropSetSimple::PropSetSimple() { PropSetSimple::~PropSetSimple() { mapss *props = PropsFromPointer(impl); delete props; - impl = 0; + impl = nullptr; } void PropSetSimple::Set(const char *key, const char *val, size_t lenKey, size_t lenVal) { @@ -45,10 +49,6 @@ void PropSetSimple::Set(const char *key, const char *val, size_t lenKey, size_t (*props)[std::string(key, lenKey)] = std::string(val, lenVal); } -static bool IsASpaceCharacter(unsigned int ch) { - return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d)); -} - void PropSetSimple::Set(const char *keyVal) { while (IsASpaceCharacter(*keyVal)) keyVal++; @@ -90,7 +90,7 @@ const char *PropSetSimple::Get(const char *key) const { // for that, through a recursive function and a simple chain of pointers. struct VarChain { - VarChain(const char *var_=nullptr, const VarChain *link_= nullptr): var(var_), link(link_) {} + VarChain(const char *var_=nullptr, const VarChain *link_= nullptr) noexcept : var(var_), link(link_) {} bool contains(const char *testVar) const { return (var && (0 == strcmp(var, testVar))) @@ -137,10 +137,10 @@ static int ExpandAllInPlace(const PropSetSimple &props, std::string &withVars, i return maxExpands; } -int PropSetSimple::GetExpanded(const char *key, char *result) const { +size_t PropSetSimple::GetExpanded(const char *key, char *result) const { std::string val = Get(key); ExpandAllInPlace(*this, val, 100, VarChain(key)); - const int n = static_cast(val.size()); + const size_t n = val.size(); if (result) { memcpy(result, val.c_str(), n+1); } diff --git a/scintilla/lexlib/PropSetSimple.h b/scintilla/lexlib/PropSetSimple.h index ba4e424463..d4a5b2243d 100644 --- a/scintilla/lexlib/PropSetSimple.h +++ b/scintilla/lexlib/PropSetSimple.h @@ -19,7 +19,7 @@ class PropSetSimple { void Set(const char *key, const char *val, size_t lenKey, size_t lenVal); void SetMultiple(const char *); const char *Get(const char *key) const; - int GetExpanded(const char *key, char *result) const; + size_t GetExpanded(const char *key, char *result) const; int GetInt(const char *key, int defaultValue=0) const; }; diff --git a/scintilla/lexlib/SparseState.h b/scintilla/lexlib/SparseState.h index 4e7ac92e38..6286c76afb 100644 --- a/scintilla/lexlib/SparseState.h +++ b/scintilla/lexlib/SparseState.h @@ -17,12 +17,12 @@ class SparseState { struct State { Sci_Position position; T value; - State(Sci_Position position_, T value_) : position(position_), value(value_) { + constexpr State(Sci_Position position_, T value_) noexcept : position(position_), value(value_) { } - inline bool operator<(const State &other) const { + inline bool operator<(const State &other) const noexcept { return position < other.position; } - inline bool operator==(const State &other) const { + inline bool operator==(const State &other) const noexcept { return (position == other.position) && (value == other.value); } }; @@ -31,7 +31,7 @@ class SparseState { stateVector states; typename stateVector::iterator Find(Sci_Position position) { - State searchValue(position, T()); + const State searchValue(position, T()); return std::lower_bound(states.begin(), states.end(), searchValue); } diff --git a/scintilla/lexlib/StyleContext.h b/scintilla/lexlib/StyleContext.h index 8cb683619f..d8c17d794f 100644 --- a/scintilla/lexlib/StyleContext.h +++ b/scintilla/lexlib/StyleContext.h @@ -72,7 +72,7 @@ class StyleContext { width(0), chNext(0), widthNext(1) { - if (styler.Encoding() != enc8bit) { + if (styler.Encoding() != EncodingType::eightBit) { multiByteAccess = styler.MultiByteAccess(); } styler.StartAt(startPos /*, chMask*/); @@ -100,7 +100,7 @@ class StyleContext { styler.ColourTo(currentPos - ((currentPos > lengthDocument) ? 2 : 1), state); styler.Flush(); } - bool More() const { + bool More() const noexcept { return currentPos < endPos; } void Forward() { @@ -139,7 +139,7 @@ class StyleContext { } } } - void ChangeState(int state_) { + void ChangeState(int state_) noexcept { state = state_; } void SetState(int state_) { @@ -154,8 +154,8 @@ class StyleContext { Sci_Position LengthCurrent() const { return currentPos - styler.GetStartSegment(); } - int GetRelative(Sci_Position n) { - return static_cast(styler.SafeGetCharAt(currentPos+n, 0)); + int GetRelative(Sci_Position n, char chDefault='\0') { + return static_cast(styler.SafeGetCharAt(currentPos+n, chDefault)); } int GetRelativeCharacter(Sci_Position n) { if (n == 0) diff --git a/scintilla/lexlib/SubStyles.h b/scintilla/lexlib/SubStyles.h index 3e99efe83a..4bfe7ebfc9 100644 --- a/scintilla/lexlib/SubStyles.h +++ b/scintilla/lexlib/SubStyles.h @@ -27,23 +27,23 @@ class WordClassifier { wordToStyle.clear(); } - int Base() const { + int Base() const noexcept { return baseStyle; } - int Start() const { + int Start() const noexcept { return firstStyle; } - int Last() const { + int Last() const noexcept { return firstStyle + lenStyles - 1; } - int Length() const { + int Length() const noexcept { return lenStyles; } - void Clear() { + void Clear() noexcept { firstStyle = 0; lenStyles = 0; wordToStyle.clear(); @@ -57,11 +57,23 @@ class WordClassifier { return -1; } - bool IncludesStyle(int style) const { + bool IncludesStyle(int style) const noexcept { return (style >= firstStyle) && (style < (firstStyle + lenStyles)); } + void RemoveStyle(int style) { + std::map::iterator it = wordToStyle.begin(); + while (it != wordToStyle.end()) { + if (it->second == style) { + it = wordToStyle.erase(it); + } else { + ++it; + } + } + } + void SetIdentifiers(int style, const char *identifiers) { + RemoveStyle(style); while (*identifiers) { const char *cpSpace = identifiers; while (*cpSpace && !(*cpSpace == ' ' || *cpSpace == '\t' || *cpSpace == '\r' || *cpSpace == '\n')) @@ -86,7 +98,7 @@ class SubStyles { int allocated; std::vector classifiers; - int BlockFromBaseStyle(int baseStyle) const { + int BlockFromBaseStyle(int baseStyle) const noexcept { for (int b=0; b < classifications; b++) { if (baseStyle == baseStyles[b]) return b; @@ -133,12 +145,12 @@ class SubStyles { } } - int Start(int styleBase) { + int Start(int styleBase) noexcept { const int block = BlockFromBaseStyle(styleBase); return (block >= 0) ? classifiers[block].Start() : -1; } - int Length(int styleBase) { + int Length(int styleBase) noexcept { const int block = BlockFromBaseStyle(styleBase); return (block >= 0) ? classifiers[block].Length() : 0; } @@ -151,7 +163,7 @@ class SubStyles { return subStyle; } - int DistanceToSecondaryStyles() const { + int DistanceToSecondaryStyles() const noexcept { return secondaryDistance; } @@ -185,7 +197,7 @@ class SubStyles { it->Clear(); } - const WordClassifier &Classifier(int baseStyle) const { + const WordClassifier &Classifier(int baseStyle) const noexcept { const int block = BlockFromBaseStyle(baseStyle); return classifiers[block >= 0 ? block : 0]; } diff --git a/scintilla/lexlib/WordList.cxx b/scintilla/lexlib/WordList.cxx index c8b4cd63b5..460995daae 100644 --- a/scintilla/lexlib/WordList.cxx +++ b/scintilla/lexlib/WordList.cxx @@ -20,7 +20,7 @@ using namespace Scintilla; * Creates an array that points into each word in the string and puts \0 terminators * after each word. */ -static char **ArrayFromWordList(char *wordlist, int *len, bool onlyLineEnds = false) { +static char **ArrayFromWordList(char *wordlist, size_t slen, int *len, bool onlyLineEnds = false) { int prev = '\n'; int words = 0; // For rapid determination of whether a character is a separator, build @@ -40,7 +40,6 @@ static char **ArrayFromWordList(char *wordlist, int *len, bool onlyLineEnds = fa } char **keywords = new char *[words + 1]; int wordsStore = 0; - const size_t slen = strlen(wordlist); if (words) { prev = '\0'; for (size_t k = 0; k < slen; k++) { @@ -71,11 +70,11 @@ WordList::~WordList() { Clear(); } -WordList::operator bool() const { +WordList::operator bool() const noexcept { return len ? true : false; } -bool WordList::operator!=(const WordList &other) const { +bool WordList::operator!=(const WordList &other) const noexcept { if (len != other.len) return true; for (int i=0; i= 0; l--) { unsigned char indexChar = words[l][0]; starts[indexChar] = l; } + return true; } /** Check whether a string is in the list. @@ -140,7 +160,7 @@ void WordList::Set(const char *s) { * Prefix elements start with '^' and match all strings that start with the rest of the element * so '^GTK_' matches 'GTK_X', 'GTK_MAJOR_VERSION', and 'GTK_'. */ -bool WordList::InList(const char *s) const { +bool WordList::InList(const char *s) const noexcept { if (0 == words) return false; const unsigned char firstChar = s[0]; @@ -182,7 +202,7 @@ bool WordList::InList(const char *s) const { * with def to be a keyword, but also defi, defin and define are valid. * The marker is ~ in this case. */ -bool WordList::InListAbbreviated(const char *s, const char marker) const { +bool WordList::InListAbbreviated(const char *s, const char marker) const noexcept { if (0 == words) return false; const unsigned char firstChar = s[0]; @@ -236,7 +256,7 @@ bool WordList::InListAbbreviated(const char *s, const char marker) const { * The marker is ~ in this case. * No multiple markers check is done and wont work. */ -bool WordList::InListAbridged(const char *s, const char marker) const { +bool WordList::InListAbridged(const char *s, const char marker) const noexcept { if (0 == words) return false; const unsigned char firstChar = s[0]; @@ -289,7 +309,7 @@ bool WordList::InListAbridged(const char *s, const char marker) const { return false; } -const char *WordList::WordAt(int n) const { +const char *WordList::WordAt(int n) const noexcept { return words[n]; } diff --git a/scintilla/lexlib/WordList.h b/scintilla/lexlib/WordList.h index a9f2d4ab2f..127f00e68c 100644 --- a/scintilla/lexlib/WordList.h +++ b/scintilla/lexlib/WordList.h @@ -22,15 +22,15 @@ class WordList { public: explicit WordList(bool onlyLineEnds_ = false); ~WordList(); - operator bool() const; - bool operator!=(const WordList &other) const; - int Length() const; - void Clear(); - void Set(const char *s); - bool InList(const char *s) const; - bool InListAbbreviated(const char *s, const char marker) const; - bool InListAbridged(const char *s, const char marker) const; - const char *WordAt(int n) const; + operator bool() const noexcept; + bool operator!=(const WordList &other) const noexcept; + int Length() const noexcept; + void Clear() noexcept; + bool Set(const char *s); + bool InList(const char *s) const noexcept; + bool InListAbbreviated(const char *s, const char marker) const noexcept; + bool InListAbridged(const char *s, const char marker) const noexcept; + const char *WordAt(int n) const noexcept; }; } diff --git a/scintilla/scintilla_changes.patch b/scintilla/scintilla_changes.patch index f28072ea4a..d70b4451c5 100644 --- a/scintilla/scintilla_changes.patch +++ b/scintilla/scintilla_changes.patch @@ -62,7 +62,7 @@ diff --git scintilla/src/Catalogue.cxx scintilla/src/Catalogue.cxx index ed47aa8..e58f1ab 100644 --- scintilla/src/Catalogue.cxx +++ scintilla/src/Catalogue.cxx -@@ -77,129 +77,50 @@ int Scintilla_LinkLexers() { +@@ -60,133 +60,50 @@ //++Autogenerated -- run scripts/LexGen.py to regenerate //**\(\tLINK_LEXER(\*);\n\) @@ -96,6 +96,7 @@ index ed47aa8..e58f1ab 100644 - LINK_LEXER(lmCsound); LINK_LEXER(lmCss); LINK_LEXER(lmD); +- LINK_LEXER(lmDataflex); LINK_LEXER(lmDiff); - LINK_LEXER(lmDMAP); - LINK_LEXER(lmDMIS); @@ -114,6 +115,7 @@ index ed47aa8..e58f1ab 100644 - LINK_LEXER(lmGAP); - LINK_LEXER(lmGui4Cli); LINK_LEXER(lmHaskell); +- LINK_LEXER(lmHollywood); LINK_LEXER(lmHTML); - LINK_LEXER(lmIHex); - LINK_LEXER(lmIndent); @@ -162,6 +164,7 @@ index ed47aa8..e58f1ab 100644 - LINK_LEXER(lmPureBasic); LINK_LEXER(lmPython); LINK_LEXER(lmR); +- LINK_LEXER(lmRaku); - LINK_LEXER(lmREBOL); - LINK_LEXER(lmRegistry); LINK_LEXER(lmRuby); @@ -190,6 +193,7 @@ index ed47aa8..e58f1ab 100644 LINK_LEXER(lmVerilog); LINK_LEXER(lmVHDL); - LINK_LEXER(lmVisualProlog); +- LINK_LEXER(lmX12); LINK_LEXER(lmXML); LINK_LEXER(lmYAML); diff --git a/scintilla/src/AutoComplete.h b/scintilla/src/AutoComplete.h index 6440c13d43..c5b40ad146 100644 --- a/scintilla/src/AutoComplete.h +++ b/scintilla/src/AutoComplete.h @@ -17,7 +17,7 @@ class AutoComplete { std::string stopChars; std::string fillUpChars; char separator; - char typesep; // Type seperator + char typesep; // Type separator enum { maxItemLen=1000 }; std::vector sortMatrix; @@ -28,7 +28,7 @@ class AutoComplete { std::unique_ptr lb; Sci::Position posStart; Sci::Position startLen; - /// Should autocompletion be canceled if editor's currentPos <= startPos? + /// Should autocompletion be cancelled if editor's currentPos <= startPos? bool cancelAtStartPos; bool autoHide; bool dropRestOfWord; diff --git a/scintilla/src/CallTip.cxx b/scintilla/src/CallTip.cxx index 18c4549bba..96b54224c9 100644 --- a/scintilla/src/CallTip.cxx +++ b/scintilla/src/CallTip.cxx @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -21,23 +22,24 @@ #include "Scintilla.h" -#include "StringCopy.h" #include "Position.h" #include "IntegerRectangle.h" #include "CallTip.h" using namespace Scintilla; -CallTip::CallTip() { - wCallTip = 0; +size_t Chunk::Length() const noexcept { + return end - start; +} + +CallTip::CallTip() noexcept { + wCallTip = {}; inCallTipMode = false; posStartCallTip = 0; rectUp = PRectangle(0,0,0,0); rectDown = PRectangle(0,0,0,0); lineHeight = 1; offsetMain = 0; - startHighlight = 0; - endHighlight = 0; tabSize = 0; above = false; useStyleCallTip = false; // for backwards compatibility @@ -67,17 +69,12 @@ CallTip::~CallTip() { wCallTip.Destroy(); } -// Although this test includes 0, we should never see a \0 character. -static bool IsArrowCharacter(char ch) { - return (ch == 0) || (ch == '\001') || (ch == '\002'); -} - // We ignore tabs unless a tab width has been set. -bool CallTip::IsTabCharacter(char ch) const { +bool CallTip::IsTabCharacter(char ch) const noexcept { return (tabSize > 0) && (ch == '\t'); } -int CallTip::NextTabPos(int x) const { +int CallTip::NextTabPos(int x) const noexcept { if (tabSize > 0) { // paranoia... not called unless this is true x -= insetX; // position relative to text x = (x + tabSize) / tabSize; // tab "number" @@ -87,86 +84,100 @@ int CallTip::NextTabPos(int x) const { } } +namespace { + +// Although this test includes 0, we should never see a \0 character. +constexpr bool IsArrowCharacter(char ch) noexcept { + return (ch == 0) || (ch == '\001') || (ch == '\002'); +} + +void DrawArrow(Scintilla::Surface *surface, const PRectangle &rc, bool upArrow, ColourDesired colourBG, ColourDesired colourUnSel) { + surface->FillRectangle(rc, colourBG); + const int width = static_cast(rc.Width()); + const int halfWidth = width / 2 - 3; + const int quarterWidth = halfWidth / 2; + const int centreX = static_cast(rc.left) + width / 2 - 1; + const int centreY = static_cast(rc.top + rc.bottom) / 2; + const PRectangle rcClientInner(rc.left + 1, rc.top + 1, rc.right - 2, rc.bottom - 1); + surface->FillRectangle(rcClientInner, colourUnSel); + + if (upArrow) { // Up arrow + Point pts[] = { + Point::FromInts(centreX - halfWidth, centreY + quarterWidth), + Point::FromInts(centreX + halfWidth, centreY + quarterWidth), + Point::FromInts(centreX, centreY - halfWidth + quarterWidth), + }; + surface->Polygon(pts, Sci::size(pts), colourBG, colourBG); + } else { // Down arrow + Point pts[] = { + Point::FromInts(centreX - halfWidth, centreY - quarterWidth), + Point::FromInts(centreX + halfWidth, centreY - quarterWidth), + Point::FromInts(centreX, centreY + halfWidth - quarterWidth), + }; + surface->Polygon(pts, Sci::size(pts), colourBG, colourBG); + } +} + +} + // Draw a section of the call tip that does not include \n in one colour. -// The text may include up to numEnds tabs or arrow characters. -void CallTip::DrawChunk(Surface *surface, int &x, const char *s, - int posStart, int posEnd, int ytext, PRectangle rcClient, - bool highlight, bool draw) { - s += posStart; - const int len = posEnd - posStart; +// The text may include tabs or arrow characters. +int CallTip::DrawChunk(Surface *surface, int x, const char *s, size_t len, + int ytext, PRectangle rcClient, bool asHighlight, bool draw) { + if (len == 0) { + return x; + } // Divide the text into sections that are all text, or that are // single arrows or single tab characters (if tabSize > 0). - int maxEnd = 0; - const int numEnds = 10; - int ends[numEnds + 2]; - for (int i=0; i 0) - ends[maxEnd++] = i; - ends[maxEnd++] = i+1; + // Start with single element 0 to simplify append checks. + std::vector ends(1); + for (size_t i=0; i startSeg) { - if (IsArrowCharacter(s[startSeg])) { - xEnd = x + widthArrow; - const bool upArrow = s[startSeg] == '\001'; + if (ends.back() != len) + ends.push_back(len); + ends.erase(ends.begin()); // Remove initial 0. + + size_t startSeg = 0; + for (const size_t endSeg : ends) { + assert(endSeg > 0); + int xEnd; + if (IsArrowCharacter(s[startSeg])) { + xEnd = x + widthArrow; + const bool upArrow = s[startSeg] == '\001'; + rcClient.left = static_cast(x); + rcClient.right = static_cast(xEnd); + if (draw) { + DrawArrow(surface, rcClient, upArrow, colourBG, colourUnSel); + } + offsetMain = xEnd; + if (upArrow) { + rectUp = rcClient; + } else { + rectDown = rcClient; + } + } else if (IsTabCharacter(s[startSeg])) { + xEnd = NextTabPos(x); + } else { + const char *segText = s + startSeg; + xEnd = x + static_cast(Sci::lround(surface->WidthText(font, segText, endSeg - startSeg))); + if (draw) { rcClient.left = static_cast(x); rcClient.right = static_cast(xEnd); - if (draw) { - const int halfWidth = widthArrow / 2 - 3; - const int quarterWidth = halfWidth / 2; - const int centreX = x + widthArrow / 2 - 1; - const int centreY = static_cast(rcClient.top + rcClient.bottom) / 2; - surface->FillRectangle(rcClient, colourBG); - const PRectangle rcClientInner(rcClient.left + 1, rcClient.top + 1, - rcClient.right - 2, rcClient.bottom - 1); - surface->FillRectangle(rcClientInner, colourUnSel); - - if (upArrow) { // Up arrow - Point pts[] = { - Point::FromInts(centreX - halfWidth, centreY + quarterWidth), - Point::FromInts(centreX + halfWidth, centreY + quarterWidth), - Point::FromInts(centreX, centreY - halfWidth + quarterWidth), - }; - surface->Polygon(pts, ELEMENTS(pts), colourBG, colourBG); - } else { // Down arrow - Point pts[] = { - Point::FromInts(centreX - halfWidth, centreY - quarterWidth), - Point::FromInts(centreX + halfWidth, centreY - quarterWidth), - Point::FromInts(centreX, centreY + halfWidth - quarterWidth), - }; - surface->Polygon(pts, ELEMENTS(pts), colourBG, colourBG); - } - } - offsetMain = xEnd; - if (upArrow) { - rectUp = rcClient; - } else { - rectDown = rcClient; - } - } else if (IsTabCharacter(s[startSeg])) { - xEnd = NextTabPos(x); - } else { - xEnd = x + static_cast(lround(surface->WidthText(font, s + startSeg, endSeg - startSeg))); - if (draw) { - rcClient.left = static_cast(x); - rcClient.right = static_cast(xEnd); - surface->DrawTextTransparent(rcClient, font, static_cast(ytext), - s+startSeg, endSeg - startSeg, - highlight ? colourSel : colourUnSel); - } + surface->DrawTextTransparent(rcClient, font, static_cast(ytext), + segText, endSeg - startSeg, + asHighlight ? colourSel : colourUnSel); } - x = xEnd; - startSeg = endSeg; } + x = xEnd; + startSeg = endSeg; } + return x; } int CallTip::PaintContents(Surface *surfaceWindow, bool draw) { @@ -176,46 +187,50 @@ int CallTip::PaintContents(Surface *surfaceWindow, bool draw) { PRectangle rcClient(1.0f, 1.0f, rcClientSize.right - 1, rcClientSize.bottom - 1); // To make a nice small call tip window, it is only sized to fit most normal characters without accents - const int ascent = static_cast(round(surfaceWindow->Ascent(font) - surfaceWindow->InternalLeading(font))); + const int ascent = static_cast(Sci::round(surfaceWindow->Ascent(font) - surfaceWindow->InternalLeading(font))); // For each line... // Draw the definition in three parts: before highlight, highlighted, after highlight int ytext = static_cast(rcClient.top) + ascent + 1; rcClient.bottom = ytext + surfaceWindow->Descent(font) + 1; - const char *chunkVal = val.c_str(); - bool moreChunks = true; + const char *remaining = val.c_str(); int maxWidth = 0; - - while (moreChunks) { - const char *chunkEnd = strchr(chunkVal, '\n'); + size_t lineStart = 0; + while (*remaining) { + const char *chunkVal = remaining; + const char *chunkEnd = strchr(remaining, '\n'); if (!chunkEnd) { chunkEnd = chunkVal + strlen(chunkVal); - moreChunks = false; } - const int chunkOffset = static_cast(chunkVal - val.c_str()); - const int chunkLength = static_cast(chunkEnd - chunkVal); - const int chunkEndOffset = chunkOffset + chunkLength; - int thisStartHighlight = std::max(startHighlight, chunkOffset); - thisStartHighlight = std::min(thisStartHighlight, chunkEndOffset); - thisStartHighlight -= chunkOffset; - int thisEndHighlight = std::max(endHighlight, chunkOffset); - thisEndHighlight = std::min(thisEndHighlight, chunkEndOffset); - thisEndHighlight -= chunkOffset; + const size_t chunkLength = static_cast(chunkEnd - chunkVal); + remaining += chunkLength; + if (*remaining) { + remaining++; // Skip \n + } + + const Chunk chunkLine(lineStart, lineStart + chunkLength); + Chunk chunkHighlight( + Sci::clamp(highlight.start, chunkLine.start, chunkLine.end), + Sci::clamp(highlight.end, chunkLine.start, chunkLine.end) + ); + chunkHighlight.start -= lineStart; + chunkHighlight.end -= lineStart; + rcClient.top = static_cast(ytext - ascent - 1); int x = insetX; // start each line at this inset - DrawChunk(surfaceWindow, x, chunkVal, 0, thisStartHighlight, + x = DrawChunk(surfaceWindow, x, chunkVal, chunkHighlight.start, ytext, rcClient, false, draw); - DrawChunk(surfaceWindow, x, chunkVal, thisStartHighlight, thisEndHighlight, + x = DrawChunk(surfaceWindow, x, chunkVal + chunkHighlight.start, chunkHighlight.Length(), ytext, rcClient, true, draw); - DrawChunk(surfaceWindow, x, chunkVal, thisEndHighlight, chunkLength, + x = DrawChunk(surfaceWindow, x, chunkVal + chunkHighlight.end, chunkLength - chunkHighlight.end, ytext, rcClient, false, draw); - chunkVal = chunkEnd + 1; ytext += lineHeight; rcClient.bottom += lineHeight; maxWidth = std::max(maxWidth, x); + lineStart += chunkLength + 1; } return maxWidth; } @@ -247,7 +262,7 @@ void CallTip::PaintCT(Surface *surfaceWindow) { #endif } -void CallTip::MouseClick(Point pt) { +void CallTip::MouseClick(Point pt) noexcept { clickPlace = 0; if (rectUp.Contains(pt)) clickPlace = 1; @@ -266,8 +281,7 @@ PRectangle CallTip::CallTipStart(Sci::Position pos, Point pt, int textHeight, co surfaceMeasure->Init(wParent.GetID()); surfaceMeasure->SetUnicodeMode(SC_CP_UTF8 == codePage); surfaceMeasure->SetDBCSMode(codePage); - startHighlight = 0; - endHighlight = 0; + highlight = Chunk(); inCallTipMode = true; posStartCallTip = pos; const XYPOSITION deviceHeight = static_cast(surfaceMeasure->DeviceHeightFont(size)); @@ -280,7 +294,7 @@ PRectangle CallTip::CallTipStart(Sci::Position pos, Point pt, int textHeight, co rectDown = PRectangle(0,0,0,0); offsetMain = insetX; // changed to right edge of any arrows const int width = PaintContents(surfaceMeasure.get(), false) + insetX; - lineHeight = static_cast(lround(surfaceMeasure->Height(font))); + lineHeight = static_cast(Sci::lround(surfaceMeasure->Height(font))); // The returned // rectangle is aligned to the right edge of the last arrow encountered in @@ -300,11 +314,11 @@ void CallTip::CallTipCancel() { } } -void CallTip::SetHighlight(int start, int end) { +void CallTip::SetHighlight(size_t start, size_t end) { // Avoid flashing by checking something has really changed - if ((start != startHighlight) || (end != endHighlight)) { - startHighlight = start; - endHighlight = (end > start) ? end : start; + if ((start != highlight.start) || (end != highlight.end)) { + highlight.start = start; + highlight.end = (end > start) ? end : start; if (wCallTip.Created()) { wCallTip.InvalidateAll(); } @@ -313,20 +327,24 @@ void CallTip::SetHighlight(int start, int end) { // Set the tab size (sizes > 0 enable the use of tabs). This also enables the // use of the STYLE_CALLTIP. -void CallTip::SetTabSize(int tabSz) { +void CallTip::SetTabSize(int tabSz) noexcept { tabSize = tabSz; useStyleCallTip = true; } // Set the calltip position, below the text by default or if above is false // else above the text. -void CallTip::SetPosition(bool aboveText) { +void CallTip::SetPosition(bool aboveText) noexcept { above = aboveText; } +bool CallTip::UseStyleCallTip() const noexcept { + return useStyleCallTip; +} + // It might be better to have two access functions for this and to use // them for all settings of colours. -void CallTip::SetForeBack(const ColourDesired &fore, const ColourDesired &back) { +void CallTip::SetForeBack(const ColourDesired &fore, const ColourDesired &back) noexcept { colourBG = back; colourUnSel = fore; } diff --git a/scintilla/src/CallTip.h b/scintilla/src/CallTip.h index a37138d5fa..1a0a317cb0 100644 --- a/scintilla/src/CallTip.h +++ b/scintilla/src/CallTip.h @@ -10,11 +10,19 @@ namespace Scintilla { +struct Chunk { + size_t start; + size_t end; + Chunk(size_t start_=0, size_t end_=0) noexcept : start(start_), end(end_) { + assert(start <= end); + } + size_t Length() const noexcept; +}; + /** */ class CallTip { - int startHighlight; // character offset to start and... - int endHighlight; // ...end of highlighted text + Chunk highlight; // character offset to start and end of highlighted text std::string val; Font font; PRectangle rectUp; // rectangle of last up angle in the tip @@ -25,12 +33,11 @@ class CallTip { bool useStyleCallTip; // if true, STYLE_CALLTIP should be used bool above; // if true, display calltip above text - void DrawChunk(Surface *surface, int &x, const char *s, - int posStart, int posEnd, int ytext, PRectangle rcClient, - bool highlight, bool draw); + int DrawChunk(Surface *surface, int x, const char *s, size_t len, + int ytext, PRectangle rcClient, bool asHighlight, bool draw); int PaintContents(Surface *surfaceWindow, bool draw); - bool IsTabCharacter(char ch) const; - int NextTabPos(int x) const; + bool IsTabCharacter(char ch) const noexcept; + int NextTabPos(int x) const noexcept; public: Window wCallTip; @@ -50,7 +57,7 @@ class CallTip { int borderHeight; int verticalOffset; // pixel offset up or down of the calltip with respect to the line - CallTip(); + CallTip() noexcept; // Deleted so CallTip objects can not be copied. CallTip(const CallTip &) = delete; CallTip(CallTip &&) = delete; @@ -60,7 +67,7 @@ class CallTip { void PaintCT(Surface *surfaceWindow); - void MouseClick(Point pt); + void MouseClick(Point pt) noexcept; /// Setup the calltip and return a rectangle of the area required. PRectangle CallTipStart(Sci::Position pos, Point pt, int textHeight, const char *defn, @@ -71,19 +78,19 @@ class CallTip { /// Set a range of characters to be displayed in a highlight style. /// Commonly used to highlight the current parameter. - void SetHighlight(int start, int end); + void SetHighlight(size_t start, size_t end); /// Set the tab size in pixels for the call tip. 0 or -ve means no tab expand. - void SetTabSize(int tabSz); + void SetTabSize(int tabSz) noexcept; /// Set calltip position. - void SetPosition(bool aboveText); + void SetPosition(bool aboveText) noexcept; /// Used to determine which STYLE_xxxx to use for call tip information - bool UseStyleCallTip() const { return useStyleCallTip;} + bool UseStyleCallTip() const noexcept; // Modify foreground and background colours - void SetForeBack(const ColourDesired &fore, const ColourDesired &back); + void SetForeBack(const ColourDesired &fore, const ColourDesired &back) noexcept; }; } diff --git a/scintilla/src/CaseConvert.cxx b/scintilla/src/CaseConvert.cxx index c1cfd38e28..26104f33d7 100644 --- a/scintilla/src/CaseConvert.cxx +++ b/scintilla/src/CaseConvert.cxx @@ -19,6 +19,8 @@ #include "CaseConvert.h" #include "UniConversion.h" +#include "Compat.h" + using namespace Scintilla; namespace { @@ -75,6 +77,7 @@ int symmetricCaseConversionRanges[] = { 42803,42802,31,2, 42879,42878,5,2, 42903,42902,10,2, +42933,42932,6,2, 65345,65313,26,1, 66600,66560,40,1, 66776,66736,36,1, @@ -157,6 +160,7 @@ int symmetricCaseConversions[] = { 629,415, 637,11364, 640,422, +642,42949, 643,425, 647,42929, 648,430, @@ -191,6 +195,7 @@ int symmetricCaseConversions[] = { 4351,7359, 7545,42877, 7549,11363, +7566,42950, 8017,8025, 8019,8027, 8021,8029, @@ -236,9 +241,8 @@ int symmetricCaseConversions[] = { 42892,42891, 42897,42896, 42899,42898, -42933,42932, -42935,42934, -42937,42936, +42900,42948, +42947,42946, 43859,42931, //--Autogenerated -- end of section automatically generated @@ -577,6 +581,9 @@ class CaseConverter : public ICaseConverter { struct CharacterConversion { int character; ConversionString conversion; + CharacterConversion() noexcept : character(0) { + // Empty case: NUL -> "". + } CharacterConversion(int character_=0, const char *conversion_="") noexcept : character(character_) { StringCopy(conversion.conversion, conversion_); } @@ -690,7 +697,7 @@ void AddSymmetric(enum CaseConversion conversion, int lower,int upper) { void SetupConversions(enum CaseConversion conversion) { // First initialize for the symmetric ranges - for (size_t i=0; i(iChar); } @@ -37,7 +37,7 @@ size_t CaseFolderTable::Fold(char *folded, size_t sizeFolded, const char *mixed, } } -void CaseFolderTable::SetTranslation(char ch, char chTranslation) { +void CaseFolderTable::SetTranslation(char ch, char chTranslation) noexcept { mapping[static_cast(ch)] = chTranslation; } diff --git a/scintilla/src/CaseFolder.h b/scintilla/src/CaseFolder.h index eb852a491b..966069bc4e 100644 --- a/scintilla/src/CaseFolder.h +++ b/scintilla/src/CaseFolder.h @@ -20,10 +20,10 @@ class CaseFolderTable : public CaseFolder { protected: char mapping[256]; public: - CaseFolderTable(); + CaseFolderTable() noexcept; ~CaseFolderTable() override; size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) override; - void SetTranslation(char ch, char chTranslation); + void SetTranslation(char ch, char chTranslation) noexcept; void StandardASCII() noexcept; }; diff --git a/scintilla/src/Catalogue.cxx b/scintilla/src/Catalogue.cxx index 01f20c649e..735836d940 100644 --- a/scintilla/src/Catalogue.cxx +++ b/scintilla/src/Catalogue.cxx @@ -19,41 +19,27 @@ #include "SciLexer.h" #include "LexerModule.h" +#include "CatalogueModules.h" #include "Catalogue.h" using namespace Scintilla; -static std::vector lexerCatalogue; -static int nextLanguage = SCLEX_AUTOMATIC+1; +namespace { + +CatalogueModules catalogueDefault; + +} const LexerModule *Catalogue::Find(int language) { - Scintilla_LinkLexers(); - for (const LexerModule *lm : lexerCatalogue) { - if (lm->GetLanguage() == language) { - return lm; - } - } - return nullptr; + return catalogueDefault.Find(language); } -const LexerModule *Catalogue::Find(const char *languageName) { - Scintilla_LinkLexers(); - if (languageName) { - for (const LexerModule *lm : lexerCatalogue) { - if (lm->languageName && (0 == strcmp(lm->languageName, languageName))) { - return lm; - } - } - } - return nullptr; +const LexerModule *Catalogue::Find(const char *languageName) noexcept { + return catalogueDefault.Find(languageName); } void Catalogue::AddLexerModule(LexerModule *plm) { - if (plm->GetLanguage() == SCLEX_AUTOMATIC) { - plm->language = nextLanguage; - nextLanguage++; - } - lexerCatalogue.push_back(plm); + catalogueDefault.AddLexerModule(plm); } // To add or remove a lexer, add or remove its file and run LexGen.py. @@ -67,8 +53,10 @@ int Scintilla_LinkLexers() { return 0; initialised = 1; +#if !defined(SCI_EMPTYCATALOGUE) + // Shorten the code that declares a lexer and ensures it is linked in by calling a method. -#define LINK_LEXER(lexer) extern LexerModule lexer; Catalogue::AddLexerModule(&lexer); +#define LINK_LEXER(lexer) extern LexerModule lexer; catalogueDefault.AddLexerModule(&lexer); //++Autogenerated -- run scripts/LexGen.py to regenerate //**\(\tLINK_LEXER(\*);\n\) @@ -121,5 +109,7 @@ int Scintilla_LinkLexers() { //--Autogenerated -- end of automatically generated section +#endif + return 1; } diff --git a/scintilla/src/Catalogue.h b/scintilla/src/Catalogue.h index d8769a8960..05a1f1d294 100644 --- a/scintilla/src/Catalogue.h +++ b/scintilla/src/Catalogue.h @@ -15,7 +15,7 @@ namespace Scintilla { class Catalogue { public: static const LexerModule *Find(int language); - static const LexerModule *Find(const char *languageName); + static const LexerModule *Find(const char *languageName) noexcept; static void AddLexerModule(LexerModule *plm); }; diff --git a/scintilla/src/CellBuffer.cxx b/scintilla/src/CellBuffer.cxx index 17a30a565a..661502d336 100644 --- a/scintilla/src/CellBuffer.cxx +++ b/scintilla/src/CellBuffer.cxx @@ -61,16 +61,17 @@ struct CountWidths { class ILineVector { public: virtual void Init() = 0; - virtual void SetPerLine(PerLine *pl) = 0; - virtual void InsertText(Sci::Line line, Sci::Position delta) = 0; + virtual void SetPerLine(PerLine *pl) noexcept = 0; + virtual void InsertText(Sci::Line line, Sci::Position delta) noexcept = 0; virtual void InsertLine(Sci::Line line, Sci::Position position, bool lineStart) = 0; + virtual void InsertLines(Sci::Line line, const Sci::Position *positions, size_t lines, bool lineStart) = 0; virtual void SetLineStart(Sci::Line line, Sci::Position position) noexcept = 0; virtual void RemoveLine(Sci::Line line) = 0; virtual Sci::Line Lines() const noexcept = 0; virtual Sci::Line LineFromPosition(Sci::Position pos) const noexcept = 0; virtual Sci::Position LineStart(Sci::Line line) const noexcept = 0; - virtual void InsertCharacters(Sci::Line line, CountWidths delta) = 0; - virtual void SetLineCharactersWidth(Sci::Line line, CountWidths width) = 0; + virtual void InsertCharacters(Sci::Line line, CountWidths delta) noexcept = 0; + virtual void SetLineCharactersWidth(Sci::Line line, CountWidths width) noexcept = 0; virtual int LineCharacterIndex() const noexcept = 0; virtual bool AllocateLineCharacterIndex(int lineCharacterIndex, Sci::Line lines) = 0; virtual bool ReleaseLineCharacterIndex(int lineCharacterIndex) = 0; @@ -98,7 +99,6 @@ class LineStartIndex { void operator=(const LineStartIndex &) = delete; void operator=(LineStartIndex &&) = delete; virtual ~LineStartIndex() { - starts.DeleteAll(); } bool Allocate(Sci::Line lines) { refCount++; @@ -124,10 +124,19 @@ class LineStartIndex { return starts.PositionFromPartition(static_cast(line) + 1) - starts.PositionFromPartition(static_cast(line)); } - void SetLineWidth(Sci::Line line, Sci::Position width) { + void SetLineWidth(Sci::Line line, Sci::Position width) noexcept { const Sci::Position widthCurrent = LineWidth(line); starts.InsertText(static_cast(line), static_cast(width - widthCurrent)); } + void InsertLines(Sci::Line line, Sci::Line lines) { + // Insert multiple lines with each temporarily 1 character wide. + // The line widths will be fixed up by later measuring code. + const POS lineAsPos = static_cast(line); + const POS lineStart = starts.PositionFromPartition(lineAsPos - 1) + 1; + for (POS l = 0; l < static_cast(lines); l++) { + starts.InsertPartition(lineAsPos + l, lineStart + l); + } + } }; template @@ -136,17 +145,23 @@ class LineVector : public ILineVector { PerLine *perLine; LineStartIndex startsUTF16; LineStartIndex startsUTF32; + int activeIndices; + + void SetActiveIndices() noexcept { + activeIndices = (startsUTF32.Active() ? SC_LINECHARACTERINDEX_UTF32 : 0) + | (startsUTF16.Active() ? SC_LINECHARACTERINDEX_UTF16 : 0); + } + public: - LineVector() : starts(256), perLine(nullptr) { - Init(); - } + LineVector() : starts(256), perLine(nullptr), activeIndices(0) { + } // Deleted so LineVector objects can not be copied. LineVector(const LineVector &) = delete; LineVector(LineVector &&) = delete; LineVector &operator=(const LineVector &) = delete; LineVector &operator=(LineVector &&) = delete; ~LineVector() override { - } + } void Init() override { starts.DeleteAll(); if (perLine) { @@ -155,22 +170,22 @@ class LineVector : public ILineVector { startsUTF32.starts.DeleteAll(); startsUTF16.starts.DeleteAll(); } - void SetPerLine(PerLine *pl) override { + void SetPerLine(PerLine *pl) noexcept override { perLine = pl; } - void InsertText(Sci::Line line, Sci::Position delta) override { + void InsertText(Sci::Line line, Sci::Position delta) noexcept override { starts.InsertText(static_cast(line), static_cast(delta)); } void InsertLine(Sci::Line line, Sci::Position position, bool lineStart) override { const POS lineAsPos = static_cast(line); starts.InsertPartition(lineAsPos, static_cast(position)); - if (startsUTF32.Active()) { - startsUTF32.starts.InsertPartition(lineAsPos, - static_cast(startsUTF32.starts.PositionFromPartition(lineAsPos - 1) + 1)); - } - if (startsUTF16.Active()) { - startsUTF16.starts.InsertPartition(lineAsPos, - static_cast(startsUTF16.starts.PositionFromPartition(lineAsPos - 1) + 1)); + if (activeIndices) { + if (activeIndices & SC_LINECHARACTERINDEX_UTF32) { + startsUTF32.InsertLines(line, 1); + } + if (activeIndices & SC_LINECHARACTERINDEX_UTF16) { + startsUTF16.InsertLines(line, 1); + } } if (perLine) { if ((line > 0) && lineStart) @@ -178,15 +193,36 @@ class LineVector : public ILineVector { perLine->InsertLine(line); } } + void InsertLines(Sci::Line line, const Sci::Position *positions, size_t lines, bool lineStart) override { + const POS lineAsPos = static_cast(line); + if (sizeof(Sci::Position) == sizeof(POS)) { + starts.InsertPartitions(lineAsPos, reinterpret_cast(positions), lines); + } else { + starts.InsertPartitionsWithCast(lineAsPos, positions, lines); + } + if (activeIndices) { + if (activeIndices & SC_LINECHARACTERINDEX_UTF32) { + startsUTF32.InsertLines(line, lines); + } + if (activeIndices & SC_LINECHARACTERINDEX_UTF16) { + startsUTF16.InsertLines(line, lines); + } + } + if (perLine) { + if ((line > 0) && lineStart) + line--; + perLine->InsertLines(line, lines); + } + } void SetLineStart(Sci::Line line, Sci::Position position) noexcept override { starts.SetPartitionStartPosition(static_cast(line), static_cast(position)); } void RemoveLine(Sci::Line line) override { starts.RemovePartition(static_cast(line)); - if (startsUTF32.Active()) { + if (activeIndices & SC_LINECHARACTERINDEX_UTF32) { startsUTF32.starts.RemovePartition(static_cast(line)); } - if (startsUTF16.Active()) { + if (activeIndices & SC_LINECHARACTERINDEX_UTF16) { startsUTF16.starts.RemovePartition(static_cast(line)); } if (perLine) { @@ -202,56 +238,51 @@ class LineVector : public ILineVector { Sci::Position LineStart(Sci::Line line) const noexcept override { return starts.PositionFromPartition(static_cast(line)); } - void InsertCharacters(Sci::Line line, CountWidths delta) override { - if (startsUTF32.Active()) { + void InsertCharacters(Sci::Line line, CountWidths delta) noexcept override { + if (activeIndices & SC_LINECHARACTERINDEX_UTF32) { startsUTF32.starts.InsertText(static_cast(line), static_cast(delta.WidthUTF32())); } - if (startsUTF16.Active()) { + if (activeIndices & SC_LINECHARACTERINDEX_UTF16) { startsUTF16.starts.InsertText(static_cast(line), static_cast(delta.WidthUTF16())); } } - void SetLineCharactersWidth(Sci::Line line, CountWidths width) override { - if (startsUTF32.Active()) { + void SetLineCharactersWidth(Sci::Line line, CountWidths width) noexcept override { + if (activeIndices & SC_LINECHARACTERINDEX_UTF32) { assert(startsUTF32.starts.Partitions() == starts.Partitions()); startsUTF32.SetLineWidth(line, width.WidthUTF32()); } - if (startsUTF16.Active()) { + if (activeIndices & SC_LINECHARACTERINDEX_UTF16) { assert(startsUTF16.starts.Partitions() == starts.Partitions()); startsUTF16.SetLineWidth(line, width.WidthUTF16()); } } int LineCharacterIndex() const noexcept override { - int retVal = 0; - if (startsUTF32.Active()) { - retVal |= SC_LINECHARACTERINDEX_UTF32; - } - if (startsUTF16.Active()) { - retVal |= SC_LINECHARACTERINDEX_UTF16; - } - return retVal; + return activeIndices; } bool AllocateLineCharacterIndex(int lineCharacterIndex, Sci::Line lines) override { - bool changed = false; + const int activeIndicesStart = activeIndices; if ((lineCharacterIndex & SC_LINECHARACTERINDEX_UTF32) != 0) { - changed = startsUTF32.Allocate(lines) || changed; + startsUTF32.Allocate(lines); assert(startsUTF32.starts.Partitions() == starts.Partitions()); } if ((lineCharacterIndex & SC_LINECHARACTERINDEX_UTF16) != 0) { - changed = startsUTF16.Allocate(lines) || changed; + startsUTF16.Allocate(lines); assert(startsUTF16.starts.Partitions() == starts.Partitions()); } - return changed; + SetActiveIndices(); + return activeIndicesStart != activeIndices; } bool ReleaseLineCharacterIndex(int lineCharacterIndex) override { - bool changed = false; + const int activeIndicesStart = activeIndices; if ((lineCharacterIndex & SC_LINECHARACTERINDEX_UTF32) != 0) { - changed = startsUTF32.Release() || changed; + startsUTF32.Release(); } if ((lineCharacterIndex & SC_LINECHARACTERINDEX_UTF16) != 0) { - changed = startsUTF16.Release() || changed; + startsUTF16.Release(); } - return changed; + SetActiveIndices(); + return activeIndicesStart != activeIndices; } Sci::Position IndexLineStart(Sci::Line line, int lineCharacterIndex) const noexcept override { if (lineCharacterIndex == SC_LINECHARACTERINDEX_UTF32) { @@ -269,7 +300,7 @@ class LineVector : public ILineVector { } }; -Action::Action() { +Action::Action() noexcept { at = startAction; position = 0; lenData = 0; @@ -284,14 +315,14 @@ void Action::Create(actionType at_, Sci::Position position_, const char *data_, position = position_; at = at_; if (lenData_) { - data = std::unique_ptr(new char[lenData_]); + data = Sci::make_unique(lenData_); memcpy(&data[0], data_, lenData_); } lenData = lenData_; mayCoalesce = mayCoalesce_; } -void Action::Clear() { +void Action::Clear() noexcept { data = nullptr; lenData = 0; } @@ -451,11 +482,11 @@ void UndoHistory::DeleteUndoHistory() { tentativePoint = -1; } -void UndoHistory::SetSavePoint() { +void UndoHistory::SetSavePoint() noexcept { savePoint = currentAction; } -bool UndoHistory::IsSavePoint() const { +bool UndoHistory::IsSavePoint() const noexcept { return savePoint == currentAction; } @@ -469,7 +500,11 @@ void UndoHistory::TentativeCommit() { maxAction = currentAction; } -int UndoHistory::TentativeSteps() { +bool UndoHistory::TentativeActive() const noexcept { + return tentativePoint >= 0; +} + +int UndoHistory::TentativeSteps() noexcept { // Drop any trailing startAction if (actions[currentAction].at == startAction && currentAction > 0) currentAction--; @@ -479,7 +514,7 @@ int UndoHistory::TentativeSteps() { return -1; } -bool UndoHistory::CanUndo() const { +bool UndoHistory::CanUndo() const noexcept { return (currentAction > 0) && (maxAction > 0); } @@ -504,7 +539,7 @@ void UndoHistory::CompletedUndoStep() { currentAction--; } -bool UndoHistory::CanRedo() const { +bool UndoHistory::CanRedo() const noexcept { return maxAction > currentAction; } @@ -536,9 +571,9 @@ CellBuffer::CellBuffer(bool hasStyles_, bool largeDocument_) : utf8LineEnds = 0; collectingUndo = true; if (largeDocument) - plv = std::unique_ptr>(new LineVector()); + plv = Sci::make_unique>(); else - plv = std::unique_ptr>(new LineVector()); + plv = Sci::make_unique>(); } CellBuffer::~CellBuffer() { @@ -558,8 +593,10 @@ void CellBuffer::GetCharRange(char *buffer, Sci::Position position, Sci::Positio if (position < 0) return; if ((position + lengthRetrieve) > substance.Length()) { - Platform::DebugPrintf("Bad GetCharRange %d for %d of %d\n", position, - lengthRetrieve, substance.Length()); + Platform::DebugPrintf("Bad GetCharRange %.0f for %.0f of %.0f\n", + static_cast(position), + static_cast(lengthRetrieve), + static_cast(substance.Length())); return; } substance.GetRange(buffer, position, lengthRetrieve); @@ -579,8 +616,10 @@ void CellBuffer::GetStyleRange(unsigned char *buffer, Sci::Position position, Sc return; } if ((position + lengthRetrieve) > style.Length()) { - Platform::DebugPrintf("Bad GetStyleRange %d for %d of %d\n", position, - lengthRetrieve, style.Length()); + Platform::DebugPrintf("Bad GetStyleRange %.0f for %.0f of %.0f\n", + static_cast(position), + static_cast(lengthRetrieve), + static_cast(style.Length())); return; } style.GetRange(reinterpret_cast(buffer), position, lengthRetrieve); @@ -590,11 +629,11 @@ const char *CellBuffer::BufferPointer() { return substance.BufferPointer(); } -const char *CellBuffer::RangePointer(Sci::Position position, Sci::Position rangeLength) { +const char *CellBuffer::RangePointer(Sci::Position position, Sci::Position rangeLength) noexcept { return substance.RangePointer(position, rangeLength); } -Sci::Position CellBuffer::GapPosition() const { +Sci::Position CellBuffer::GapPosition() const noexcept { return substance.GapPosition(); } @@ -614,7 +653,7 @@ const char *CellBuffer::InsertString(Sci::Position position, const char *s, Sci: return data; } -bool CellBuffer::SetStyleAt(Sci::Position position, char styleValue) { +bool CellBuffer::SetStyleAt(Sci::Position position, char styleValue) noexcept { if (!hasStyles) { return false; } @@ -627,7 +666,7 @@ bool CellBuffer::SetStyleAt(Sci::Position position, char styleValue) { } } -bool CellBuffer::SetStyleFor(Sci::Position position, Sci::Position lengthStyle, char styleValue) { +bool CellBuffer::SetStyleFor(Sci::Position position, Sci::Position lengthStyle, char styleValue) noexcept { if (!hasStyles) { return false; } @@ -674,11 +713,8 @@ void CellBuffer::Allocate(Sci::Position newSize) { } } -void CellBuffer::SetUTF8Substance(bool utf8Substance_) { - if (utf8Substance != utf8Substance_) { - utf8Substance = utf8Substance_; - ResetLineEnds(); - } +void CellBuffer::SetUTF8Substance(bool utf8Substance_) noexcept { + utf8Substance = utf8Substance_; } void CellBuffer::SetLineEndTypes(int utf8LineEnds_) { @@ -690,7 +726,7 @@ void CellBuffer::SetLineEndTypes(int utf8LineEnds_) { } } -bool CellBuffer::ContainsLineEnd(const char *s, Sci::Position length) const { +bool CellBuffer::ContainsLineEnd(const char *s, Sci::Position length) const noexcept { unsigned char chBeforePrev = 0; unsigned char chPrev = 0; for (Sci::Position i = 0; i < length; i++) { @@ -698,8 +734,7 @@ bool CellBuffer::ContainsLineEnd(const char *s, Sci::Position length) const { if ((ch == '\r') || (ch == '\n')) { return true; } else if (utf8LineEnds) { - const unsigned char back3[3] = { chBeforePrev, chPrev, ch }; - if (UTF8IsSeparator(back3) || UTF8IsNEL(back3 + 1)) { + if (UTF8IsMultibyteLineEnd(chBeforePrev, chPrev, ch)) { return true; } } @@ -709,7 +744,7 @@ bool CellBuffer::ContainsLineEnd(const char *s, Sci::Position length) const { return false; } -void CellBuffer::SetPerLine(PerLine *pl) { +void CellBuffer::SetPerLine(PerLine *pl) noexcept { plv->SetPerLine(pl); } @@ -755,19 +790,19 @@ Sci::Line CellBuffer::LineFromPositionIndex(Sci::Position pos, int lineCharacter return plv->LineFromPositionIndex(pos, lineCharacterIndex); } -bool CellBuffer::IsReadOnly() const { +bool CellBuffer::IsReadOnly() const noexcept { return readOnly; } -void CellBuffer::SetReadOnly(bool set) { +void CellBuffer::SetReadOnly(bool set) noexcept { readOnly = set; } -bool CellBuffer::IsLarge() const { +bool CellBuffer::IsLarge() const noexcept { return largeDocument; } -bool CellBuffer::HasStyles() const { +bool CellBuffer::HasStyles() const noexcept { return hasStyles; } @@ -775,7 +810,7 @@ void CellBuffer::SetSavePoint() { uh.SetSavePoint(); } -bool CellBuffer::IsSavePoint() const { +bool CellBuffer::IsSavePoint() const noexcept { return uh.IsSavePoint(); } @@ -787,11 +822,11 @@ void CellBuffer::TentativeCommit() { uh.TentativeCommit(); } -int CellBuffer::TentativeSteps() { +int CellBuffer::TentativeSteps() noexcept { return uh.TentativeSteps(); } -bool CellBuffer::TentativeActive() const { +bool CellBuffer::TentativeActive() const noexcept { return uh.TentativeActive(); } @@ -805,7 +840,7 @@ void CellBuffer::RemoveLine(Sci::Line line) { plv->RemoveLine(line); } -bool CellBuffer::UTF8LineEndOverlaps(Sci::Position position) const { +bool CellBuffer::UTF8LineEndOverlaps(Sci::Position position) const noexcept { const unsigned char bytes[] = { static_cast(substance.ValueAt(position-2)), static_cast(substance.ValueAt(position-1)), @@ -871,8 +906,7 @@ void CellBuffer::ResetLineEnds() { lineInsert++; } } else if (utf8LineEnds) { - const unsigned char back3[3] = {chBeforePrev, chPrev, ch}; - if (UTF8IsSeparator(back3) || UTF8IsNEL(back3+1)) { + if (UTF8IsMultibyteLineEnd(chBeforePrev, chPrev, ch)) { InsertLine(lineInsert, (position + i) + 1, atLineStart); lineInsert++; } @@ -963,33 +997,95 @@ void CellBuffer::BasicInsertString(Sci::Position position, const char *s, Sci::P if (breakingUTF8LineEnd) { RemoveLine(lineInsert); } - unsigned char ch = ' '; - for (Sci::Position i = 0; i < insertLength; i++) { - ch = s[i]; - if (ch == '\r') { - InsertLine(lineInsert, (position + i) + 1, atLineStart); - lineInsert++; - simpleInsertion = false; - } else if (ch == '\n') { - if (chPrev == '\r') { - // Patch up what was end of line - plv->SetLineStart(lineInsert - 1, (position + i) + 1); - } else { - InsertLine(lineInsert, (position + i) + 1, atLineStart); - lineInsert++; + + constexpr size_t PositionBlockSize = 128; + Sci::Position positions[PositionBlockSize]{}; + size_t nPositions = 0; + const Sci::Line lineStart = lineInsert; + + // s may not NULL-terminated, ensure *ptr == '\n' or *next == '\n' is valid. + const char * const end = s + insertLength - 1; + const char *ptr = s; + unsigned char ch = 0; + + if (chPrev == '\r' && *ptr == '\n') { + ++ptr; + // Patch up what was end of line + plv->SetLineStart(lineInsert - 1, (position + ptr - s)); + simpleInsertion = false; + } + + if (ptr < end) { + uint8_t eolTable[256]{}; + eolTable[static_cast('\n')] = 1; + eolTable[static_cast('\r')] = 2; + if (utf8LineEnds) { + // see UniConversion.h for LS, PS and NEL + eolTable[0x85] = 4; + eolTable[0xa8] = 3; + eolTable[0xa9] = 3; + } + + do { + // skip to line end + ch = *ptr++; + uint8_t type; + while ((type = eolTable[ch]) == 0 && ptr < end) { + chBeforePrev = chPrev; + chPrev = ch; + ch = *ptr++; } - simpleInsertion = false; - } else if (utf8LineEnds) { - const unsigned char back3[3] = {chBeforePrev, chPrev, ch}; - if (UTF8IsSeparator(back3) || UTF8IsNEL(back3+1)) { - InsertLine(lineInsert, (position + i) + 1, atLineStart); + switch (type) { + case 2: // '\r' + if (*ptr == '\n') { + ++ptr; + } + case 1: // '\n' + positions[nPositions++] = position + ptr - s; + if (nPositions == PositionBlockSize) { + plv->InsertLines(lineInsert, positions, nPositions, atLineStart); + lineInsert += nPositions; + nPositions = 0; + } + break; + case 3: + case 4: + // LS, PS and NEL + if ((type == 3 && chPrev == 0x80 && chBeforePrev == 0xe2) || (type == 4 && chPrev == 0xc2)) { + positions[nPositions++] = position + ptr - s; + if (nPositions == PositionBlockSize) { + plv->InsertLines(lineInsert, positions, nPositions, atLineStart); + lineInsert += nPositions; + nPositions = 0; + } + } + break; + } + + chBeforePrev = chPrev; + chPrev = ch; + } while (ptr < end); + } + + if (nPositions != 0) { + plv->InsertLines(lineInsert, positions, nPositions, atLineStart); + lineInsert += nPositions; + } + + ch = *end; + if (ptr == end) { + ++ptr; + if (ch == '\r' || ch == '\n') { + InsertLine(lineInsert, (position + ptr - s), atLineStart); + lineInsert++; + } else if (utf8LineEnds && !UTF8IsAscii(ch)) { + if (UTF8IsMultibyteLineEnd(chBeforePrev, chPrev, ch)) { + InsertLine(lineInsert, (position + ptr - s), atLineStart); lineInsert++; - simpleInsertion = false; } } - chBeforePrev = chPrev; - chPrev = ch; } + // Joining two lines where last insertion is cr and following substance starts with lf if (chAfter == '\n') { if (ch == '\r') { @@ -998,6 +1094,8 @@ void CellBuffer::BasicInsertString(Sci::Position position, const char *s, Sci::P simpleInsertion = false; } } else if (utf8LineEnds && !UTF8IsAscii(chAfter)) { + chBeforePrev = chPrev; + chPrev = ch; // May have end of UTF-8 line end in buffer and start in insertion for (int j = 0; j < UTF8SeparatorLength-1; j++) { const unsigned char chAt = substance.ValueAt(position + insertLength + j); @@ -1005,19 +1103,17 @@ void CellBuffer::BasicInsertString(Sci::Position position, const char *s, Sci::P if (UTF8IsSeparator(back3)) { InsertLine(lineInsert, (position + insertLength + j) + 1, atLineStart); lineInsert++; - simpleInsertion = false; } if ((j == 0) && UTF8IsNEL(back3+1)) { InsertLine(lineInsert, (position + insertLength + j) + 1, atLineStart); lineInsert++; - simpleInsertion = false; } chBeforePrev = chPrev; chPrev = chAt; } } if (maintainingIndex) { - if (simpleInsertion) { + if (simpleInsertion && (lineInsert == lineStart)) { const CountWidths cw = CountCharacterWidthsUTF8(s, insertLength); plv->InsertCharacters(linePosition, cw); } else { @@ -1133,7 +1229,7 @@ bool CellBuffer::SetUndoCollection(bool collectUndo) { return collectingUndo; } -bool CellBuffer::IsCollectingUndo() const { +bool CellBuffer::IsCollectingUndo() const noexcept { return collectingUndo; } @@ -1154,7 +1250,7 @@ void CellBuffer::DeleteUndoHistory() { uh.DeleteUndoHistory(); } -bool CellBuffer::CanUndo() const { +bool CellBuffer::CanUndo() const noexcept { return uh.CanUndo(); } @@ -1180,7 +1276,7 @@ void CellBuffer::PerformUndoStep() { uh.CompletedUndoStep(); } -bool CellBuffer::CanRedo() const { +bool CellBuffer::CanRedo() const noexcept { return uh.CanRedo(); } diff --git a/scintilla/src/CellBuffer.h b/scintilla/src/CellBuffer.h index 7d56822605..599b6062f4 100644 --- a/scintilla/src/CellBuffer.h +++ b/scintilla/src/CellBuffer.h @@ -16,6 +16,7 @@ class PerLine { virtual ~PerLine() {} virtual void Init()=0; virtual void InsertLine(Sci::Line line)=0; + virtual void InsertLines(Sci::Line line, Sci::Line lines) = 0; virtual void RemoveLine(Sci::Line line)=0; }; @@ -37,7 +38,7 @@ class Action { Sci::Position lenData; bool mayCoalesce; - Action(); + Action() noexcept; // Deleted so Action objects can not be copied. Action(const Action &other) = delete; Action &operator=(const Action &other) = delete; @@ -46,7 +47,7 @@ class Action { Action(Action &&other) noexcept = default; ~Action(); void Create(actionType at_, Sci::Position position_=0, const char *data_=nullptr, Sci::Position lenData_=0, bool mayCoalesce_=true); - void Clear(); + void Clear() noexcept; }; /** @@ -80,22 +81,22 @@ class UndoHistory { /// The save point is a marker in the undo stack where the container has stated that /// the buffer was saved. Undo and redo can move over the save point. - void SetSavePoint(); - bool IsSavePoint() const; + void SetSavePoint() noexcept; + bool IsSavePoint() const noexcept; // Tentative actions are used for input composition so that it can be undone cleanly void TentativeStart(); void TentativeCommit(); - bool TentativeActive() const noexcept { return tentativePoint >= 0; } - int TentativeSteps(); + bool TentativeActive() const noexcept; + int TentativeSteps() noexcept; /// To perform an undo, StartUndo is called to retrieve the number of steps, then UndoStep is /// called that many times. Similarly for redo. - bool CanUndo() const; + bool CanUndo() const noexcept; int StartUndo(); const Action &GetUndoStep() const; void CompletedUndoStep(); - bool CanRedo() const; + bool CanRedo() const noexcept; int StartRedo(); const Action &GetRedoStep() const; void CompletedRedoStep(); @@ -121,7 +122,7 @@ class CellBuffer { std::unique_ptr plv; - bool UTF8LineEndOverlaps(Sci::Position position) const; + bool UTF8LineEndOverlaps(Sci::Position position) const noexcept; bool UTF8IsCharacterBoundary(Sci::Position position) const; void ResetLineEnds(); void RecalculateIndexLineStarts(Sci::Line lineFirst, Sci::Line lineLast); @@ -147,16 +148,16 @@ class CellBuffer { char StyleAt(Sci::Position position) const noexcept; void GetStyleRange(unsigned char *buffer, Sci::Position position, Sci::Position lengthRetrieve) const; const char *BufferPointer(); - const char *RangePointer(Sci::Position position, Sci::Position rangeLength); - Sci::Position GapPosition() const; + const char *RangePointer(Sci::Position position, Sci::Position rangeLength) noexcept; + Sci::Position GapPosition() const noexcept; Sci::Position Length() const noexcept; void Allocate(Sci::Position newSize); - void SetUTF8Substance(bool utf8Substance_); - int GetLineEndTypes() const { return utf8LineEnds; } + void SetUTF8Substance(bool utf8Substance_) noexcept; + int GetLineEndTypes() const noexcept { return utf8LineEnds; } void SetLineEndTypes(int utf8LineEnds_); - bool ContainsLineEnd(const char *s, Sci::Position length) const; - void SetPerLine(PerLine *pl); + bool ContainsLineEnd(const char *s, Sci::Position length) const noexcept; + void SetPerLine(PerLine *pl) noexcept; int LineCharacterIndex() const noexcept; void AllocateLineCharacterIndex(int lineCharacterIndex); void ReleaseLineCharacterIndex(int lineCharacterIndex); @@ -171,28 +172,28 @@ class CellBuffer { /// 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); - bool SetStyleFor(Sci::Position position, Sci::Position lengthStyle, char styleValue); + bool SetStyleAt(Sci::Position position, char styleValue) noexcept; + bool SetStyleFor(Sci::Position position, Sci::Position lengthStyle, char styleValue) noexcept; const char *DeleteChars(Sci::Position position, Sci::Position deleteLength, bool &startSequence); - bool IsReadOnly() const; - void SetReadOnly(bool set); - bool IsLarge() const; - bool HasStyles() const; + bool IsReadOnly() const noexcept; + void SetReadOnly(bool set) noexcept; + bool IsLarge() const noexcept; + bool HasStyles() const noexcept; /// The save point is a marker in the undo stack where the container has stated that /// the buffer was saved. Undo and redo can move over the save point. void SetSavePoint(); - bool IsSavePoint() const; + bool IsSavePoint() const noexcept; void TentativeStart(); void TentativeCommit(); - bool TentativeActive() const; - int TentativeSteps(); + bool TentativeActive() const noexcept; + int TentativeSteps() noexcept; bool SetUndoCollection(bool collectUndo); - bool IsCollectingUndo() const; + bool IsCollectingUndo() const noexcept; void BeginUndoAction(); void EndUndoAction(); void AddUndoAction(Sci::Position token, bool mayCoalesce); @@ -200,11 +201,11 @@ class CellBuffer { /// To perform an undo, StartUndo is called to retrieve the number of steps, then UndoStep is /// called that many times. Similarly for redo. - bool CanUndo() const; + bool CanUndo() const noexcept; int StartUndo(); const Action &GetUndoStep() const; void PerformUndoStep(); - bool CanRedo() const; + bool CanRedo() const noexcept; int StartRedo(); const Action &GetRedoStep() const; void PerformRedoStep(); diff --git a/scintilla/src/CharClassify.cxx b/scintilla/src/CharClassify.cxx index 5ae47a2ef7..b5e2870f36 100644 --- a/scintilla/src/CharClassify.cxx +++ b/scintilla/src/CharClassify.cxx @@ -34,7 +34,7 @@ void CharClassify::SetDefaultCharClasses(bool includeWordClass) { } void CharClassify::SetCharClasses(const unsigned char *chars, cc newCharClass) { - // Apply the newCharClass to the specifed chars + // Apply the newCharClass to the specified chars if (chars) { while (*chars) { charClass[*chars] = static_cast(newCharClass); @@ -43,7 +43,7 @@ void CharClassify::SetCharClasses(const unsigned char *chars, cc newCharClass) { } } -int CharClassify::GetCharsOfClass(cc characterClass, unsigned char *buffer) const { +int CharClassify::GetCharsOfClass(cc characterClass, unsigned char *buffer) const noexcept { // Get characters belonging to the given char class; return the number // of characters (if the buffer is NULL, don't write to it). int count = 0; diff --git a/scintilla/src/CharClassify.h b/scintilla/src/CharClassify.h index c1ca3c1208..36cc345586 100644 --- a/scintilla/src/CharClassify.h +++ b/scintilla/src/CharClassify.h @@ -17,9 +17,9 @@ class CharClassify { enum cc { ccSpace, ccNewLine, ccWord, ccPunctuation }; void SetDefaultCharClasses(bool includeWordClass); void SetCharClasses(const unsigned char *chars, cc newCharClass); - int GetCharsOfClass(cc characterClass, unsigned char *buffer) const; - cc GetClass(unsigned char ch) const { return static_cast(charClass[ch]);} - bool IsWord(unsigned char ch) const { return static_cast(charClass[ch]) == ccWord;} + int GetCharsOfClass(cc characterClass, unsigned char *buffer) const noexcept; + cc GetClass(unsigned char ch) const noexcept { return static_cast(charClass[ch]);} + bool IsWord(unsigned char ch) const noexcept { return static_cast(charClass[ch]) == ccWord;} private: enum { maxChar=256 }; diff --git a/scintilla/src/ContractionState.cxx b/scintilla/src/ContractionState.cxx index 47f345ada8..8897f3d957 100644 --- a/scintilla/src/ContractionState.cxx +++ b/scintilla/src/ContractionState.cxx @@ -60,32 +60,32 @@ class ContractionState final : public IContractionState { void Clear() noexcept override; - Sci::Line LinesInDoc() const override; - Sci::Line LinesDisplayed() const override; - Sci::Line DisplayFromDoc(Sci::Line lineDoc) const override; - Sci::Line DisplayLastFromDoc(Sci::Line lineDoc) const override; - Sci::Line DocFromDisplay(Sci::Line lineDisplay) const override; + Sci::Line LinesInDoc() const noexcept override; + Sci::Line LinesDisplayed() const noexcept override; + Sci::Line DisplayFromDoc(Sci::Line lineDoc) const noexcept override; + Sci::Line DisplayLastFromDoc(Sci::Line lineDoc) const noexcept override; + Sci::Line DocFromDisplay(Sci::Line lineDisplay) const noexcept override; void InsertLines(Sci::Line lineDoc, Sci::Line lineCount) override; void DeleteLines(Sci::Line lineDoc, Sci::Line lineCount) override; - bool GetVisible(Sci::Line lineDoc) const override; + bool GetVisible(Sci::Line lineDoc) const noexcept override; bool SetVisible(Sci::Line lineDocStart, Sci::Line lineDocEnd, bool isVisible) override; - bool HiddenLines() const override; + bool HiddenLines() const noexcept override; - const char *GetFoldDisplayText(Sci::Line lineDoc) const override; + const char *GetFoldDisplayText(Sci::Line lineDoc) const noexcept override; bool SetFoldDisplayText(Sci::Line lineDoc, const char *text) override; - bool GetExpanded(Sci::Line lineDoc) const override; + bool GetExpanded(Sci::Line lineDoc) const noexcept override; bool SetExpanded(Sci::Line lineDoc, bool isExpanded) override; - Sci::Line ContractedNext(Sci::Line lineDocStart) const override; + Sci::Line ContractedNext(Sci::Line lineDocStart) const noexcept override; - int GetHeight(Sci::Line lineDoc) const override; + int GetHeight(Sci::Line lineDoc) const noexcept override; bool SetHeight(Sci::Line lineDoc, int height) override; - void ShowAll() override; + void ShowAll() noexcept override; - void Check() const; + void Check() const noexcept; }; template @@ -100,11 +100,11 @@ ContractionState::~ContractionState() { template void ContractionState::EnsureData() { if (OneToOne()) { - visible = std::unique_ptr>(new RunStyles()); - expanded = std::unique_ptr>(new RunStyles()); - heights = std::unique_ptr>(new RunStyles()); - foldDisplayTexts = std::unique_ptr>(new SparseVector()); - displayLines = std::unique_ptr>(new Partitioning(4)); + visible = Sci::make_unique>(); + expanded = Sci::make_unique>(); + heights = Sci::make_unique>(); + foldDisplayTexts = Sci::make_unique>(); + displayLines = Sci::make_unique>(4); InsertLines(0, linesInDocument); } } @@ -157,7 +157,7 @@ void ContractionState::Clear() noexcept { } template -Sci::Line ContractionState::LinesInDoc() const { +Sci::Line ContractionState::LinesInDoc() const noexcept { if (OneToOne()) { return linesInDocument; } else { @@ -166,7 +166,7 @@ Sci::Line ContractionState::LinesInDoc() const { } template -Sci::Line ContractionState::LinesDisplayed() const { +Sci::Line ContractionState::LinesDisplayed() const noexcept { if (OneToOne()) { return linesInDocument; } else { @@ -175,7 +175,7 @@ Sci::Line ContractionState::LinesDisplayed() const { } template -Sci::Line ContractionState::DisplayFromDoc(Sci::Line lineDoc) const { +Sci::Line ContractionState::DisplayFromDoc(Sci::Line lineDoc) const noexcept { if (OneToOne()) { return (lineDoc <= linesInDocument) ? lineDoc : linesInDocument; } else { @@ -186,12 +186,12 @@ Sci::Line ContractionState::DisplayFromDoc(Sci::Line lineDoc) const { } template -Sci::Line ContractionState::DisplayLastFromDoc(Sci::Line lineDoc) const { +Sci::Line ContractionState::DisplayLastFromDoc(Sci::Line lineDoc) const noexcept { return DisplayFromDoc(lineDoc) + GetHeight(lineDoc) - 1; } template -Sci::Line ContractionState::DocFromDisplay(Sci::Line lineDisplay) const { +Sci::Line ContractionState::DocFromDisplay(Sci::Line lineDisplay) const noexcept { if (OneToOne()) { return lineDisplay; } else { @@ -209,22 +209,30 @@ Sci::Line ContractionState::DocFromDisplay(Sci::Line lineDisplay) const { template void ContractionState::InsertLines(Sci::Line lineDoc, Sci::Line lineCount) { - for (Sci::Line l = 0; l < lineCount; l++) { - InsertLine(lineDoc + l); + if (OneToOne()) { + linesInDocument += static_cast(lineCount); + } else { + for (Sci::Line l = 0; l < lineCount; l++) { + InsertLine(lineDoc + l); + } } Check(); } template void ContractionState::DeleteLines(Sci::Line lineDoc, Sci::Line lineCount) { - for (Sci::Line l = 0; l < lineCount; l++) { - DeleteLine(lineDoc); + if (OneToOne()) { + linesInDocument -= static_cast(lineCount); + } else { + for (Sci::Line l = 0; l < lineCount; l++) { + DeleteLine(lineDoc); + } } Check(); } template -bool ContractionState::GetVisible(Sci::Line lineDoc) const { +bool ContractionState::GetVisible(Sci::Line lineDoc) const noexcept { if (OneToOne()) { return true; } else { @@ -261,7 +269,7 @@ bool ContractionState::SetVisible(Sci::Line lineDocStart, Sci::Line lineDo } template -bool ContractionState::HiddenLines() const { +bool ContractionState::HiddenLines() const noexcept { if (OneToOne()) { return false; } else { @@ -270,7 +278,7 @@ bool ContractionState::HiddenLines() const { } template -const char *ContractionState::GetFoldDisplayText(Sci::Line lineDoc) const { +const char *ContractionState::GetFoldDisplayText(Sci::Line lineDoc) const noexcept { Check(); return foldDisplayTexts->ValueAt(lineDoc).get(); } @@ -291,7 +299,7 @@ bool ContractionState::SetFoldDisplayText(Sci::Line lineDoc, const char *t } template -bool ContractionState::GetExpanded(Sci::Line lineDoc) const { +bool ContractionState::GetExpanded(Sci::Line lineDoc) const noexcept { if (OneToOne()) { return true; } else { @@ -318,7 +326,7 @@ bool ContractionState::SetExpanded(Sci::Line lineDoc, bool isExpanded) { } template -Sci::Line ContractionState::ContractedNext(Sci::Line lineDocStart) const { +Sci::Line ContractionState::ContractedNext(Sci::Line lineDocStart) const noexcept { if (OneToOne()) { return -1; } else { @@ -336,7 +344,7 @@ Sci::Line ContractionState::ContractedNext(Sci::Line lineDocStart) const { } template -int ContractionState::GetHeight(Sci::Line lineDoc) const { +int ContractionState::GetHeight(Sci::Line lineDoc) const noexcept { if (OneToOne()) { return 1; } else { @@ -369,7 +377,7 @@ bool ContractionState::SetHeight(Sci::Line lineDoc, int height) { } template -void ContractionState::ShowAll() { +void ContractionState::ShowAll() noexcept { const LINE lines = static_cast(LinesInDoc()); Clear(); linesInDocument = lines; @@ -378,7 +386,7 @@ void ContractionState::ShowAll() { // Debugging checks template -void ContractionState::Check() const { +void ContractionState::Check() const noexcept { #ifdef CHECK_CORRECTNESS for (Sci::Line vline = 0; vline < LinesDisplayed(); vline++) { const Sci::Line lineDoc = DocFromDisplay(vline); @@ -404,9 +412,9 @@ namespace Scintilla { std::unique_ptr ContractionStateCreate(bool largeDocument) { if (largeDocument) - return std::unique_ptr>(new ContractionState()); + return Sci::make_unique>(); else - return std::unique_ptr>(new ContractionState()); + return Sci::make_unique>(); } } diff --git a/scintilla/src/ContractionState.h b/scintilla/src/ContractionState.h index f9ec7b6454..b30d071b4c 100644 --- a/scintilla/src/ContractionState.h +++ b/scintilla/src/ContractionState.h @@ -18,30 +18,30 @@ class IContractionState { virtual void Clear()=0; - virtual Sci::Line LinesInDoc() const=0; - virtual Sci::Line LinesDisplayed() const=0; - virtual Sci::Line DisplayFromDoc(Sci::Line lineDoc) const=0; - virtual Sci::Line DisplayLastFromDoc(Sci::Line lineDoc) const=0; - virtual Sci::Line DocFromDisplay(Sci::Line lineDisplay) const=0; + virtual Sci::Line LinesInDoc() const noexcept=0; + virtual Sci::Line LinesDisplayed() const noexcept=0; + virtual Sci::Line DisplayFromDoc(Sci::Line lineDoc) const noexcept=0; + virtual Sci::Line DisplayLastFromDoc(Sci::Line lineDoc) const noexcept=0; + virtual Sci::Line DocFromDisplay(Sci::Line lineDisplay) const noexcept=0; virtual void InsertLines(Sci::Line lineDoc, Sci::Line lineCount)=0; virtual void DeleteLines(Sci::Line lineDoc, Sci::Line lineCount)=0; - virtual bool GetVisible(Sci::Line lineDoc) const=0; + virtual bool GetVisible(Sci::Line lineDoc) const noexcept=0; virtual bool SetVisible(Sci::Line lineDocStart, Sci::Line lineDocEnd, bool isVisible)=0; - virtual bool HiddenLines() const=0; + virtual bool HiddenLines() const noexcept=0; - virtual const char *GetFoldDisplayText(Sci::Line lineDoc) const=0; + virtual const char *GetFoldDisplayText(Sci::Line lineDoc) const noexcept=0; virtual bool SetFoldDisplayText(Sci::Line lineDoc, const char *text)=0; - virtual bool GetExpanded(Sci::Line lineDoc) const=0; + virtual bool GetExpanded(Sci::Line lineDoc) const noexcept=0; virtual bool SetExpanded(Sci::Line lineDoc, bool isExpanded)=0; - virtual Sci::Line ContractedNext(Sci::Line lineDocStart) const=0; + virtual Sci::Line ContractedNext(Sci::Line lineDocStart) const noexcept =0; - virtual int GetHeight(Sci::Line lineDoc) const=0; + virtual int GetHeight(Sci::Line lineDoc) const noexcept=0; virtual bool SetHeight(Sci::Line lineDoc, int height)=0; - virtual void ShowAll()=0; + virtual void ShowAll() noexcept=0; }; std::unique_ptr ContractionStateCreate(bool largeDocument); diff --git a/scintilla/src/Decoration.cxx b/scintilla/src/Decoration.cxx index 104f75ae24..4bfff2d01f 100644 --- a/scintilla/src/Decoration.cxx +++ b/scintilla/src/Decoration.cxx @@ -39,22 +39,22 @@ class Decoration : public IDecoration { ~Decoration() override { } - bool Empty() const override { + bool Empty() const noexcept override { return (rs.Runs() == 1) && (rs.AllSameAs(0)); } - int Indicator() const override { + int Indicator() const noexcept override { return indicator; } - Sci::Position Length() const override { + Sci::Position Length() const noexcept override { return rs.Length(); } - int ValueAt(Sci::Position position) const override { + int ValueAt(Sci::Position position) const noexcept override { return rs.ValueAt(static_cast(position)); } - Sci::Position StartRun(Sci::Position position) const override { + Sci::Position StartRun(Sci::Position position) const noexcept override { return rs.StartRun(static_cast(position)); } - Sci::Position EndRun(Sci::Position position) const override { + Sci::Position EndRun(Sci::Position position) const noexcept override { return rs.EndRun(static_cast(position)); } void SetValueAt(Sci::Position position, int value) override { @@ -63,7 +63,7 @@ class Decoration : public IDecoration { void InsertSpace(Sci::Position position, Sci::Position insertLength) override { rs.InsertSpace(static_cast(position), static_cast(insertLength)); } - Sci::Position Runs() const override { + Sci::Position Runs() const noexcept override { return rs.Runs(); } }; @@ -79,7 +79,7 @@ class DecorationList : public IDecorationList { std::vector decorationView; // Read-only view of decorationList bool clickNotified; - Decoration *DecorationFromIndicator(int indicator); + Decoration *DecorationFromIndicator(int indicator) noexcept; Decoration *Create(int indicator, Sci::Position length); void Delete(int indicator); void DeleteAnyEmpty(); @@ -89,15 +89,15 @@ class DecorationList : public IDecorationList { DecorationList(); ~DecorationList() override; - const std::vector &View() const override { + const std::vector &View() const noexcept override { return decorationView; } void SetCurrentIndicator(int indicator) override; - int GetCurrentIndicator() const override { return currentIndicator; } + int GetCurrentIndicator() const noexcept override { return currentIndicator; } void SetCurrentValue(int value) override; - int GetCurrentValue() const override { return currentValue; } + int GetCurrentValue() const noexcept override { return currentValue; } // Returns changed=true if some values may have changed FillResult FillRange(Sci::Position position, int value, Sci::Position fillLength) override; @@ -107,15 +107,15 @@ class DecorationList : public IDecorationList { void DeleteLexerDecorations() override; - int AllOnFor(Sci::Position position) const override; - int ValueAt(int indicator, Sci::Position position) override; - Sci::Position Start(int indicator, Sci::Position position) override; - Sci::Position End(int indicator, Sci::Position position) override; + int AllOnFor(Sci::Position position) const noexcept override; + int ValueAt(int indicator, Sci::Position position) noexcept override; + Sci::Position Start(int indicator, Sci::Position position) noexcept override; + Sci::Position End(int indicator, Sci::Position position) noexcept override; - bool ClickNotified() const override { + bool ClickNotified() const noexcept override { return clickNotified; } - void SetClickNotified(bool notified) override { + void SetClickNotified(bool notified) noexcept override { clickNotified = notified; } }; @@ -131,7 +131,7 @@ DecorationList::~DecorationList() { } template -Decoration *DecorationList::DecorationFromIndicator(int indicator) { +Decoration *DecorationList::DecorationFromIndicator(int indicator) noexcept { for (const std::unique_ptr> &deco : decorationList) { if (deco->Indicator() == indicator) { return deco.get(); @@ -143,12 +143,12 @@ Decoration *DecorationList::DecorationFromIndicator(int indicator) { template Decoration *DecorationList::Create(int indicator, Sci::Position length) { currentIndicator = indicator; - std::unique_ptr> decoNew = std::unique_ptr>(new Decoration(indicator)); + std::unique_ptr> decoNew = Sci::make_unique>(indicator); decoNew->rs.InsertSpace(0, static_cast(length)); typename std::vector>>::iterator it = std::lower_bound( decorationList.begin(), decorationList.end(), decoNew, - [](const std::unique_ptr> &a, const std::unique_ptr> &b) { + [](const std::unique_ptr> &a, const std::unique_ptr> &b) noexcept { return a->Indicator() < b->Indicator(); }); typename std::vector>>::iterator itAdded = @@ -162,7 +162,7 @@ Decoration *DecorationList::Create(int indicator, Sci::Position length template void DecorationList::Delete(int indicator) { decorationList.erase(std::remove_if(decorationList.begin(), decorationList.end(), - [indicator](const std::unique_ptr> &deco) { + [indicator](const std::unique_ptr> &deco) noexcept { return deco->Indicator() == indicator; }), decorationList.end()); current = nullptr; @@ -227,8 +227,8 @@ void DecorationList::DeleteRange(Sci::Position position, Sci::Position dele template void DecorationList::DeleteLexerDecorations() { decorationList.erase(std::remove_if(decorationList.begin(), decorationList.end(), - [](const std::unique_ptr> &deco) { - return deco->Indicator() < INDIC_CONTAINER; + [](const std::unique_ptr> &deco) noexcept { + return deco->Indicator() < INDICATOR_CONTAINER ; }), decorationList.end()); current = nullptr; SetView(); @@ -240,7 +240,7 @@ void DecorationList::DeleteAnyEmpty() { decorationList.clear(); } else { decorationList.erase(std::remove_if(decorationList.begin(), decorationList.end(), - [](const std::unique_ptr> &deco) { + [](const std::unique_ptr> &deco) noexcept { return deco->Empty(); }), decorationList.end()); } @@ -255,11 +255,11 @@ void DecorationList::SetView() { } template -int DecorationList::AllOnFor(Sci::Position position) const { +int DecorationList::AllOnFor(Sci::Position position) const noexcept { int mask = 0; for (const std::unique_ptr> &deco : decorationList) { if (deco->rs.ValueAt(static_cast(position))) { - if (deco->Indicator() < INDIC_IME) { + if (deco->Indicator() < INDICATOR_IME) { mask |= 1 << deco->Indicator(); } } @@ -268,7 +268,7 @@ int DecorationList::AllOnFor(Sci::Position position) const { } template -int DecorationList::ValueAt(int indicator, Sci::Position position) { +int DecorationList::ValueAt(int indicator, Sci::Position position) noexcept { const Decoration *deco = DecorationFromIndicator(indicator); if (deco) { return deco->rs.ValueAt(static_cast(position)); @@ -277,7 +277,7 @@ int DecorationList::ValueAt(int indicator, Sci::Position position) { } template -Sci::Position DecorationList::Start(int indicator, Sci::Position position) { +Sci::Position DecorationList::Start(int indicator, Sci::Position position) noexcept { const Decoration *deco = DecorationFromIndicator(indicator); if (deco) { return deco->rs.StartRun(static_cast(position)); @@ -286,7 +286,7 @@ Sci::Position DecorationList::Start(int indicator, Sci::Position position) } template -Sci::Position DecorationList::End(int indicator, Sci::Position position) { +Sci::Position DecorationList::End(int indicator, Sci::Position position) noexcept { const Decoration *deco = DecorationFromIndicator(indicator); if (deco) { return deco->rs.EndRun(static_cast(position)); @@ -300,16 +300,16 @@ namespace Scintilla { std::unique_ptr DecorationCreate(bool largeDocument, int indicator) { if (largeDocument) - return std::unique_ptr>(new Decoration(indicator)); + return Sci::make_unique>(indicator); else - return std::unique_ptr>(new Decoration(indicator)); + return Sci::make_unique>(indicator); } std::unique_ptr DecorationListCreate(bool largeDocument) { if (largeDocument) - return std::unique_ptr>(new DecorationList()); + return Sci::make_unique>(); else - return std::unique_ptr>(new DecorationList()); + return Sci::make_unique>(); } } diff --git a/scintilla/src/Decoration.h b/scintilla/src/Decoration.h index 1461f2f983..bab8e2500f 100644 --- a/scintilla/src/Decoration.h +++ b/scintilla/src/Decoration.h @@ -12,28 +12,28 @@ namespace Scintilla { class IDecoration { public: virtual ~IDecoration() {} - virtual bool Empty() const = 0; - virtual int Indicator() const = 0; - virtual Sci::Position Length() const = 0; - virtual int ValueAt(Sci::Position position) const = 0; - virtual Sci::Position StartRun(Sci::Position position) const = 0; - virtual Sci::Position EndRun(Sci::Position position) const = 0; + virtual bool Empty() const noexcept = 0; + virtual int Indicator() const noexcept = 0; + virtual Sci::Position Length() const noexcept = 0; + virtual int ValueAt(Sci::Position position) const noexcept = 0; + virtual Sci::Position StartRun(Sci::Position position) const noexcept = 0; + virtual Sci::Position EndRun(Sci::Position position) const noexcept = 0; virtual void SetValueAt(Sci::Position position, int value) = 0; virtual void InsertSpace(Sci::Position position, Sci::Position insertLength) = 0; - virtual Sci::Position Runs() const = 0; + virtual Sci::Position Runs() const noexcept = 0; }; class IDecorationList { public: virtual ~IDecorationList() {} - virtual const std::vector &View() const =0; + virtual const std::vector &View() const noexcept = 0; virtual void SetCurrentIndicator(int indicator) = 0; - virtual int GetCurrentIndicator() const = 0; + virtual int GetCurrentIndicator() const noexcept = 0; virtual void SetCurrentValue(int value) = 0; - virtual int GetCurrentValue() const = 0; + virtual int GetCurrentValue() const noexcept = 0; // Returns with changed=true if some values may have changed virtual FillResult FillRange(Sci::Position position, int value, Sci::Position fillLength) = 0; @@ -41,13 +41,13 @@ class IDecorationList { virtual void DeleteRange(Sci::Position position, Sci::Position deleteLength) = 0; virtual void DeleteLexerDecorations() = 0; - virtual int AllOnFor(Sci::Position position) const = 0; - virtual int ValueAt(int indicator, Sci::Position position) = 0; - virtual Sci::Position Start(int indicator, Sci::Position position) = 0; - virtual Sci::Position End(int indicator, Sci::Position position) = 0; + virtual int AllOnFor(Sci::Position position) const noexcept = 0; + virtual int ValueAt(int indicator, Sci::Position position) noexcept = 0; + virtual Sci::Position Start(int indicator, Sci::Position position) noexcept = 0; + virtual Sci::Position End(int indicator, Sci::Position position) noexcept = 0; - virtual bool ClickNotified() const = 0; - virtual void SetClickNotified(bool notified) = 0; + virtual bool ClickNotified() const noexcept = 0; + virtual void SetClickNotified(bool notified) noexcept = 0; }; std::unique_ptr DecorationCreate(bool largeDocument, int indicator); diff --git a/scintilla/src/Document.cxx b/scintilla/src/Document.cxx index dd11ae42dc..f4681a5eda 100644 --- a/scintilla/src/Document.cxx +++ b/scintilla/src/Document.cxx @@ -98,7 +98,7 @@ void ActionDuration::AddSample(size_t numberActions, double durationOfActions) n // Alpha value for exponential smoothing. // Most recent value contributes 25% to smoothed value. - const double alpha = 0.25; + constexpr double alpha = 0.25; const double durationOne = durationOfActions / numberActions; duration = Sci::clamp(alpha * durationOne + (1.0 - alpha) * duration, @@ -135,11 +135,12 @@ Document::Document(int options) : matchesValid = false; - perLineData[ldMarkers].reset(new LineMarkers()); - perLineData[ldLevels].reset(new LineLevels()); - perLineData[ldState].reset(new LineState()); - perLineData[ldMargin].reset(new LineAnnotation()); - perLineData[ldAnnotation].reset(new LineAnnotation()); + perLineData[ldMarkers] = Sci::make_unique(); + perLineData[ldLevels] = Sci::make_unique(); + perLineData[ldState] = Sci::make_unique(); + perLineData[ldMargin] = Sci::make_unique(); + perLineData[ldAnnotation] = Sci::make_unique(); + perLineData[ldEOLAnnotation] = Sci::make_unique(); decorations = DecorationListCreate(IsLarge()); @@ -181,6 +182,13 @@ void Document::InsertLine(Sci::Line line) { } } +void Document::InsertLines(Sci::Line line, Sci::Line lines) { + for (const auto &pl : perLineData) { + if (pl) + pl->InsertLines(line, lines); + } +} + void Document::RemoveLine(Sci::Line line) { for (const std::unique_ptr &pl : perLineData) { if (pl) @@ -188,24 +196,28 @@ void Document::RemoveLine(Sci::Line line) { } } -LineMarkers *Document::Markers() const { - return static_cast(perLineData[ldMarkers].get()); +LineMarkers *Document::Markers() const noexcept { + return dynamic_cast(perLineData[ldMarkers].get()); } -LineLevels *Document::Levels() const { - return static_cast(perLineData[ldLevels].get()); +LineLevels *Document::Levels() const noexcept { + return dynamic_cast(perLineData[ldLevels].get()); } -LineState *Document::States() const { - return static_cast(perLineData[ldState].get()); +LineState *Document::States() const noexcept { + return dynamic_cast(perLineData[ldState].get()); } -LineAnnotation *Document::Margins() const { - return static_cast(perLineData[ldMargin].get()); +LineAnnotation *Document::Margins() const noexcept { + return dynamic_cast(perLineData[ldMargin].get()); } -LineAnnotation *Document::Annotations() const { - return static_cast(perLineData[ldAnnotation].get()); +LineAnnotation *Document::Annotations() const noexcept { + return dynamic_cast(perLineData[ldAnnotation].get()); +} + +LineAnnotation *Document::EOLAnnotations() const noexcept { + return dynamic_cast(perLineData[ldEOLAnnotation].get()); } int Document::LineEndTypesSupported() const { @@ -310,11 +322,11 @@ void Document::TentativeUndo() { } } -int Document::GetMark(Sci::Line line) const { +int Document::GetMark(Sci::Line line) const noexcept { return Markers()->MarkValue(line); } -Sci::Line Document::MarkerNext(Sci::Line lineStart, int mask) const { +Sci::Line Document::MarkerNext(Sci::Line lineStart, int mask) const noexcept { return Markers()->MarkerNext(lineStart, mask); } @@ -368,12 +380,20 @@ void Document::DeleteAllMarks(int markerNum) { } } -Sci::Line Document::LineFromHandle(int markerHandle) const { +Sci::Line Document::LineFromHandle(int markerHandle) const noexcept { return Markers()->LineFromHandle(markerHandle); } +int Document::MarkerNumberFromLine(Sci::Line line, int which) const noexcept { + return Markers()->NumberFromLine(line, which); +} + +int Document::MarkerHandleFromLine(Sci::Line line, int which) const noexcept { + return Markers()->HandleFromLine(line, which); +} + Sci_Position SCI_METHOD Document::LineStart(Sci_Position line) const { - return cb.LineStart(static_cast(line)); + return cb.LineStart(line); } bool Document::IsLineStartPosition(Sci::Position position) const { @@ -385,7 +405,7 @@ Sci_Position SCI_METHOD Document::LineEnd(Sci_Position line) const { return LineStart(line + 1); } else { Sci::Position position = LineStart(line + 1); - if (SC_CP_UTF8 == dbcsCodePage) { + if (SC_LINE_END_TYPE_UNICODE == cb.GetLineEndTypes()) { const unsigned char bytes[] = { cb.UCharAt(position-3), cb.UCharAt(position-2), @@ -448,19 +468,19 @@ Sci::Position Document::VCHomePosition(Sci::Position position) const { return startText; } -Sci::Position Document::IndexLineStart(Sci::Line line, int lineCharacterIndex) const { +Sci::Position Document::IndexLineStart(Sci::Line line, int lineCharacterIndex) const noexcept { return cb.IndexLineStart(line, lineCharacterIndex); } -Sci::Line Document::LineFromPositionIndex(Sci::Position pos, int lineCharacterIndex) const { +Sci::Line Document::LineFromPositionIndex(Sci::Position pos, int lineCharacterIndex) const noexcept { return cb.LineFromPositionIndex(pos, lineCharacterIndex); } int SCI_METHOD Document::SetLevel(Sci_Position line, int level) { - const int prev = Levels()->SetLevel(static_cast(line), level, LinesTotal()); + const int prev = Levels()->SetLevel(line, level, LinesTotal()); if (prev != level) { DocModification mh(SC_MOD_CHANGEFOLD | SC_MOD_CHANGEMARKER, - LineStart(line), 0, 0, nullptr, static_cast(line)); + LineStart(line), 0, 0, nullptr, line); mh.foldLevelNow = level; mh.foldLevelPrev = prev; NotifyModified(mh); @@ -469,7 +489,7 @@ int SCI_METHOD Document::SetLevel(Sci_Position line, int level) { } int SCI_METHOD Document::GetLevel(Sci_Position line) const { - return Levels()->GetLevel(static_cast(line)); + return Levels()->GetLevel(line); } void Document::ClearLevels() { @@ -595,35 +615,50 @@ void Document::GetHighlightDelimiters(HighlightDelimiter &highlightDelimiter, Sc highlightDelimiter.firstChangeableLineAfter = firstChangeableLineAfter; } -Sci::Position Document::ClampPositionIntoDocument(Sci::Position pos) const { +Sci::Position Document::ClampPositionIntoDocument(Sci::Position pos) const noexcept { return Sci::clamp(pos, static_cast(0), static_cast(Length())); } -bool Document::IsCrLf(Sci::Position pos) const { +bool Document::IsCrLf(Sci::Position pos) const noexcept { if (pos < 0) return false; - if (pos >= (Length() - 1)) + if (pos >= (LengthNoExcept() - 1)) return false; return (cb.CharAt(pos) == '\r') && (cb.CharAt(pos + 1) == '\n'); } -int Document::LenChar(Sci::Position pos) { - if (pos < 0) { +int Document::LenChar(Sci::Position pos) const noexcept { + if (pos < 0 || pos >= LengthNoExcept()) { + // Returning 1 instead of 0 to defend against hanging with a loop that goes (or starts) out of bounds. return 1; } else if (IsCrLf(pos)) { return 2; - } else if (SC_CP_UTF8 == dbcsCodePage) { - const unsigned char leadByte = cb.UCharAt(pos); + } + + const unsigned char leadByte = cb.UCharAt(pos); + if (!dbcsCodePage || UTF8IsAscii(leadByte)) { + // Common case: ASCII character + return 1; + } + if (SC_CP_UTF8 == dbcsCodePage) { const int widthCharBytes = UTF8BytesOfLead[leadByte]; - const Sci::Position lengthDoc = Length(); - if ((pos + widthCharBytes) > lengthDoc) - return static_cast(lengthDoc - pos); - else - return widthCharBytes; - } else if (dbcsCodePage) { - return IsDBCSLeadByteNoExcept(cb.CharAt(pos)) ? 2 : 1; + unsigned char charBytes[UTF8MaxBytes] = { leadByte, 0, 0, 0 }; + for (int b = 1; b < widthCharBytes; b++) { + charBytes[b] = cb.UCharAt(pos + b); + } + const int utf8status = UTF8Classify(charBytes, widthCharBytes); + if (utf8status & UTF8MaskInvalid) { + // Treat as invalid and use up just one byte + return 1; + } else { + return utf8status & UTF8MaskWidth; + } } else { - return 1; + if (IsDBCSLeadByteNoExcept(leadByte) && ((pos + 1) < LengthNoExcept())) { + return 2; + } else { + return 1; + } } } @@ -659,15 +694,15 @@ bool Document::InGoodUTF8(Sci::Position pos, Sci::Position &start, Sci::Position // When lines are terminated with \r\n pairs which should be treated as one character. // When displaying DBCS text such as Japanese. // If moving, move the position in the indicated direction. -Sci::Position Document::MovePositionOutsideChar(Sci::Position pos, Sci::Position moveDir, bool checkLineEnd) const { +Sci::Position Document::MovePositionOutsideChar(Sci::Position pos, Sci::Position moveDir, bool checkLineEnd) const noexcept { //Platform::DebugPrintf("NoCRLF %d %d\n", pos, moveDir); // If out of range, just return minimum/maximum value. if (pos <= 0) return 0; - if (pos >= Length()) - return Length(); + if (pos >= LengthNoExcept()) + return LengthNoExcept(); - // PLATFORM_ASSERT(pos > 0 && pos < Length()); + // PLATFORM_ASSERT(pos > 0 && pos < LengthNoExcept()); if (checkLineEnd && IsCrLf(pos - 1)) { if (moveDir > 0) return pos + 1; @@ -694,7 +729,7 @@ Sci::Position Document::MovePositionOutsideChar(Sci::Position pos, Sci::Position } else { // Anchor DBCS calculations at start of line because start of line can // not be a DBCS trail byte. - const Sci::Position posStartLine = LineStart(LineFromPosition(pos)); + const Sci::Position posStartLine = cb.LineStart(cb.LineFromPosition(pos)); if (pos == posStartLine) return pos; @@ -815,8 +850,8 @@ bool Document::NextCharacter(Sci::Position &pos, int moveDir) const noexcept { } } -Document::CharacterExtracted Document::CharacterAfter(Sci::Position position) const { - if (position >= Length()) { +Document::CharacterExtracted Document::CharacterAfter(Sci::Position position) const noexcept { + if (position >= LengthNoExcept()) { return CharacterExtracted(unicodeReplacementChar, 0); } const unsigned char leadByte = cb.UCharAt(position); @@ -837,7 +872,7 @@ Document::CharacterExtracted Document::CharacterAfter(Sci::Position position) co return CharacterExtracted(UnicodeFromUTF8(charBytes), utf8status & UTF8MaskWidth); } } else { - if (IsDBCSLeadByteNoExcept(leadByte) && ((position + 1) < Length())) { + if (IsDBCSLeadByteNoExcept(leadByte) && ((position + 1) < LengthNoExcept())) { return CharacterExtracted::DBCS(leadByte, cb.UCharAt(position + 1)); } else { return CharacterExtracted(leadByte, 1); @@ -845,7 +880,7 @@ Document::CharacterExtracted Document::CharacterAfter(Sci::Position position) co } } -Document::CharacterExtracted Document::CharacterBefore(Sci::Position position) const { +Document::CharacterExtracted Document::CharacterBefore(Sci::Position position) const noexcept { if (position <= 0) { return CharacterExtracted(unicodeReplacementChar, 0); } @@ -864,9 +899,9 @@ Document::CharacterExtracted Document::CharacterBefore(Sci::Position position) c Sci::Position startUTF = position; Sci::Position endUTF = position; if (InGoodUTF8(position, startUTF, endUTF)) { - const int widthCharBytes = static_cast(endUTF - startUTF); + const Sci::Position widthCharBytes = endUTF - startUTF; unsigned char charBytes[UTF8MaxBytes] = { 0, 0, 0, 0 }; - for (int b = 0; b 0) ? 1 : -1; @@ -921,7 +956,7 @@ Sci::Position Document::GetRelativePositionUTF16(Sci::Position positionStart, Sc } } else { pos = positionStart + characterOffset; - if ((pos < 0) || (pos > Length())) + if ((pos < 0) || (pos > LengthNoExcept())) return INVALID_POSITION; } return pos; @@ -1143,11 +1178,11 @@ int Document::SafeSegment(const char *text, int length, int lengthSegment) const EncodingFamily Document::CodePageFamily() const noexcept { if (SC_CP_UTF8 == dbcsCodePage) - return efUnicode; + return EncodingFamily::unicode; else if (dbcsCodePage) - return efDBCS; + return EncodingFamily::dbcs; else - return efEightBit; + return EncodingFamily::eightBit; } void Document::ModifiedAt(Sci::Position pos) noexcept { @@ -1171,7 +1206,7 @@ bool Document::DeleteChars(Sci::Position pos, Sci::Position len) { return false; if (len <= 0) return false; - if ((pos + len) > Length()) + if ((pos + len) > LengthNoExcept()) return false; CheckReadOnly(); if (enteredModification != 0) { @@ -1189,8 +1224,8 @@ bool Document::DeleteChars(Sci::Position pos, Sci::Position len) { bool startSequence = false; const char *text = cb.DeleteChars(pos, len, startSequence); if (startSavePoint && cb.IsCollectingUndo()) - NotifySavePoint(!startSavePoint); - if ((pos < Length()) || (pos == 0)) + NotifySavePoint(false); + if ((pos < LengthNoExcept()) || (pos == 0)) ModifiedAt(pos); else ModifiedAt(pos-1); @@ -1241,7 +1276,7 @@ Sci::Position Document::InsertString(Sci::Position position, const char *s, Sci: bool startSequence = false; const char *text = cb.InsertString(position, s, insertLength, startSequence); if (startSavePoint && cb.IsCollectingUndo()) - NotifySavePoint(!startSavePoint); + NotifySavePoint(false); ModifiedAt(position); NotifyModified( DocModification( @@ -1527,7 +1562,7 @@ Sci::Position Document::GetColumn(Sci::Position pos) { return column; } -Sci::Position Document::CountCharacters(Sci::Position startPos, Sci::Position endPos) const { +Sci::Position Document::CountCharacters(Sci::Position startPos, Sci::Position endPos) const noexcept { startPos = MovePositionOutsideChar(startPos, 1, false); endPos = MovePositionOutsideChar(endPos, -1, false); Sci::Position count = 0; @@ -1539,7 +1574,7 @@ Sci::Position Document::CountCharacters(Sci::Position startPos, Sci::Position en return count; } -Sci::Position Document::CountUTF16(Sci::Position startPos, Sci::Position endPos) const { +Sci::Position Document::CountUTF16(Sci::Position startPos, Sci::Position endPos) const noexcept { startPos = MovePositionOutsideChar(startPos, 1, false); endPos = MovePositionOutsideChar(endPos, -1, false); Sci::Position count = 0; @@ -1654,7 +1689,7 @@ void Document::ConvertLineEnds(int eolModeSet) { } -int Document::Options() const { +int Document::Options() const noexcept { return (IsLarge() ? SC_DOCUMENTOPTION_TEXT_LARGE : 0) | (cb.HasStyles() ? 0 : SC_DOCUMENTOPTION_STYLES_NONE); } @@ -1698,14 +1733,6 @@ Sci::Position Document::ParaDown(Sci::Position pos) const { return LineEnd(line-1); } -bool Document::IsASCIIWordByte(unsigned char ch) const { - if (IsASCII(ch)) { - return charClass.GetClass(ch) == CharClassify::ccWord; - } else { - return false; - } -} - CharClassify::cc Document::WordCharacterClass(unsigned int ch) const { if (dbcsCodePage && (!UTF8IsAscii(ch))) { if (SC_CP_UTF8 == dbcsCodePage) { @@ -1769,7 +1796,7 @@ CharClassify::cc Document::WordCharacterClass(unsigned int ch) const { } /** - * Used by commmands that want to select whole words. + * Used by commands that want to select whole words. * Finds the start of word at pos when delta < 0 or the end of the word when delta >= 0. */ Sci::Position Document::ExtendWordSelect(Sci::Position pos, int delta, bool onlyWordCharacters) const { @@ -1786,11 +1813,11 @@ Sci::Position Document::ExtendWordSelect(Sci::Position pos, int delta, bool only pos -= ce.widthBytes; } } else { - if (!onlyWordCharacters && pos < Length()) { + if (!onlyWordCharacters && pos < LengthNoExcept()) { const CharacterExtracted ce = CharacterAfter(pos); ccStart = WordCharacterClass(ce.character); } - while (pos < Length()) { + while (pos < LengthNoExcept()) { const CharacterExtracted ce = CharacterAfter(pos); if (WordCharacterClass(ce.character) != ccStart) break; @@ -1828,13 +1855,13 @@ Sci::Position Document::NextWordStart(Sci::Position pos, int delta) const { } else { CharacterExtracted ce = CharacterAfter(pos); const CharClassify::cc ccStart = WordCharacterClass(ce.character); - while (pos < Length()) { + while (pos < LengthNoExcept()) { ce = CharacterAfter(pos); if (WordCharacterClass(ce.character) != ccStart) break; pos += ce.widthBytes; } - while (pos < Length()) { + while (pos < LengthNoExcept()) { ce = CharacterAfter(pos); if (WordCharacterClass(ce.character) != CharClassify::ccSpace) break; @@ -1872,16 +1899,16 @@ Sci::Position Document::NextWordEnd(Sci::Position pos, int delta) const { } } } else { - while (pos < Length()) { + while (pos < LengthNoExcept()) { const CharacterExtracted ce = CharacterAfter(pos); if (WordCharacterClass(ce.character) != CharClassify::ccSpace) break; pos += ce.widthBytes; } - if (pos < Length()) { + if (pos < LengthNoExcept()) { CharacterExtracted ce = CharacterAfter(pos); const CharClassify::cc ccStart = WordCharacterClass(ce.character); - while (pos < Length()) { + while (pos < LengthNoExcept()) { ce = CharacterAfter(pos); if (WordCharacterClass(ce.character) != ccStart) break; @@ -1897,7 +1924,7 @@ Sci::Position Document::NextWordEnd(Sci::Position pos, int delta) const { * the previous character is of a different character class. */ bool Document::IsWordStartAt(Sci::Position pos) const { - if (pos >= Length()) + if (pos >= LengthNoExcept()) return false; if (pos > 0) { const CharacterExtracted cePos = CharacterAfter(pos); @@ -1917,7 +1944,7 @@ bool Document::IsWordStartAt(Sci::Position pos) const { bool Document::IsWordEndAt(Sci::Position pos) const { if (pos <= 0) return false; - if (pos < Length()) { + if (pos < LengthNoExcept()) { const CharacterExtracted cePos = CharacterAfter(pos); const CharClassify::cc ccPos = WordCharacterClass(cePos.character); const CharacterExtracted cePrev = CharacterBefore(pos); @@ -1946,7 +1973,7 @@ bool Document::HasCaseFolder() const noexcept { return pcf != nullptr; } -void Document::SetCaseFolder(CaseFolder *pcf_) { +void Document::SetCaseFolder(CaseFolder *pcf_) noexcept { pcf.reset(pcf_); } @@ -2022,7 +2049,7 @@ Sci::Position Document::FindText(Sci::Position minPos, Sci::Position maxPos, con break; } } else if (SC_CP_UTF8 == dbcsCodePage) { - const size_t maxFoldingExpansion = 4; + constexpr size_t maxFoldingExpansion = 4; std::vector searchThing((lengthFind+1) * UTF8MaxBytes * maxFoldingExpansion + 1); const size_t lenSearch = pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind); @@ -2074,8 +2101,8 @@ Sci::Position Document::FindText(Sci::Position minPos, Sci::Position maxPos, con } } } else if (dbcsCodePage) { - const size_t maxBytesCharacter = 2; - const size_t maxFoldingExpansion = 4; + constexpr size_t maxBytesCharacter = 2; + constexpr size_t maxFoldingExpansion = 4; std::vector searchThing((lengthFind+1) * maxBytesCharacter * maxFoldingExpansion + 1); const size_t lenSearch = pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind); while (forward ? (pos < endPos) : (pos >= endPos)) { @@ -2141,7 +2168,7 @@ const char *Document::SubstituteByPosition(const char *text, Sci::Position *leng return nullptr; } -int Document::LineCharacterIndex() const { +int Document::LineCharacterIndex() const noexcept { return cb.LineCharacterIndex(); } @@ -2258,16 +2285,16 @@ void Document::LexerChanged() { } } -LexInterface *Document::GetLexInterface() const { +LexInterface *Document::GetLexInterface() const noexcept { return pli.get(); } -void Document::SetLexInterface(LexInterface *pLexInterface) { - pli.reset(pLexInterface); +void Document::SetLexInterface(std::unique_ptr pLexInterface) noexcept { + pli = std::move(pLexInterface); } int SCI_METHOD Document::SetLineState(Sci_Position line, int state) { - const int statePrevious = States()->SetLineState(static_cast(line), state); + const int statePrevious = States()->SetLineState(line, state); if (state != statePrevious) { const DocModification mh(SC_MOD_CHANGELINESTATE, LineStart(line), 0, 0, nullptr, static_cast(line)); @@ -2277,10 +2304,10 @@ int SCI_METHOD Document::SetLineState(Sci_Position line, int state) { } int SCI_METHOD Document::GetLineState(Sci_Position line) const { - return States()->GetLineState(static_cast(line)); + return States()->GetLineState(line); } -Sci::Line Document::GetMaxLineState() const { +Sci::Line Document::GetMaxLineState() const noexcept { return States()->GetMaxLineState(); } @@ -2290,7 +2317,7 @@ void SCI_METHOD Document::ChangeLexerState(Sci_Position start, Sci_Position end) NotifyModified(mh); } -StyledText Document::MarginStyledText(Sci::Line line) const { +StyledText Document::MarginStyledText(Sci::Line line) const noexcept { const LineAnnotation *pla = Margins(); return StyledText(pla->Length(line), pla->Text(line), pla->MultipleStyles(line), pla->Style(line), pla->Styles(line)); @@ -2323,7 +2350,7 @@ void Document::MarginClearAll() { Margins()->ClearAll(); } -StyledText Document::AnnotationStyledText(Sci::Line line) const { +StyledText Document::AnnotationStyledText(Sci::Line line) const noexcept { const LineAnnotation *pla = Annotations(); return StyledText(pla->Length(line), pla->Text(line), pla->MultipleStyles(line), pla->Style(line), pla->Styles(line)); @@ -2342,10 +2369,12 @@ void Document::AnnotationSetText(Sci::Line line, const char *text) { } void Document::AnnotationSetStyle(Sci::Line line, int style) { - Annotations()->SetStyle(line, style); - const DocModification mh(SC_MOD_CHANGEANNOTATION, LineStart(line), - 0, 0, 0, line); - NotifyModified(mh); + if (line >= 0 && line < LinesTotal()) { + Annotations()->SetStyle(line, style); + const DocModification mh(SC_MOD_CHANGEANNOTATION, LineStart(line), + 0, 0, 0, line); + NotifyModified(mh); + } } void Document::AnnotationSetStyles(Sci::Line line, const unsigned char *styles) { @@ -2354,7 +2383,7 @@ void Document::AnnotationSetStyles(Sci::Line line, const unsigned char *styles) } } -int Document::AnnotationLines(Sci::Line line) const { +int Document::AnnotationLines(Sci::Line line) const noexcept { return Annotations()->Lines(line); } @@ -2366,6 +2395,38 @@ void Document::AnnotationClearAll() { Annotations()->ClearAll(); } +StyledText Document::EOLAnnotationStyledText(Sci::Line line) const noexcept { + const LineAnnotation *pla = EOLAnnotations(); + return StyledText(pla->Length(line), pla->Text(line), + pla->MultipleStyles(line), pla->Style(line), pla->Styles(line)); +} + +void Document::EOLAnnotationSetText(Sci::Line line, const char *text) { + if (line >= 0 && line < LinesTotal()) { + EOLAnnotations()->SetText(line, text); + const DocModification mh(SC_MOD_CHANGEEOLANNOTATION, LineStart(line), + 0, 0, 0, line); + NotifyModified(mh); + } +} + +void Document::EOLAnnotationSetStyle(Sci::Line line, int style) { + if (line >= 0 && line < LinesTotal()) { + EOLAnnotations()->SetStyle(line, style); + const DocModification mh(SC_MOD_CHANGEEOLANNOTATION, LineStart(line), + 0, 0, 0, line); + NotifyModified(mh); + } +} + +void Document::EOLAnnotationClearAll() { + const Sci::Line maxEditorLine = LinesTotal(); + for (Sci::Line l=0; lClearAll(); +} + void Document::IncrementStyleClock() noexcept { styleClock = (styleClock + 1) % 0x100000; } @@ -2524,7 +2585,7 @@ Sci::Position Document::WordPartLeft(Sci::Position pos) const { Sci::Position Document::WordPartRight(Sci::Position pos) const { CharacterExtracted ceStart = CharacterAfter(pos); - const Sci::Position length = Length(); + const Sci::Position length = LengthNoExcept(); if (IsWordPartSeparator(ceStart.character)) { while (pos < length && IsWordPartSeparator(CharacterAfter(pos).character)) pos += CharacterAfter(pos).widthBytes; @@ -2566,14 +2627,14 @@ static constexpr bool IsLineEndChar(char c) noexcept { return (c == '\n' || c == '\r'); } -Sci::Position Document::ExtendStyleRange(Sci::Position pos, int delta, bool singleLine) { +Sci::Position Document::ExtendStyleRange(Sci::Position pos, int delta, bool singleLine) noexcept { const int sStart = cb.StyleAt(pos); if (delta < 0) { while (pos > 0 && (cb.StyleAt(pos) == sStart) && (!singleLine || !IsLineEndChar(cb.CharAt(pos)))) pos--; pos++; } else { - while (pos < (Length()) && (cb.StyleAt(pos) == sStart) && (!singleLine || !IsLineEndChar(cb.CharAt(pos)))) + while (pos < (LengthNoExcept()) && (cb.StyleAt(pos) == sStart) && (!singleLine || !IsLineEndChar(cb.CharAt(pos)))) pos++; } return pos; @@ -2603,7 +2664,7 @@ static char BraceOpposite(char ch) noexcept { } // TODO: should be able to extend styled region to find matching brace -Sci::Position Document::BraceMatch(Sci::Position position, Sci::Position /*maxReStyle*/) { +Sci::Position Document::BraceMatch(Sci::Position position, Sci::Position /*maxReStyle*/, Sci::Position startPos, bool useStartPos) noexcept { const char chBrace = CharAt(position); const char chSeek = BraceOpposite(chBrace); if (chSeek == '\0') @@ -2613,8 +2674,8 @@ Sci::Position Document::BraceMatch(Sci::Position position, Sci::Position /*maxRe if (chBrace == '(' || chBrace == '[' || chBrace == '{' || chBrace == '<') direction = 1; int depth = 1; - position = NextPosition(position, direction); - while ((position >= 0) && (position < Length())) { + position = useStartPos ? startPos : NextPosition(position, direction); + while ((position >= 0) && (position < LengthNoExcept())) { const char chAtPos = CharAt(position); const int styAtPos = StyleIndexAt(position); if ((position > GetEndStyled()) || (styAtPos == styBrace)) { @@ -2670,7 +2731,7 @@ class RESearchRange { Sci::Line lineRangeStart; Sci::Line lineRangeEnd; Sci::Line lineRangeBreak; - RESearchRange(const Document *doc_, Sci::Position minPos, Sci::Position maxPos) : doc(doc_) { + RESearchRange(const Document *doc_, Sci::Position minPos, Sci::Position maxPos) noexcept : doc(doc_) { increment = (minPos <= maxPos) ? 1 : -1; // Range endpoints should not be inside DBCS characters or between a CR and LF, @@ -3059,7 +3120,7 @@ Sci::Position Cxx11RegexFindText(const Document *doc, Sci::Position minPos, Sci: try { //ElapsedPeriod ep; std::regex::flag_type flagsRe = std::regex::ECMAScript; - // Flags that apper to have no effect: + // Flags that appear to have no effect: // | std::regex::collate | std::regex::extended; if (!caseSensitive) flagsRe = flagsRe | std::regex::icase; diff --git a/scintilla/src/Document.h b/scintilla/src/Document.h index adbdc34138..a314247394 100644 --- a/scintilla/src/Document.h +++ b/scintilla/src/Document.h @@ -18,7 +18,7 @@ class LineLevels; class LineState; class LineAnnotation; -enum EncodingFamily { efEightBit, efUnicode, efDBCS }; +enum class EncodingFamily { eightBit, unicode, dbcs }; /** * The range class represents a range of text in a document. @@ -137,23 +137,23 @@ class HighlightDelimiter { firstChangeableLineAfter = -1; } - bool NeedsDrawing(Sci::Line line) const { + bool NeedsDrawing(Sci::Line line) const noexcept { return isEnabled && (line <= firstChangeableLineBefore || line >= firstChangeableLineAfter); } - bool IsFoldBlockHighlighted(Sci::Line line) const { + bool IsFoldBlockHighlighted(Sci::Line line) const noexcept { return isEnabled && beginFoldBlock != -1 && beginFoldBlock <= line && line <= endFoldBlock; } - bool IsHeadOfFoldBlock(Sci::Line line) const { + bool IsHeadOfFoldBlock(Sci::Line line) const noexcept { return beginFoldBlock == line && line < endFoldBlock; } - bool IsBodyOfFoldBlock(Sci::Line line) const { + bool IsBodyOfFoldBlock(Sci::Line line) const noexcept { return beginFoldBlock != -1 && beginFoldBlock < line && line < endFoldBlock; } - bool IsTailOfFoldBlock(Sci::Line line) const { + bool IsTailOfFoldBlock(Sci::Line line) const noexcept { return beginFoldBlock != -1 && beginFoldBlock < line && line == endFoldBlock; } @@ -244,13 +244,14 @@ class Document : PerLine, public IDocumentWithLineEnd, public ILoader { std::vector watchers; // ldSize is not real data - it is for dimensions and loops - enum lineData { ldMarkers, ldLevels, ldState, ldMargin, ldAnnotation, ldSize }; + enum lineData { ldMarkers, ldLevels, ldState, ldMargin, ldAnnotation, ldEOLAnnotation, ldSize }; std::unique_ptr perLineData[ldSize]; - LineMarkers *Markers() const; - LineLevels *Levels() const; - LineState *States() const; - LineAnnotation *Margins() const; - LineAnnotation *Annotations() const; + LineMarkers *Markers() const noexcept; + LineLevels *Levels() const noexcept; + LineState *States() const noexcept; + LineAnnotation *Margins() const noexcept; + LineAnnotation *Annotations() const noexcept; + LineAnnotation *EOLAnnotations() const noexcept; bool matchesValid; std::unique_ptr regex; @@ -298,13 +299,14 @@ class Document : PerLine, public IDocumentWithLineEnd, public ILoader { // From PerLine void Init() override; void InsertLine(Sci::Line line) override; + void InsertLines(Sci::Line line, Sci::Line lines) override; void RemoveLine(Sci::Line line) override; int LineEndTypesSupported() const; bool SetDBCSCodePage(int dbcsCodePage_); - int GetLineEndTypesAllowed() const { return cb.GetLineEndTypes(); } + int GetLineEndTypesAllowed() const noexcept { return cb.GetLineEndTypes(); } bool SetLineEndTypesAllowed(int lineEndBitSet_); - int GetLineEndTypesActive() const { return cb.GetLineEndTypes(); } + int GetLineEndTypesActive() const noexcept { return cb.GetLineEndTypes(); } int SCI_METHOD Version() const override { return dvLineEnd; @@ -314,18 +316,18 @@ class Document : PerLine, public IDocumentWithLineEnd, public ILoader { Sci_Position SCI_METHOD LineFromPosition(Sci_Position pos) const override; Sci::Line SciLineFromPosition(Sci::Position pos) const noexcept; // Avoids casting LineFromPosition - Sci::Position ClampPositionIntoDocument(Sci::Position pos) const; - bool ContainsLineEnd(const char *s, Sci::Position length) const { return cb.ContainsLineEnd(s, length); } - bool IsCrLf(Sci::Position pos) const; - int LenChar(Sci::Position pos); + Sci::Position ClampPositionIntoDocument(Sci::Position pos) const noexcept; + bool ContainsLineEnd(const char *s, Sci::Position length) const noexcept { return cb.ContainsLineEnd(s, length); } + bool IsCrLf(Sci::Position pos) const noexcept; + int LenChar(Sci::Position pos) const noexcept; bool InGoodUTF8(Sci::Position pos, Sci::Position &start, Sci::Position &end) const noexcept; - Sci::Position MovePositionOutsideChar(Sci::Position pos, Sci::Position moveDir, bool checkLineEnd=true) const; + Sci::Position MovePositionOutsideChar(Sci::Position pos, Sci::Position moveDir, bool checkLineEnd=true) const noexcept; Sci::Position NextPosition(Sci::Position pos, int moveDir) const noexcept; bool NextCharacter(Sci::Position &pos, int moveDir) const noexcept; // Returns true if pos changed - Document::CharacterExtracted CharacterAfter(Sci::Position position) const; - Document::CharacterExtracted CharacterBefore(Sci::Position position) const; + Document::CharacterExtracted CharacterAfter(Sci::Position position) const noexcept; + Document::CharacterExtracted CharacterBefore(Sci::Position position) const noexcept; Sci_Position SCI_METHOD GetRelativePosition(Sci_Position positionStart, Sci_Position characterOffset) const override; - Sci::Position GetRelativePositionUTF16(Sci::Position positionStart, Sci::Position characterOffset) const; + Sci::Position GetRelativePositionUTF16(Sci::Position positionStart, Sci::Position characterOffset) const noexcept; int SCI_METHOD GetCharacterAndWidth(Sci_Position position, Sci_Position *pWidth) const override; int SCI_METHOD CodePage() const override; bool SCI_METHOD IsDBCSLeadByte(char ch) const override; @@ -346,42 +348,42 @@ class Document : PerLine, public IDocumentWithLineEnd, public ILoader { void * SCI_METHOD ConvertToDocument() override; Sci::Position Undo(); Sci::Position Redo(); - bool CanUndo() const { return cb.CanUndo(); } - bool CanRedo() const { return cb.CanRedo(); } + bool CanUndo() const noexcept { return cb.CanUndo(); } + bool CanRedo() const noexcept { return cb.CanRedo(); } void DeleteUndoHistory() { cb.DeleteUndoHistory(); } bool SetUndoCollection(bool collectUndo) { return cb.SetUndoCollection(collectUndo); } - bool IsCollectingUndo() const { return cb.IsCollectingUndo(); } + bool IsCollectingUndo() const noexcept { return cb.IsCollectingUndo(); } void BeginUndoAction() { cb.BeginUndoAction(); } void EndUndoAction() { cb.EndUndoAction(); } void AddUndoAction(Sci::Position token, bool mayCoalesce) { cb.AddUndoAction(token, mayCoalesce); } void SetSavePoint(); - bool IsSavePoint() const { return cb.IsSavePoint(); } + bool IsSavePoint() const noexcept { return cb.IsSavePoint(); } void TentativeStart() { cb.TentativeStart(); } void TentativeCommit() { cb.TentativeCommit(); } void TentativeUndo(); - bool TentativeActive() const { return cb.TentativeActive(); } + bool TentativeActive() const noexcept { return cb.TentativeActive(); } const char * SCI_METHOD BufferPointer() override { return cb.BufferPointer(); } - const char *RangePointer(Sci::Position position, Sci::Position rangeLength) { return cb.RangePointer(position, rangeLength); } - Sci::Position GapPosition() const { return cb.GapPosition(); } + const char *RangePointer(Sci::Position position, Sci::Position rangeLength) noexcept { return cb.RangePointer(position, rangeLength); } + Sci::Position GapPosition() const noexcept { return cb.GapPosition(); } int SCI_METHOD GetLineIndentation(Sci_Position line) override; Sci::Position SetLineIndentation(Sci::Line line, Sci::Position indent); Sci::Position GetLineIndentPosition(Sci::Line line) const; Sci::Position GetColumn(Sci::Position pos); - Sci::Position CountCharacters(Sci::Position startPos, Sci::Position endPos) const; - Sci::Position CountUTF16(Sci::Position startPos, Sci::Position endPos) const; + Sci::Position CountCharacters(Sci::Position startPos, Sci::Position endPos) const noexcept; + Sci::Position CountUTF16(Sci::Position startPos, Sci::Position endPos) const noexcept; Sci::Position FindColumn(Sci::Line line, Sci::Position column); void Indent(bool forwards, Sci::Line lineBottom, Sci::Line lineTop); static std::string TransformLineEnds(const char *s, size_t len, int eolModeWanted); void ConvertLineEnds(int eolModeSet); void SetReadOnly(bool set) { cb.SetReadOnly(set); } - bool IsReadOnly() const { return cb.IsReadOnly(); } - bool IsLarge() const { return cb.IsLarge(); } - int Options() const; + bool IsReadOnly() const noexcept { return cb.IsReadOnly(); } + bool IsLarge() const noexcept { return cb.IsLarge(); } + int Options() const noexcept; void DelChar(Sci::Position pos); void DelCharBack(Sci::Position pos); @@ -395,14 +397,16 @@ class Document : PerLine, public IDocumentWithLineEnd, public ILoader { void GetStyleRange(unsigned char *buffer, Sci::Position position, Sci::Position lengthRetrieve) const { cb.GetStyleRange(buffer, position, lengthRetrieve); } - int GetMark(Sci::Line line) const; - Sci::Line MarkerNext(Sci::Line lineStart, int mask) const; + int GetMark(Sci::Line line) const noexcept; + Sci::Line MarkerNext(Sci::Line lineStart, int mask) const noexcept; int AddMark(Sci::Line line, int markerNum); void AddMarkSet(Sci::Line line, int valueSet); void DeleteMark(Sci::Line line, int markerNum); void DeleteMarkFromHandle(int markerHandle); void DeleteAllMarks(int markerNum); - Sci::Line LineFromHandle(int markerHandle) const; + Sci::Line LineFromHandle(int markerHandle) const noexcept; + int MarkerNumberFromLine(Sci::Line line, int which) const noexcept; + int MarkerHandleFromLine(Sci::Line line, int which) const noexcept; Sci_Position SCI_METHOD LineStart(Sci_Position line) const override; bool IsLineStartPosition(Sci::Position position) const; Sci_Position SCI_METHOD LineEnd(Sci_Position line) const override; @@ -410,8 +414,8 @@ class Document : PerLine, public IDocumentWithLineEnd, public ILoader { bool IsLineEndPosition(Sci::Position position) const; bool IsPositionInLineEnd(Sci::Position position) const; Sci::Position VCHomePosition(Sci::Position position) const; - Sci::Position IndexLineStart(Sci::Line line, int lineCharacterIndex) const; - Sci::Line LineFromPositionIndex(Sci::Position pos, int lineCharacterIndex) const; + Sci::Position IndexLineStart(Sci::Line line, int lineCharacterIndex) const noexcept; + Sci::Line LineFromPositionIndex(Sci::Position pos, int lineCharacterIndex) const noexcept; int SCI_METHOD SetLevel(Sci_Position line, int level) override; int SCI_METHOD GetLevel(Sci_Position line) const override; @@ -424,6 +428,7 @@ class Document : PerLine, public IDocumentWithLineEnd, public ILoader { Sci::Position NextWordStart(Sci::Position pos, int delta) const; Sci::Position NextWordEnd(Sci::Position pos, int delta) const; Sci_Position SCI_METHOD Length() const override { return cb.Length(); } + Sci::Position LengthNoExcept() const noexcept { return cb.Length(); } void Allocate(Sci::Position newSize) { cb.Allocate(newSize); } CharacterExtracted ExtractCharacter(Sci::Position position) const noexcept; @@ -434,10 +439,10 @@ class Document : PerLine, public IDocumentWithLineEnd, public ILoader { bool MatchesWordOptions(bool word, bool wordStart, Sci::Position pos, Sci::Position length) const; bool HasCaseFolder() const noexcept; - void SetCaseFolder(CaseFolder *pcf_); + void SetCaseFolder(CaseFolder *pcf_) noexcept; Sci::Position FindText(Sci::Position minPos, Sci::Position maxPos, const char *search, int flags, Sci::Position *length); const char *SubstituteByPosition(const char *text, Sci::Position *length); - int LineCharacterIndex() const; + int LineCharacterIndex() const noexcept; void AllocateLineCharacterIndex(int lineCharacterIndex); void ReleaseLineCharacterIndex(int lineCharacterIndex); Sci::Line LinesTotal() const noexcept; @@ -458,41 +463,45 @@ class Document : PerLine, public IDocumentWithLineEnd, public ILoader { void IncrementStyleClock() noexcept; void SCI_METHOD DecorationSetCurrentIndicator(int indicator) override; void SCI_METHOD DecorationFillRange(Sci_Position position, int value, Sci_Position fillLength) override; - LexInterface *GetLexInterface() const; - void SetLexInterface(LexInterface *pLexInterface); + LexInterface *GetLexInterface() const noexcept; + void SetLexInterface(std::unique_ptr pLexInterface) noexcept; int SCI_METHOD SetLineState(Sci_Position line, int state) override; int SCI_METHOD GetLineState(Sci_Position line) const override; - Sci::Line GetMaxLineState() const; + Sci::Line GetMaxLineState() const noexcept; void SCI_METHOD ChangeLexerState(Sci_Position start, Sci_Position end) override; - StyledText MarginStyledText(Sci::Line line) const; + StyledText MarginStyledText(Sci::Line line) const noexcept; void MarginSetStyle(Sci::Line line, int style); void MarginSetStyles(Sci::Line line, const unsigned char *styles); void MarginSetText(Sci::Line line, const char *text); void MarginClearAll(); - StyledText AnnotationStyledText(Sci::Line line) const; + StyledText AnnotationStyledText(Sci::Line line) const noexcept; void AnnotationSetText(Sci::Line line, const char *text); void AnnotationSetStyle(Sci::Line line, int style); void AnnotationSetStyles(Sci::Line line, const unsigned char *styles); - int AnnotationLines(Sci::Line line) const; + int AnnotationLines(Sci::Line line) const noexcept; void AnnotationClearAll(); + StyledText EOLAnnotationStyledText(Sci::Line line) const noexcept; + void EOLAnnotationSetStyle(Sci::Line line, int style); + void EOLAnnotationSetText(Sci::Line line, const char *text); + void EOLAnnotationClearAll(); + bool AddWatcher(DocWatcher *watcher, void *userData); bool RemoveWatcher(DocWatcher *watcher, void *userData); - bool IsASCIIWordByte(unsigned char ch) const; CharClassify::cc WordCharacterClass(unsigned int ch) const; bool IsWordPartSeparator(unsigned int ch) const; Sci::Position WordPartLeft(Sci::Position pos) const; Sci::Position WordPartRight(Sci::Position pos) const; - Sci::Position ExtendStyleRange(Sci::Position pos, int delta, bool singleLine = false); + Sci::Position ExtendStyleRange(Sci::Position pos, int delta, bool singleLine) noexcept; bool IsWhiteLine(Sci::Line line) const; Sci::Position ParaUp(Sci::Position pos) const; Sci::Position ParaDown(Sci::Position pos) const; int IndentSize() const noexcept { return actualIndentInChars; } - Sci::Position BraceMatch(Sci::Position position, Sci::Position maxReStyle); + Sci::Position BraceMatch(Sci::Position position, Sci::Position maxReStyle, Sci::Position startPos, bool useStartPos) noexcept; private: void NotifyModifyAttempt(); diff --git a/scintilla/src/EditModel.cxx b/scintilla/src/EditModel.cxx index 99520f3cbd..f43ae2aed6 100644 --- a/scintilla/src/EditModel.cxx +++ b/scintilla/src/EditModel.cxx @@ -49,7 +49,7 @@ using namespace Scintilla; -Caret::Caret() : +Caret::Caret() noexcept : active(false), on(false), period(500) {} EditModel::EditModel() : braces{} { @@ -86,7 +86,7 @@ const char *EditModel::GetDefaultFoldDisplayText() const noexcept { return defaultFoldDisplayText.get(); } -const char *EditModel::GetFoldDisplayText(Sci::Line lineDoc) const { +const char *EditModel::GetFoldDisplayText(Sci::Line lineDoc) const noexcept { if (foldDisplayTextStyle == SC_FOLDDISPLAYTEXT_HIDDEN || pcs->GetExpanded(lineDoc)) { return nullptr; } @@ -94,4 +94,3 @@ const char *EditModel::GetFoldDisplayText(Sci::Line lineDoc) const { const char *text = pcs->GetFoldDisplayText(lineDoc); return text ? text : defaultFoldDisplayText.get(); } - diff --git a/scintilla/src/EditModel.h b/scintilla/src/EditModel.h index ab5c23cdb9..cb6ea28399 100644 --- a/scintilla/src/EditModel.h +++ b/scintilla/src/EditModel.h @@ -18,7 +18,7 @@ class Caret { bool on; int period; - Caret(); + Caret() noexcept; }; class EditModel { @@ -37,6 +37,7 @@ class EditModel { bool primarySelection; enum IMEInteraction { imeWindowed, imeInline } imeInteraction; + enum class CharacterSource { directInput, tentativeInput, imeResult }; int foldFlags; int foldDisplayTextStyle; @@ -64,7 +65,7 @@ class EditModel { virtual Range GetHotSpotRange() const noexcept = 0; void SetDefaultFoldDisplayText(const char *text); const char *GetDefaultFoldDisplayText() const noexcept; - const char *GetFoldDisplayText(Sci::Line lineDoc) const; + const char *GetFoldDisplayText(Sci::Line lineDoc) const noexcept; }; } diff --git a/scintilla/src/EditView.cxx b/scintilla/src/EditView.cxx index fa01a03856..cae02ef5c9 100644 --- a/scintilla/src/EditView.cxx +++ b/scintilla/src/EditView.cxx @@ -28,7 +28,6 @@ #include "ILexer.h" #include "Scintilla.h" -#include "StringCopy.h" #include "CharacterSet.h" #include "CharacterCategory.h" #include "Position.h" @@ -59,20 +58,15 @@ using namespace Scintilla; -static inline bool IsControlCharacter(int ch) { - // iscntrl returns true for lots of chars > 127 which are displayable - return ch >= 0 && ch < ' '; -} - PrintParameters::PrintParameters() noexcept { magnification = 0; colourMode = SC_PRINT_NORMAL; - wrapState = eWrapWord; + wrapState = WrapMode::word; } namespace Scintilla { -bool ValidStyledText(const ViewStyle &vs, size_t styleOffset, const StyledText &st) { +bool ValidStyledText(const ViewStyle &vs, size_t styleOffset, const StyledText &st) noexcept { if (st.multipleStyles) { for (size_t iStyle = 0; iStyle(x + tabWidthMinimumPixels)); if (next > 0) return static_cast(next); return (static_cast((x + tabWidthMinimumPixels) / tabWidth) + 1) * tabWidth; } -bool EditView::ClearTabstops(Sci::Line line) { +bool EditView::ClearTabstops(Sci::Line line) noexcept { return ldTabstops && ldTabstops->ClearTabstops(line); } bool EditView::AddTabstop(Sci::Line line, int x) { if (!ldTabstops) { - ldTabstops.reset(new LineTabstops()); + ldTabstops = Sci::make_unique(); } return ldTabstops && ldTabstops->AddTabstop(line, x); } -int EditView::GetNextTabstop(Sci::Line line, int x) const { +int EditView::GetNextTabstop(Sci::Line line, int x) const noexcept { if (ldTabstops) { return ldTabstops->GetNextTabstop(line, x); } else { @@ -287,7 +279,7 @@ static const char *ControlCharacterString(unsigned char ch) noexcept { "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB", "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US" }; - if (ch < ELEMENTS(reps)) { + if (ch < Sci::size(reps)) { return reps[ch]; } else { return "BAD"; @@ -323,9 +315,7 @@ void EditView::RefreshPixMaps(Surface *surfaceWindow, WindowID wid, const ViewSt pixmapIndentGuideHighlight->InitPixMap(1, vsDraw.lineHeight + 1, surfaceWindow, wid); const PRectangle rcIG = PRectangle::FromInts(0, 0, 1, vsDraw.lineHeight); pixmapIndentGuide->FillRectangle(rcIG, vsDraw.styles[STYLE_INDENTGUIDE].back); - pixmapIndentGuide->PenColour(vsDraw.styles[STYLE_INDENTGUIDE].fore); pixmapIndentGuideHighlight->FillRectangle(rcIG, vsDraw.styles[STYLE_BRACELIGHT].back); - pixmapIndentGuideHighlight->PenColour(vsDraw.styles[STYLE_BRACELIGHT].fore); for (int stripe = 1; stripe < vsDraw.lineHeight + 1; stripe += 2) { const PRectangle rcPixel = PRectangle::FromInts(0, stripe, 1, stripe + 1); pixmapIndentGuide->FillRectangle(rcPixel, vsDraw.styles[STYLE_INDENTGUIDE].fore); @@ -344,6 +334,42 @@ LineLayout *EditView::RetrieveLineLayout(Sci::Line lineNumber, const EditModel & model.LinesOnScreen() + 1, model.pdoc->LinesTotal()); } +namespace { + +constexpr XYPOSITION epsilon = 0.0001f; // A small nudge to avoid floating point precision issues + +/** +* Return the chDoc argument with case transformed as indicated by the caseForce argument. +* chPrevious is needed for camel casing. +* This only affects ASCII characters and is provided for languages with case-insensitive +* ASCII keywords where the user wishes to view keywords in a preferred case. +*/ +inline char CaseForce(Style::ecaseForced caseForce, char chDoc, char chPrevious) { + switch (caseForce) { + case Style::caseMixed: + return chDoc; + case Style::caseLower: + return MakeLowerCase(chDoc); + case Style::caseUpper: + return MakeUpperCase(chDoc); + case Style::caseCamel: + default: // default should not occur, included to avoid warnings + if (IsUpperOrLowerCase(chDoc) && !IsUpperOrLowerCase(chPrevious)) { + return MakeUpperCase(chDoc); + } else { + return MakeLowerCase(chDoc); + } + } +} + +constexpr bool IsControlCharacter(int ch) noexcept { + // iscntrl returns true for lots of chars > 127 which are displayable, + // currently only check C0 control characters. + return (ch >= 0 && ch < ' ') || (ch == 127); +} + +} + /** * Fill in the LineLayout data for the given line. * Copy the given @a line and its styles from the document into local arrays. @@ -361,7 +387,10 @@ void EditView::LayoutLine(const EditModel &model, Sci::Line line, Surface *surfa if (posLineEnd >(posLineStart + ll->maxLineLength)) { posLineEnd = posLineStart + ll->maxLineLength; } - if (ll->validity == LineLayout::llCheckTextAndStyle) { + // Hard to cope when too narrow, so just assume there is space + width = std::max(width, 20); + + if (ll->validity == LineLayout::ValidLevel::checkTextAndStyle) { Sci::Position lineLength = posLineEnd - posLineStart; if (!vstyle.viewEOL) { lineLength = model.pdoc->LineEnd(line) - posLineStart; @@ -370,44 +399,29 @@ void EditView::LayoutLine(const EditModel &model, Sci::Line line, Surface *surfa // See if chars, styles, indicators, are all the same bool allSame = true; // Check base line layout - int styleByte = 0; - int numCharsInLine = 0; - while (numCharsInLine < lineLength) { + char chPrevious = 0; + for (Sci::Position numCharsInLine = 0; numCharsInLine < lineLength; numCharsInLine++) { const Sci::Position charInDoc = numCharsInLine + posLineStart; const char chDoc = model.pdoc->CharAt(charInDoc); - styleByte = model.pdoc->StyleIndexAt(charInDoc); + const int styleByte = model.pdoc->StyleIndexAt(charInDoc); allSame = allSame && (ll->styles[numCharsInLine] == styleByte); - if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseMixed) - allSame = allSame && - (ll->chars[numCharsInLine] == chDoc); - else if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseLower) - allSame = allSame && - (ll->chars[numCharsInLine] == MakeLowerCase(chDoc)); - else if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseUpper) - allSame = allSame && - (ll->chars[numCharsInLine] == MakeUpperCase(chDoc)); - else { // Style::caseCamel - if ((model.pdoc->IsASCIIWordByte(ll->chars[numCharsInLine])) && - ((numCharsInLine == 0) || (!model.pdoc->IsASCIIWordByte(ll->chars[numCharsInLine - 1])))) { - allSame = allSame && (ll->chars[numCharsInLine] == MakeUpperCase(chDoc)); - } else { - allSame = allSame && (ll->chars[numCharsInLine] == MakeLowerCase(chDoc)); - } - } - numCharsInLine++; + allSame = allSame && + (ll->chars[numCharsInLine] == CaseForce(vstyle.styles[styleByte].caseForce, chDoc, chPrevious)); + chPrevious = chDoc; } - allSame = allSame && (ll->styles[numCharsInLine] == styleByte); // For eolFilled + const int styleByteLast = (posLineEnd > posLineStart) ? model.pdoc->StyleIndexAt(posLineEnd - 1) : 0; + allSame = allSame && (ll->styles[lineLength] == styleByteLast); // For eolFilled if (allSame) { - ll->validity = LineLayout::llPositions; + ll->validity = (ll->widthLine != width) ? LineLayout::ValidLevel::positions : LineLayout::ValidLevel::lines; } else { - ll->validity = LineLayout::llInvalid; + ll->validity = LineLayout::ValidLevel::invalid; } } else { - ll->validity = LineLayout::llInvalid; + ll->validity = LineLayout::ValidLevel::invalid; } } - if (ll->validity == LineLayout::llInvalid) { + if (ll->validity == LineLayout::ValidLevel::invalid) { ll->widthLine = LineLayout::wrapWidthInfinite; ll->lines = 1; if (vstyle.edgeState == EDGE_BACKGROUND) { @@ -426,26 +440,13 @@ void EditView::LayoutLine(const EditModel &model, Sci::Line line, Surface *surfa model.pdoc->GetStyleRange(ll->styles.get(), posLineStart, lineLength); const int numCharsBeforeEOL = static_cast(model.pdoc->LineEnd(line) - posLineStart); const int numCharsInLine = (vstyle.viewEOL) ? lineLength : numCharsBeforeEOL; - for (Sci::Position styleInLine = 0; styleInLine < numCharsInLine; styleInLine++) { - const unsigned char styleByte = ll->styles[styleInLine]; - ll->styles[styleInLine] = styleByte; - } const unsigned char styleByteLast = (lineLength > 0) ? ll->styles[lineLength - 1] : 0; if (vstyle.someStylesForceCase) { + char chPrevious = 0; for (int charInLine = 0; charInLinechars[charInLine]; - if (vstyle.styles[ll->styles[charInLine]].caseForce == Style::caseUpper) - ll->chars[charInLine] = MakeUpperCase(chDoc); - else if (vstyle.styles[ll->styles[charInLine]].caseForce == Style::caseLower) - ll->chars[charInLine] = MakeLowerCase(chDoc); - else if (vstyle.styles[ll->styles[charInLine]].caseForce == Style::caseCamel) { - if ((model.pdoc->IsASCIIWordByte(ll->chars[charInLine])) && - ((charInLine == 0) || (!model.pdoc->IsASCIIWordByte(ll->chars[charInLine - 1])))) { - ll->chars[charInLine] = MakeUpperCase(chDoc); - } else { - ll->chars[charInLine] = MakeLowerCase(chDoc); - } - } + ll->chars[charInLine] = CaseForce(vstyle.styles[ll->styles[charInLine]].caseForce, chDoc, chPrevious); + chPrevious = chDoc; } } ll->xHighlightGuide = 0; @@ -504,13 +505,9 @@ void EditView::LayoutLine(const EditModel &model, Sci::Line line, Surface *surfa } ll->numCharsInLine = numCharsInLine; ll->numCharsBeforeEOL = numCharsBeforeEOL; - ll->validity = LineLayout::llPositions; + ll->validity = LineLayout::ValidLevel::positions; } - // Hard to cope when too narrow, so just assume there is space - if (width < 20) { - width = 20; - } - if ((ll->validity == LineLayout::llPositions) || (ll->widthLine != width)) { + if ((ll->validity == LineLayout::ValidLevel::positions) || (ll->widthLine != width)) { ll->widthLine = width; if (width == LineLayout::wrapWidthInfinite) { ll->lines = 1; @@ -578,12 +575,12 @@ void EditView::LayoutLine(const EditModel &model, Sci::Line line, Surface *surfa continue; } if (p > 0) { - if (vstyle.wrapState == eWrapChar) { + if (vstyle.wrapState == WrapMode::character) { lastGoodBreak = model.pdoc->MovePositionOutsideChar(p + posLineStart, -1) - posLineStart; p = model.pdoc->MovePositionOutsideChar(p + 1 + posLineStart, 1) - posLineStart; continue; - } else if ((vstyle.wrapState == eWrapWord) && (ll->styles[p] != ll->styles[p - 1])) { + } else if ((vstyle.wrapState == WrapMode::word) && (ll->styles[p] != ll->styles[p - 1])) { lastGoodBreak = p; } else if (IsSpaceOrTab(ll->chars[p - 1]) && !IsSpaceOrTab(ll->chars[p])) { lastGoodBreak = p; @@ -593,7 +590,7 @@ void EditView::LayoutLine(const EditModel &model, Sci::Line line, Surface *surfa } ll->lines++; } - ll->validity = LineLayout::llLines; + ll->validity = LineLayout::ValidLevel::lines; } } @@ -770,7 +767,7 @@ static ColourDesired SelectionBackground(const ViewStyle &vsDraw, bool main, boo } static ColourDesired TextBackground(const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, - ColourOptional background, int inSelection, bool inHotspot, int styleMain, Sci::Position i) { + ColourOptional background, int inSelection, bool inHotspot, int styleMain, Sci::Position i) noexcept { if (inSelection == 1) { if (vsDraw.selColours.back.isSet && (vsDraw.selAlpha == SC_ALPHA_NOALPHA)) { return SelectionBackground(vsDraw, true, model.primarySelection); @@ -985,7 +982,8 @@ void EditView::DrawEOL(Surface *surface, const EditModel &model, const ViewStyle rcSegment.left = rcLine.left; rcSegment.right = rcLine.right; - const bool fillRemainder = !lastSubLine || !model.GetFoldDisplayText(line); + const bool drawEOLAnnotationStyledText = (vsDraw.eolAnnotationVisible != EOLANNOTATION_HIDDEN) && model.pdoc->EOLAnnotationStyledText(line).text; + const bool fillRemainder = (!lastSubLine || (!model.GetFoldDisplayText(line) && !drawEOLAnnotationStyledText)); if (fillRemainder) { // Fill the remainder of the line FillLineRemainder(surface, model, vsDraw, ll, line, rcSegment, subLine); @@ -1025,7 +1023,7 @@ void EditView::DrawEOL(Surface *surface, const EditModel &model, const ViewStyle } static void DrawIndicator(int indicNum, Sci::Position startPos, Sci::Position endPos, Surface *surface, const ViewStyle &vsDraw, - const LineLayout *ll, int xStart, PRectangle rcLine, Sci::Position secondCharacter, int subLine, Indicator::DrawState drawState, int value) { + const LineLayout *ll, int xStart, PRectangle rcLine, Sci::Position secondCharacter, int subLine, Indicator::State state, int value) { const XYPOSITION subLineStart = ll->positions[ll->LineStart(subLine)]; const PRectangle rcIndic( ll->positions[startPos] + xStart - subLineStart, @@ -1041,7 +1039,7 @@ static void DrawIndicator(int indicNum, Sci::Position startPos, Sci::Position en // Indicator continued from earlier line so make an empty box and don't draw rcFirstCharacter.right = rcFirstCharacter.left; } - vsDraw.indicators[indicNum].Draw(surface, rcIndic, rcLine, rcFirstCharacter, drawState, value); + vsDraw.indicators[indicNum].Draw(surface, rcIndic, rcLine, rcFirstCharacter, state, value); } static void DrawIndicators(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, @@ -1063,10 +1061,10 @@ static void DrawIndicators(Surface *surface, const EditModel &model, const ViewS const bool hover = vsDraw.indicators[deco->Indicator()].IsDynamic() && rangeRun.ContainsCharacter(hoverIndicatorPos); const int value = deco->ValueAt(startPos); - const Indicator::DrawState drawState = hover ? Indicator::drawHover : Indicator::drawNormal; + const Indicator::State state = hover ? Indicator::State::hover : Indicator::State::normal; const Sci::Position posSecond = model.pdoc->MovePositionOutsideChar(rangeRun.First() + 1, 1); DrawIndicator(deco->Indicator(), startPos - posLineStart, endPos - posLineStart, - surface, vsDraw, ll, xStart, rcLine, posSecond - posLineStart, subLine, drawState, value); + surface, vsDraw, ll, xStart, rcLine, posSecond - posLineStart, subLine, state, value); startPos = endPos; if (!deco->ValueAt(startPos)) { startPos = deco->EndRun(startPos); @@ -1085,14 +1083,14 @@ static void DrawIndicators(Surface *surface, const EditModel &model, const ViewS const Sci::Position braceOffset = model.braces[0] - posLineStart; if (braceOffset < ll->numCharsInLine) { const Sci::Position secondOffset = model.pdoc->MovePositionOutsideChar(model.braces[0] + 1, 1) - posLineStart; - DrawIndicator(braceIndicator, braceOffset, braceOffset + 1, surface, vsDraw, ll, xStart, rcLine, secondOffset, subLine, Indicator::drawNormal, 1); + DrawIndicator(braceIndicator, braceOffset, braceOffset + 1, surface, vsDraw, ll, xStart, rcLine, secondOffset, subLine, Indicator::State::normal, 1); } } if (rangeLine.ContainsCharacter(model.braces[1])) { const Sci::Position braceOffset = model.braces[1] - posLineStart; if (braceOffset < ll->numCharsInLine) { const Sci::Position secondOffset = model.pdoc->MovePositionOutsideChar(model.braces[1] + 1, 1) - posLineStart; - DrawIndicator(braceIndicator, braceOffset, braceOffset + 1, surface, vsDraw, ll, xStart, rcLine, secondOffset, subLine, Indicator::drawNormal, 1); + DrawIndicator(braceIndicator, braceOffset, braceOffset + 1, surface, vsDraw, ll, xStart, rcLine, secondOffset, subLine, Indicator::State::normal, 1); } } } @@ -1139,7 +1137,7 @@ void EditView::DrawFoldDisplayText(Surface *surface, const EditModel &model, con if (model.trackLineWidth) { if (rcSegment.right + 1> lineWidthMaxSeen) { - // Fold display text border drawn on rcSegment.right with width 1 is the last visble object of the line + // Fold display text border drawn on rcSegment.right with width 1 is the last visible object of the line lineWidthMaxSeen = static_cast(rcSegment.right + 1); } } @@ -1172,8 +1170,8 @@ void EditView::DrawFoldDisplayText(Surface *surface, const EditModel &model, con if (model.foldDisplayTextStyle == SC_FOLDDISPLAYTEXT_BOXED) { surface->PenColour(textFore); PRectangle rcBox = rcSegment; - rcBox.left = round(rcSegment.left); - rcBox.right = round(rcSegment.right); + rcBox.left = Sci::round(rcSegment.left); + rcBox.right = Sci::round(rcSegment.right); const IntegerRectangle ircBox(rcBox); surface->MoveTo(ircBox.left, ircBox.top); surface->LineTo(ircBox.left, ircBox.bottom); @@ -1193,6 +1191,93 @@ void EditView::DrawFoldDisplayText(Surface *surface, const EditModel &model, con } } +void EditView::DrawEOLAnnotationText(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, Sci::Line line, int xStart, PRectangle rcLine, int subLine, XYACCUMULATOR subLineStart, DrawPhase phase) { + + const bool lastSubLine = subLine == (ll->lines - 1); + if (!lastSubLine) + return; + + if (vsDraw.eolAnnotationVisible == EOLANNOTATION_HIDDEN) { + return; + } + const StyledText stEOLAnnotation = model.pdoc->EOLAnnotationStyledText(line); + if (!stEOLAnnotation.text || !ValidStyledText(vsDraw, vsDraw.eolAnnotationStyleOffset, stEOLAnnotation)) { + return; + } + const size_t style = stEOLAnnotation.style + vsDraw.eolAnnotationStyleOffset; + + PRectangle rcSegment = rcLine; + FontAlias fontText = vsDraw.styles[style].font; + const int widthEOLAnnotationText = static_cast(surface->WidthText(fontText, stEOLAnnotation.text, stEOLAnnotation.length)); + + const XYPOSITION spaceWidth = vsDraw.styles[ll->EndLineStyle()].spaceWidth; + const XYPOSITION virtualSpace = model.sel.VirtualSpaceFor( + model.pdoc->LineEnd(line)) * spaceWidth; + rcSegment.left = xStart + + static_cast(ll->positions[ll->numCharsInLine] - subLineStart) + + virtualSpace + vsDraw.aveCharWidth; + + const char *textFoldDisplay = model.GetFoldDisplayText(line); + if (textFoldDisplay) { + rcSegment.left += (static_cast(surface->WidthText(fontText, textFoldDisplay, static_cast(strlen(textFoldDisplay)))) + vsDraw.aveCharWidth); + } + rcSegment.right = rcSegment.left + static_cast(widthEOLAnnotationText); + + const ColourOptional background = vsDraw.Background(model.pdoc->GetMark(line), model.caret.active, ll->containsCaret); + ColourDesired textFore = vsDraw.styles[style].fore; + const ColourDesired textBack = TextBackground(model, vsDraw, ll, background, false, + false, static_cast(style), -1); + + if (model.trackLineWidth) { + if (rcSegment.right + 1> lineWidthMaxSeen) { + // EOL Annotation text border drawn on rcSegment.right with width 1 is the last visible object of the line + lineWidthMaxSeen = static_cast(rcSegment.right + 1); + } + } + + if (phase & drawBack) { + surface->FillRectangle(rcSegment, textBack); + + // Fill Remainder of the line + PRectangle rcRemainder = rcSegment; + rcRemainder.left = rcRemainder.right; + if (rcRemainder.left < rcLine.left) + rcRemainder.left = rcLine.left; + rcRemainder.right = rcLine.right; + FillLineRemainder(surface, model, vsDraw, ll, line, rcRemainder, subLine); + } + + if (phase & drawText) { + if (phasesDraw != phasesOne) { + surface->DrawTextTransparent(rcSegment, fontText, + rcSegment.top + vsDraw.maxAscent, stEOLAnnotation.text, stEOLAnnotation.length, + textFore); + } else { + surface->DrawTextNoClip(rcSegment, fontText, + rcSegment.top + vsDraw.maxAscent, stEOLAnnotation.text, stEOLAnnotation.length, + textFore, textBack); + } + } + + if (phase & drawIndicatorsFore) { + if (vsDraw.eolAnnotationVisible == EOLANNOTATION_BOXED ) { + surface->PenColour(textFore); + PRectangle rcBox = rcSegment; + rcBox.left = Sci::round(rcSegment.left); + rcBox.right = Sci::round(rcSegment.right); + const IntegerRectangle ircBox(rcBox); + surface->MoveTo(ircBox.left, ircBox.top); + surface->LineTo(ircBox.left, ircBox.bottom); + surface->MoveTo(ircBox.right, ircBox.top); + surface->LineTo(ircBox.right, ircBox.bottom); + surface->MoveTo(ircBox.left, ircBox.top); + surface->LineTo(ircBox.right, ircBox.top); + surface->MoveTo(ircBox.left, ircBox.bottom - 1); + surface->LineTo(ircBox.right, ircBox.bottom - 1); + } + } +} + static constexpr bool AnnotationBoxedOrIndented(int annotationVisible) noexcept { return annotationVisible == ANNOTATION_BOXED || annotationVisible == ANNOTATION_INDENTED; } @@ -1332,7 +1417,9 @@ void EditView::DrawCarets(Surface *surface, const EditModel &model, const ViewSt for (size_t r = 0; (r model.sel.Range(r).anchor) { + if ((vsDraw.DrawCaretInsideSelection(model.inOverstrike, imeCaretBlockOverride)) && + !drawDrag && + posCaret > model.sel.Range(r).anchor) { if (posCaret.VirtualSpace() > 0) posCaret.SetVirtualSpace(posCaret.VirtualSpace() - 1); else @@ -1350,20 +1437,19 @@ void EditView::DrawCarets(Surface *surface, const EditModel &model, const ViewSt } const bool caretBlinkState = (model.caret.active && model.caret.on) || (!additionalCaretsBlink && !mainCaret); const bool caretVisibleState = additionalCaretsVisible || mainCaret; - if ((xposCaret >= 0) && (vsDraw.caretWidth > 0) && (vsDraw.caretStyle != CARETSTYLE_INVISIBLE) && + if ((xposCaret >= 0) && vsDraw.IsCaretVisible() && (drawDrag || (caretBlinkState && caretVisibleState))) { - bool caretAtEOF = false; - bool caretAtEOL = false; + bool canDrawBlockCaret = true; bool drawBlockCaret = false; XYPOSITION widthOverstrikeCaret; XYPOSITION caretWidthOffset = 0; PRectangle rcCaret = rcLine; if (posCaret.Position() == model.pdoc->Length()) { // At end of document - caretAtEOF = true; + canDrawBlockCaret = false; widthOverstrikeCaret = vsDraw.aveCharWidth; } else if ((posCaret.Position() - posLineStart) >= ll->numCharsInLine) { // At end of line - caretAtEOL = true; + canDrawBlockCaret = false; widthOverstrikeCaret = vsDraw.aveCharWidth; } else { const int widthChar = model.pdoc->LenChar(posCaret.Position()); @@ -1378,7 +1464,7 @@ void EditView::DrawCarets(Surface *surface, const EditModel &model, const ViewSt const ViewStyle::CaretShape caretShape = drawDrag ? ViewStyle::CaretShape::line : vsDraw.CaretShapeForMode(model.inOverstrike); if (drawDrag) { /* Dragging text, use a line caret */ - rcCaret.left = round(xposCaret - caretWidthOffset); + rcCaret.left = Sci::round(xposCaret - caretWidthOffset); rcCaret.right = rcCaret.left + vsDraw.caretWidth; } else if ((caretShape == ViewStyle::CaretShape::bar) && drawOverstrikeCaret) { /* Overstrike (insert mode), use a modified bar caret */ @@ -1388,7 +1474,7 @@ void EditView::DrawCarets(Surface *surface, const EditModel &model, const ViewSt } else if ((caretShape == ViewStyle::CaretShape::block) || imeCaretBlockOverride) { /* Block caret */ rcCaret.left = xposCaret; - if (!caretAtEOL && !caretAtEOF && (ll->chars[offset] != '\t') && !(IsControlCharacter(ll->chars[offset]))) { + if (canDrawBlockCaret && !(IsControlCharacter(ll->chars[offset]))) { drawBlockCaret = true; rcCaret.right = xposCaret + widthOverstrikeCaret; } else { @@ -1396,7 +1482,7 @@ void EditView::DrawCarets(Surface *surface, const EditModel &model, const ViewSt } } else { /* Line caret */ - rcCaret.left = round(xposCaret - caretWidthOffset); + rcCaret.left = Sci::round(xposCaret - caretWidthOffset); rcCaret.right = rcCaret.left + vsDraw.caretWidth; } const ColourDesired caretColour = mainCaret ? vsDraw.caretcolour : vsDraw.additionalCaretColour; @@ -1559,6 +1645,7 @@ static void DrawMarkUnderline(Surface *surface, const EditModel &model, const Vi marks >>= 1; } } + static void DrawTranslucentSelection(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, Sci::Line line, PRectangle rcLine, int subLine, Range lineRange, int xStart) { if ((vsDraw.selAlpha != SC_ALPHA_NOALPHA) || (vsDraw.selAdditionalAlpha != SC_ALPHA_NOALPHA)) { @@ -1676,9 +1763,12 @@ void EditView::DrawForeground(Surface *surface, const EditModel &model, const Vi const int indicatorValue = deco->ValueAt(ts.start + posLineStart); if (indicatorValue) { const Indicator &indicator = vsDraw.indicators[deco->Indicator()]; - const bool hover = indicator.IsDynamic() && - ((model.hoverIndicatorPos >= ts.start + posLineStart) && - (model.hoverIndicatorPos <= ts.end() + posLineStart)); + bool hover = false; + if (indicator.IsDynamic()) { + const Sci::Position startPos = ts.start + posLineStart; + const Range rangeRun(deco->StartRun(startPos), deco->EndRun(startPos)); + hover = rangeRun.ContainsCharacter(model.hoverIndicatorPos); + } if (hover) { if (indicator.sacHover.style == INDIC_TEXTFORE) { textFore = indicator.sacHover.fore; @@ -1886,7 +1976,7 @@ void EditView::DrawLine(Surface *surface, const EditModel &model, const ViewStyl return; // No further drawing } - // See if something overrides the line background color. + // See if something overrides the line background colour. const ColourOptional background = vsDraw.Background(model.pdoc->GetMark(line), model.caret.active, ll->containsCaret); const Sci::Position posLineStart = model.pdoc->LineStart(line); @@ -1907,6 +1997,7 @@ void EditView::DrawLine(Surface *surface, const EditModel &model, const ViewStyl DrawBackground(surface, model, vsDraw, ll, rcLine, lineRange, posLineStart, xStart, subLine, background); DrawFoldDisplayText(surface, model, vsDraw, ll, line, xStart, rcLine, subLine, subLineStart, drawBack); + DrawEOLAnnotationText(surface, model, vsDraw, ll, line, xStart, rcLine, subLine, subLineStart, drawBack); phase = static_cast(phase & ~drawBack); // Remove drawBack to not draw again in DrawFoldDisplayText DrawEOL(surface, model, vsDraw, ll, rcLine, line, lineRange.end, xStart, subLine, subLineStart, background); @@ -1935,6 +2026,7 @@ void EditView::DrawLine(Surface *surface, const EditModel &model, const ViewStyl } DrawFoldDisplayText(surface, model, vsDraw, ll, line, xStart, rcLine, subLine, subLineStart, phase); + DrawEOLAnnotationText(surface, model, vsDraw, ll, line, xStart, rcLine, subLine, subLineStart, phase); if (phasesDraw == phasesOne) { DrawEOL(surface, model, vsDraw, ll, rcLine, line, lineRange.end, @@ -2283,13 +2375,11 @@ Sci::Position EditView::FormatRange(bool draw, const Sci_RangeToFormat *pfr, Sur vsPrint.Refresh(*surfaceMeasure, model.pdoc->tabInChars); // Recalculate fixedColumnWidth } - const Sci::Line linePrintStart = - model.pdoc->SciLineFromPosition(static_cast(pfr->chrg.cpMin)); + const Sci::Line linePrintStart = model.pdoc->SciLineFromPosition(pfr->chrg.cpMin); Sci::Line linePrintLast = linePrintStart + (pfr->rc.bottom - pfr->rc.top) / vsPrint.lineHeight - 1; if (linePrintLast < linePrintStart) linePrintLast = linePrintStart; - const Sci::Line linePrintMax = - model.pdoc->SciLineFromPosition(static_cast(pfr->chrg.cpMax)); + const Sci::Line linePrintMax = model.pdoc->SciLineFromPosition(pfr->chrg.cpMax); if (linePrintLast > linePrintMax) linePrintLast = linePrintMax; //Platform::DebugPrintf("Formatting lines=[%0d,%0d,%0d] top=%0d bottom=%0d line=%0d %0d\n", @@ -2307,10 +2397,10 @@ Sci::Position EditView::FormatRange(bool draw, const Sci_RangeToFormat *pfr, Sur Sci::Line lineDoc = linePrintStart; - Sci::Position nPrintPos = static_cast(pfr->chrg.cpMin); + Sci::Position nPrintPos = pfr->chrg.cpMin; int visibleLine = 0; int widthPrint = pfr->rc.right - pfr->rc.left - vsPrint.fixedColumnWidth; - if (printParameters.wrapState == eWrapNone) + if (printParameters.wrapState == WrapMode::none) widthPrint = LineLayout::wrapWidthInfinite; while (lineDoc <= linePrintLast && ypos < pfr->rc.bottom) { diff --git a/scintilla/src/EditView.h b/scintilla/src/EditView.h index 3addfbab8e..0ff5ef8349 100644 --- a/scintilla/src/EditView.h +++ b/scintilla/src/EditView.h @@ -33,7 +33,7 @@ enum DrawPhase { drawAll = 0x1FF }; -bool ValidStyledText(const ViewStyle &vs, size_t styleOffset, const StyledText &st); +bool ValidStyledText(const ViewStyle &vs, size_t styleOffset, const StyledText &st) noexcept; int WidestLineWidth(Surface *surface, const ViewStyle &vs, int styleOffset, const StyledText &st); void DrawTextNoClipPhase(Surface *surface, PRectangle rc, const Style &style, XYPOSITION ybase, const char *s, int len, DrawPhase phase); @@ -102,10 +102,10 @@ class EditView { bool LinesOverlap() const noexcept; void ClearAllTabstops() noexcept; - XYPOSITION NextTabstopPos(Sci::Line line, XYPOSITION x, XYPOSITION tabWidth) const; - bool ClearTabstops(Sci::Line line); + XYPOSITION NextTabstopPos(Sci::Line line, XYPOSITION x, XYPOSITION tabWidth) const noexcept; + bool ClearTabstops(Sci::Line line) noexcept; bool AddTabstop(Sci::Line line, int x); - int GetNextTabstop(Sci::Line line, int x) const; + int GetNextTabstop(Sci::Line line, int x) const noexcept; void LinesAddedOrRemoved(Sci::Line lineOfPos, Sci::Line linesAdded); void DropGraphics(bool freeObjects); @@ -131,6 +131,8 @@ class EditView { ColourOptional background); void DrawFoldDisplayText(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, Sci::Line line, int xStart, PRectangle rcLine, int subLine, XYACCUMULATOR subLineStart, DrawPhase phase); + void DrawEOLAnnotationText(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, + Sci::Line line, int xStart, PRectangle rcLine, int subLine, XYACCUMULATOR subLineStart, DrawPhase phase); void DrawAnnotation(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, Sci::Line line, int xStart, PRectangle rcLine, int subLine, DrawPhase phase); void DrawCarets(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, Sci::Line lineDoc, diff --git a/scintilla/src/Editor.cxx b/scintilla/src/Editor.cxx index 8f583636d6..684d205e60 100644 --- a/scintilla/src/Editor.cxx +++ b/scintilla/src/Editor.cxx @@ -28,7 +28,6 @@ #include "ILexer.h" #include "Scintilla.h" -#include "StringCopy.h" #include "CharacterSet.h" #include "CharacterCategory.h" #include "Position.h" @@ -134,7 +133,7 @@ Editor::Editor() : durationWrapOneLine(0.00001, 0.000001, 0.0001) { dropWentOutside = false; posDrop = SelectionPosition(Sci::invalidPosition); hotSpotClickPos = INVALID_POSITION; - selectionType = selChar; + selectionUnit = TextUnit::character; lastXChosen = 0; lineAnchorPos = 0; @@ -143,14 +142,10 @@ Editor::Editor() : durationWrapOneLine(0.00001, 0.000001, 0.0001) { wordSelectAnchorEndPos = 0; wordSelectInitialCaretPos = -1; - caretXPolicy = CARET_SLOP | CARET_EVEN; - caretXSlop = 50; + caretPolicies.x = { CARET_SLOP | CARET_EVEN, 50 }; + caretPolicies.y = { CARET_EVEN, 0 }; - caretYPolicy = CARET_EVEN; - caretYSlop = 0; - - visiblePolicy = 0; - visibleSlop = 0; + visiblePolicy = { 0, 0 }; searchAnchor = 0; @@ -167,8 +162,7 @@ Editor::Editor() : durationWrapOneLine(0.00001, 0.000001, 0.0001) { multiPasteMode = SC_MULTIPASTE_ONCE; virtualSpaceOptions = SCVS_NONE; - targetStart = 0; - targetEnd = 0; + targetRange = SelectionSegment(); searchFlags = 0; topLine = 0; @@ -219,10 +213,11 @@ void Editor::SetRepresentations() { "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB", "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US" }; - for (size_t j=0; j < ELEMENTS(reps); j++) { + for (size_t j=0; j < Sci::size(reps); j++) { const char c[2] = { static_cast(j), 0 }; reprs.SetRepresentation(c, reps[j]); } + reprs.SetRepresentation("\x7f", "DEL"); // C1 control set // As well as Unicode mode, ISO-8859-1 should use these @@ -233,7 +228,7 @@ void Editor::SetRepresentations() { "DCS", "PU1", "PU2", "STS", "CCH", "MW", "SPA", "EPA", "SOS", "SGCI", "SCI", "CSI", "ST", "OSC", "PM", "APC" }; - for (size_t j=0; j < ELEMENTS(repsC1); j++) { + for (size_t j=0; j < Sci::size(repsC1); j++) { const char c1[3] = { '\xc2', static_cast(0x80+j), 0 }; reprs.SetRepresentation(c1, repsC1[j]); } @@ -278,7 +273,7 @@ void Editor::InvalidateStyleData() { vs.technology = technology; DropGraphics(false); AllocateGraphics(); - view.llc.Invalidate(LineLayout::llInvalid); + view.llc.Invalidate(LineLayout::ValidLevel::invalid); view.posCache.Clear(); } @@ -567,7 +562,7 @@ Sci::Position Editor::CurrentPosition() const { return sel.MainCaret(); } -bool Editor::SelectionEmpty() const { +bool Editor::SelectionEmpty() const noexcept { return sel.Empty(); } @@ -591,8 +586,11 @@ void Editor::SetRectangularRange() { const Sci::Line lineCaret = pdoc->SciLineFromPosition(sel.Rectangular().caret.Position()); const int increment = (lineCaret > lineAnchorRect) ? 1 : -1; + AutoSurface surface(this); for (Sci::Line line=lineAnchorRect; line != lineCaret+increment; line += increment) { - SelectionRange range(SPositionFromLineX(line, xCaret), SPositionFromLineX(line, xAnchor)); + SelectionRange range( + view.SPositionFromLineX(surface, *this, line, xCaret, vs), + view.SPositionFromLineX(surface, *this, line, xAnchor, vs)); if ((virtualSpaceOptions & SCVS_RECTANGULARSELECTION) == 0) range.ClearVirtualSpace(); if (line == lineAnchorRect) @@ -749,7 +747,7 @@ void Editor::MultipleSelectAdd(AddNumber addNumber) { const Range rangeMainSelection(sel.RangeMain().Start().Position(), sel.RangeMain().End().Position()); const std::string selectedText = RangeText(rangeMainSelection.start, rangeMainSelection.end); - const Range rangeTarget(targetStart, targetEnd); + const Range rangeTarget(targetRange.start.Position(), targetRange.end.Position()); std::vector searchRanges; // Search should be over the target range excluding the current selection so // may need to search 2 ranges, after the selection then before the selection. @@ -777,7 +775,7 @@ void Editor::MultipleSelectAdd(AddNumber addNumber) { ContainerNeedsUpdate(SC_UPDATE_SELECTION); ScrollRange(sel.RangeMain()); Redraw(); - if (addNumber == addOne) + if (addNumber == AddNumber::one) return; searchStart = pos + lengthFound; } else { @@ -788,7 +786,7 @@ void Editor::MultipleSelectAdd(AddNumber addNumber) { } } -bool Editor::RangeContainsProtected(Sci::Position start, Sci::Position end) const { +bool Editor::RangeContainsProtected(Sci::Position start, Sci::Position end) const noexcept { if (vs.ProtectionActive()) { if (start > end) { const Sci::Position t = start; @@ -803,7 +801,7 @@ bool Editor::RangeContainsProtected(Sci::Position start, Sci::Position end) cons return false; } -bool Editor::SelectionContainsProtected() { +bool Editor::SelectionContainsProtected() const { for (size_t r=0; rSciLineFromPosition(newPos.Position()); if (ensureVisible) { // In case in need of wrapping to ensure DisplayFromDoc works. @@ -852,7 +851,7 @@ void Editor::MovedCaret(SelectionPosition newPos, SelectionPosition previousPos, } } const XYScrollPosition newXY = XYScrollToMakeVisible( - SelectionRange(posDrag.IsValid() ? posDrag : newPos), xysDefault); + SelectionRange(posDrag.IsValid() ? posDrag : newPos), xysDefault, policies); if (previousPos.IsValid() && (newXY.xOffset == xOffset)) { // simple vertical scroll then invalidate ScrollTo(newXY.topLine); @@ -902,7 +901,7 @@ void Editor::MovePositionTo(SelectionPosition newPos, Selection::selTypes selt, SetEmptySelection(newPos); } - MovedCaret(newPos, spCaret, ensureVisible); + MovedCaret(newPos, spCaret, ensureVisible, caretPolicies); } void Editor::MovePositionTo(Sci::Position newPos, Selection::selTypes selt, bool ensureVisible) { @@ -1103,7 +1102,7 @@ Sci::Line Editor::DisplayFromPosition(Sci::Position pos) { /** * Ensure the caret is reasonably visible in context. * -Caret policy in SciTE +Caret policy in Scintilla If slop is set, we can define a slop value. This value defines an unwanted zone (UZ) where the caret is... unwanted. @@ -1146,7 +1145,8 @@ slop | strict | jumps | even | Caret can go to the margin | When 1 | 1 | 1 | 1 | No, kept out of UZ | moved to put caret at 3UZ of the margin */ -Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const SelectionRange &range, const XYScrollOptions options) { +Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const SelectionRange &range, + const XYScrollOptions options, CaretPolicies policies) { const PRectangle rcClient = GetTextRectangle(); const Point ptOrigin = GetVisibleOriginInMain(); const Point pt = LocationFromPosition(range.caret) + ptOrigin; @@ -1159,14 +1159,14 @@ Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const SelectionRange &ran } // Vertical positioning - if ((options & xysVertical) && (pt.y < rcClient.top || ptBottomCaret.y >= rcClient.bottom || (caretYPolicy & CARET_STRICT) != 0)) { + if ((options & xysVertical) && (pt.y < rcClient.top || ptBottomCaret.y >= rcClient.bottom || (policies.y.policy & CARET_STRICT) != 0)) { const Sci::Line lineCaret = DisplayFromPosition(range.caret.Position()); const Sci::Line linesOnScreen = LinesOnScreen(); const Sci::Line halfScreen = std::max(linesOnScreen - 1, static_cast(2)) / 2; - const bool bSlop = (caretYPolicy & CARET_SLOP) != 0; - const bool bStrict = (caretYPolicy & CARET_STRICT) != 0; - const bool bJump = (caretYPolicy & CARET_JUMPS) != 0; - const bool bEven = (caretYPolicy & CARET_EVEN) != 0; + const bool bSlop = (policies.y.policy & CARET_SLOP) != 0; + const bool bStrict = (policies.y.policy & CARET_STRICT) != 0; + const bool bJump = (policies.y.policy & CARET_JUMPS) != 0; + const bool bEven = (policies.y.policy & CARET_EVEN) != 0; // It should be possible to scroll the window to show the caret, // but this fails to remove the caret on GTK+ @@ -1180,8 +1180,8 @@ Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const SelectionRange &ran yMarginT = yMarginB = 0; } else { // yMarginT must equal to caretYSlop, with a minimum of 1 and - // a maximum of slightly less than half the heigth of the text area. - yMarginT = Sci::clamp(static_cast(caretYSlop), static_cast(1), halfScreen); + // a maximum of slightly less than half the height of the text area. + yMarginT = Sci::clamp(static_cast(policies.y.slop), static_cast(1), halfScreen); if (bEven) { yMarginB = yMarginT; } else { @@ -1191,7 +1191,7 @@ Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const SelectionRange &ran yMoveT = yMarginT; if (bEven) { if (bJump) { - yMoveT = Sci::clamp(static_cast(caretYSlop * 3), static_cast(1), halfScreen); + yMoveT = Sci::clamp(static_cast(policies.y.slop * 3), static_cast(1), halfScreen); } yMoveB = yMoveT; } else { @@ -1205,7 +1205,7 @@ Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const SelectionRange &ran newXY.topLine = lineCaret - linesOnScreen + 1 + yMoveB; } } else { // Not strict - yMoveT = bJump ? caretYSlop * 3 : caretYSlop; + yMoveT = bJump ? policies.y.slop * 3 : policies.y.slop; yMoveT = Sci::clamp(yMoveT, static_cast(1), halfScreen); if (bEven) { yMoveB = yMoveT; @@ -1236,7 +1236,7 @@ Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const SelectionRange &ran } } else { // Strict or going out of display if (bEven) { - // Always center caret + // Always centre caret newXY.topLine = lineCaret - halfScreen; } else { // Always put caret on top of display @@ -1262,10 +1262,10 @@ Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const SelectionRange &ran // Horizontal positioning if ((options & xysHorizontal) && !Wrapping()) { const int halfScreen = std::max(static_cast(rcClient.Width()) - 4, 4) / 2; - const bool bSlop = (caretXPolicy & CARET_SLOP) != 0; - const bool bStrict = (caretXPolicy & CARET_STRICT) != 0; - const bool bJump = (caretXPolicy & CARET_JUMPS) != 0; - const bool bEven = (caretXPolicy & CARET_EVEN) != 0; + const bool bSlop = (policies.x.policy & CARET_SLOP) != 0; + const bool bStrict = (policies.x.policy & CARET_STRICT) != 0; + const bool bJump = (policies.x.policy & CARET_JUMPS) != 0; + const bool bEven = (policies.x.policy & CARET_EVEN) != 0; if (bSlop) { // A margin is defined int xMoveL, xMoveR; @@ -1278,7 +1278,7 @@ Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const SelectionRange &ran } else { // xMargin must equal to caretXSlop, with a minimum of 2 and // a maximum of slightly less than half the width of the text area. - xMarginR = Sci::clamp(caretXSlop, 2, halfScreen); + xMarginR = Sci::clamp(policies.x.slop, 2, halfScreen); if (bEven) { xMarginL = xMarginR; } else { @@ -1287,7 +1287,7 @@ Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const SelectionRange &ran } if (bJump && bEven) { // Jump is used only in even mode - xMoveL = xMoveR = Sci::clamp(caretXSlop * 3, 1, halfScreen); + xMoveL = xMoveR = Sci::clamp(policies.x.slop * 3, 1, halfScreen); } else { xMoveL = xMoveR = 0; // Not used, avoid a warning } @@ -1309,7 +1309,7 @@ Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const SelectionRange &ran } } } else { // Not strict - xMoveR = bJump ? caretXSlop * 3 : caretXSlop; + xMoveR = bJump ? policies.x.slop * 3 : policies.x.slop; xMoveR = Sci::clamp(xMoveR, 1, halfScreen); if (bEven) { xMoveL = xMoveR; @@ -1329,7 +1329,7 @@ Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const SelectionRange &ran (bJump && (pt.x < rcClient.left || pt.x >= rcClient.right))) { // Strict or going out of display if (bEven) { - // Center caret + // Centre caret newXY.xOffset += static_cast(pt.x - rcClient.left - halfScreen); } else { // Put caret on right @@ -1408,12 +1408,13 @@ void Editor::SetXYScroll(XYScrollPosition newXY) { } void Editor::ScrollRange(SelectionRange range) { - SetXYScroll(XYScrollToMakeVisible(range, xysDefault)); + SetXYScroll(XYScrollToMakeVisible(range, xysDefault, caretPolicies)); } void Editor::EnsureCaretVisible(bool useMargin, bool vert, bool horiz) { SetXYScroll(XYScrollToMakeVisible(SelectionRange(posDrag.IsValid() ? posDrag : sel.RangeMain().caret), - static_cast((useMargin?xysUseMargin:0)|(vert?xysVertical:0)|(horiz?xysHorizontal:0)))); + static_cast((useMargin?xysUseMargin:0)|(vert?xysVertical:0)|(horiz?xysHorizontal:0)), + caretPolicies)); } void Editor::ShowCaretAtCurrentPosition() { @@ -1466,13 +1467,13 @@ void Editor::UpdateSystemCaret() { } bool Editor::Wrapping() const noexcept { - return vs.wrapState != eWrapNone; + return vs.wrapState != WrapMode::none; } void Editor::NeedWrapping(Sci::Line docLineStart, Sci::Line docLineEnd) { //Platform::DebugPrintf("\nNeedWrapping: %0d..%0d\n", docLineStart, docLineEnd); if (wrapPending.AddRange(docLineStart, docLineEnd)) { - view.llc.Invalidate(LineLayout::llPositions); + view.llc.Invalidate(LineLayout::ValidLevel::positions); } // Wrap lines during idle. if (Wrapping() && wrapPending.NeedsWrap()) { @@ -1540,7 +1541,7 @@ bool Editor::WrapLines(WrapScope ws) { } } else if (ws == WrapScope::wsIdle) { // Try to keep time taken by wrapping reasonable so interaction remains smooth. - const double secondsAllowed = 0.01; + constexpr double secondsAllowed = 0.01; const Sci::Line linesInAllowedTime = Sci::clamp( static_cast(secondsAllowed / durationWrapOneLine.Duration()), LinesOnScreen() + 50, static_cast(0x10000)); @@ -1595,17 +1596,17 @@ bool Editor::WrapLines(WrapScope ws) { } void Editor::LinesJoin() { - if (!RangeContainsProtected(targetStart, targetEnd)) { + if (!RangeContainsProtected(targetRange.start.Position(), targetRange.end.Position())) { UndoGroup ug(pdoc); bool prevNonWS = true; - for (Sci::Position pos = targetStart; pos < targetEnd; pos++) { + for (Sci::Position pos = targetRange.start.Position(); pos < targetRange.end.Position(); pos++) { if (pdoc->IsPositionInLineEnd(pos)) { - targetEnd -= pdoc->LenChar(pos); + targetRange.end.Add(-pdoc->LenChar(pos)); pdoc->DelChar(pos); if (prevNonWS) { // Ensure at least one space separating previous lines const Sci::Position lengthInserted = pdoc->InsertString(pos, " ", 1); - targetEnd += lengthInserted; + targetRange.end.Add(lengthInserted); } } else { prevNonWS = pdoc->CharAt(pos) != ' '; @@ -1625,13 +1626,13 @@ const char *Editor::StringFromEOLMode(int eolMode) noexcept { } void Editor::LinesSplit(int pixelWidth) { - if (!RangeContainsProtected(targetStart, targetEnd)) { + if (!RangeContainsProtected(targetRange.start.Position(), targetRange.end.Position())) { if (pixelWidth == 0) { const PRectangle rcText = GetTextRectangle(); pixelWidth = static_cast(rcText.Width()); } - const Sci::Line lineStart = pdoc->SciLineFromPosition(targetStart); - Sci::Line lineEnd = pdoc->SciLineFromPosition(targetEnd); + const Sci::Line lineStart = pdoc->SciLineFromPosition(targetRange.start.Position()); + Sci::Line lineEnd = pdoc->SciLineFromPosition(targetRange.end.Position()); const char *eol = StringFromEOLMode(pdoc->eolMode); UndoGroup ug(pdoc); for (Sci::Line line = lineStart; line <= lineEnd; line++) { @@ -1645,11 +1646,11 @@ void Editor::LinesSplit(int pixelWidth) { const Sci::Position lengthInserted = pdoc->InsertString( posLineStart + lengthInsertedTotal + ll->LineStart(subLine), eol, strlen(eol)); - targetEnd += lengthInserted; + targetRange.end.Add(lengthInserted); lengthInsertedTotal += lengthInserted; } } - lineEnd = pdoc->SciLineFromPosition(targetEnd); + lineEnd = pdoc->SciLineFromPosition(targetRange.end.Position()); } } } @@ -1747,7 +1748,13 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { } RefreshPixMaps(surfaceWindow); // In case pixmaps invalidated by scrollbar change } - PLATFORM_ASSERT(marginView.pixmapSelPattern->Initialised()); + + if (!marginView.pixmapSelPattern->Initialised()) { + // When Direct2D is used, pixmap creation may fail with D2DERR_RECREATE_TARGET so + // abandon this paint to avoid further failures. + // Main drawing surface and pixmaps should be recreated by next paint. + return; + } if (!view.bufferedDraw) surfaceWindow->SetClip(rcArea); @@ -1813,11 +1820,11 @@ Sci::Position Editor::FormatRange(bool draw, const Sci_RangeToFormat *pfr) { return view.FormatRange(draw, pfr, surface, surfaceMeasure, *this, vs); } -int Editor::TextWidth(int style, const char *text) { +long Editor::TextWidth(uptr_t style, const char *text) { RefreshStyleData(); AutoSurface surface(this); if (surface) { - return static_cast(surface->WidthText(vs.styles[style].font, text, static_cast(strlen(text)))); + return Sci::lround(surface->WidthText(vs.styles[style].font, text, static_cast(strlen(text)))); } else { return 1; } @@ -1888,7 +1895,7 @@ void Editor::AddChar(char ch) { char s[2]; s[0] = ch; s[1] = '\0'; - AddCharUTF(s, 1); + InsertCharacter(s, 1, CharacterSource::directInput); } void Editor::FilterSelections() { @@ -1898,8 +1905,8 @@ void Editor::FilterSelections() { } } -// AddCharUTF inserts an array of bytes which may or may not be in UTF-8. -void Editor::AddCharUTF(const char *s, unsigned int len, bool treatAsDBCS) { +// InsertCharacter inserts a character encoded in document code page. +void Editor::InsertCharacter(const char *s, unsigned int len, CharacterSource charSource) { if (len == 0) { return; } @@ -1914,7 +1921,7 @@ void Editor::AddCharUTF(const char *s, unsigned int len, bool treatAsDBCS) { } // Order selections by position in document. std::sort(selPtrs.begin(), selPtrs.end(), - [](const SelectionRange *a, const SelectionRange *b) {return *a < *b;}); + [](const SelectionRange *a, const SelectionRange *b) noexcept {return *a < *b;}); // Loop in reverse to avoid disturbing positions of selections yet to be processed. for (std::vector::reverse_iterator rit = selPtrs.rbegin(); @@ -1974,7 +1981,7 @@ void Editor::AddCharUTF(const char *s, unsigned int len, bool treatAsDBCS) { } int ch = static_cast(s[0]); - if (treatAsDBCS || pdoc->dbcsCodePage != SC_CP_UTF8) { + if (pdoc->dbcsCodePage != SC_CP_UTF8) { if (len > 1) { // DBCS code page or DBCS font character set. ch = (ch << 8) | static_cast(s[1]); @@ -1987,14 +1994,15 @@ void Editor::AddCharUTF(const char *s, unsigned int len, bool treatAsDBCS) { // characters representing themselves. } else { unsigned int utf32[1] = { 0 }; - UTF32FromUTF8(s, len, utf32, ELEMENTS(utf32)); + UTF32FromUTF8(s, len, utf32, Sci::size(utf32)); ch = utf32[0]; } } - NotifyChar(ch); + NotifyChar(ch, charSource); - if (recordingMacro) { - NotifyMacroRecord(SCI_REPLACESEL, 0, reinterpret_cast(s)); + if (recordingMacro && charSource != CharacterSource::tentativeInput) { + std::string copy(s, len); // ensure NUL-terminated + NotifyMacroRecord(SCI_REPLACESEL, 0, reinterpret_cast(copy.data())); } } @@ -2115,6 +2123,7 @@ void Editor::ClearAll() { if (!pdoc->IsReadOnly()) { pcs->Clear(); pdoc->AnnotationClearAll(); + pdoc->EOLAnnotationClearAll(); pdoc->MarginClearAll(); } } @@ -2338,10 +2347,11 @@ void Editor::NotifyErrorOccurred(Document *, void *, int status) { errorStatus = status; } -void Editor::NotifyChar(int ch) { +void Editor::NotifyChar(int ch, CharacterSource charSource) { SCNotification scn = {}; scn.nmhdr.code = SCN_CHARADDED; scn.ch = ch; + scn.characterSource = static_cast(charSource); NotifyParent(scn); } @@ -2514,7 +2524,7 @@ void Editor::NotifySavePoint(Document *, void *, bool atSavePoint) { void Editor::CheckModificationForWrap(DocModification mh) { if (mh.modificationType & (SC_MOD_INSERTTEXT | SC_MOD_DELETETEXT)) { - view.llc.Invalidate(LineLayout::llCheckTextAndStyle); + view.llc.Invalidate(LineLayout::ValidLevel::checkTextAndStyle); const Sci::Line lineDoc = pdoc->SciLineFromPosition(mh.position); const Sci::Line lines = std::max(static_cast(0), mh.linesAdded); if (Wrapping()) { @@ -2593,7 +2603,7 @@ void Editor::NotifyModified(Document *, DocModification mh, void *) { } } if (mh.modificationType & SC_MOD_CHANGESTYLE) { - view.llc.Invalidate(LineLayout::llCheckTextAndStyle); + view.llc.Invalidate(LineLayout::ValidLevel::checkTextAndStyle); } } else { // Move selection and brace highlights @@ -2649,6 +2659,11 @@ void Editor::NotifyModified(Document *, DocModification mh, void *) { Redraw(); } } + if (mh.modificationType & SC_MOD_CHANGEEOLANNOTATION) { + if (vs.eolAnnotationVisible) { + Redraw(); + } + } CheckModificationForWrap(mh); if (mh.linesAdded != 0) { // Avoid scrolling of display if change before current display @@ -2876,20 +2891,20 @@ void Editor::PageMove(int direction, Selection::selTypes selt, bool stuttered) { SelectionPosition newPos; const Sci::Line currentLine = pdoc->SciLineFromPosition(sel.MainCaret()); - const Sci::Line topStutterLine = topLine + caretYSlop; + const Sci::Line topStutterLine = topLine + caretPolicies.y.slop; const Sci::Line bottomStutterLine = pdoc->SciLineFromPosition(PositionFromLocation( Point::FromInts(lastXChosen - xOffset, direction * vs.lineHeight * static_cast(LinesToScroll())))) - - caretYSlop - 1; + - caretPolicies.y.slop - 1; if (stuttered && (direction < 0 && currentLine > topStutterLine)) { topLineNew = topLine; - newPos = SPositionFromLocation(Point::FromInts(lastXChosen - xOffset, vs.lineHeight * caretYSlop), + newPos = SPositionFromLocation(Point::FromInts(lastXChosen - xOffset, vs.lineHeight * caretPolicies.y.slop), false, false, UserVirtualSpace()); } else if (stuttered && (direction > 0 && currentLine < bottomStutterLine)) { topLineNew = topLine; - newPos = SPositionFromLocation(Point::FromInts(lastXChosen - xOffset, vs.lineHeight * static_cast(LinesToScroll() - caretYSlop)), + newPos = SPositionFromLocation(Point::FromInts(lastXChosen - xOffset, vs.lineHeight * static_cast(LinesToScroll() - caretPolicies.y.slop)), false, false, UserVirtualSpace()); } else { @@ -3087,7 +3102,7 @@ void Editor::NewLine() { for (size_t i = 0; i < countInsertions; i++) { const char *eol = StringFromEOLMode(pdoc->eolMode); while (*eol) { - NotifyChar(*eol); + NotifyChar(*eol, CharacterSource::directInput); if (recordingMacro) { char txt[2]; txt[0] = *eol; @@ -3176,7 +3191,7 @@ void Editor::CursorUpOrDown(int direction, Selection::selTypes selt) { sel.selType = Selection::selRectangle; sel.Rectangular() = SelectionRange(posNew, rangeBase.anchor); SetRectangularRange(); - MovedCaret(posNew, caretToUse, true); + MovedCaret(posNew, caretToUse, true, caretPolicies); } else if (sel.selType == Selection::selLines && sel.MoveExtends()) { // Calculate new caret position and call SetSelection(), which will ensure whole lines are selected. const SelectionPosition posNew = MovePositionSoVisible( @@ -3197,7 +3212,7 @@ void Editor::CursorUpOrDown(int direction, Selection::selTypes selt) { SelectionRange(posNew, sel.Range(r).anchor) : SelectionRange(posNew); } sel.RemoveDuplicates(); - MovedCaret(sel.RangeMain().caret, caretToUse, true); + MovedCaret(sel.RangeMain().caret, caretToUse, true, caretPolicies); } } @@ -3594,7 +3609,7 @@ int Editor::HorizontalMove(unsigned int iMessage) { sel.RemoveDuplicates(); - MovedCaret(sel.RangeMain().caret, SelectionPosition(INVALID_POSITION), true); + MovedCaret(sel.RangeMain().caret, SelectionPosition(INVALID_POSITION), true, caretPolicies); // Invalidate the new state of the selection InvalidateWholeSelection(); @@ -3665,7 +3680,7 @@ int Editor::DelWordOrLine(unsigned int iMessage) { // May need something stronger here: can selections overlap at this point? sel.RemoveDuplicates(); - MovedCaret(sel.RangeMain().caret, SelectionPosition(INVALID_POSITION), true); + MovedCaret(sel.RangeMain().caret, SelectionPosition(INVALID_POSITION), true, caretPolicies); // Invalidate the new state of the selection InvalidateWholeSelection(); @@ -4148,12 +4163,12 @@ Sci::Position Editor::SearchInTarget(const char *text, Sci::Position length) { if (!pdoc->HasCaseFolder()) pdoc->SetCaseFolder(CaseFolderForEncoding()); try { - const Sci::Position pos = pdoc->FindText(targetStart, targetEnd, text, + const Sci::Position pos = pdoc->FindText(targetRange.start.Position(), targetRange.end.Position(), text, searchFlags, &lengthFound); if (pos != -1) { - targetStart = pos; - targetEnd = pos + lengthFound; + targetRange.start.SetPosition(pos); + targetRange.end.SetPosition(pos + lengthFound); } return pos; } catch (RegexError &) { @@ -4248,6 +4263,12 @@ void Editor::SetDragPosition(SelectionPosition newPos) { posDrop = newPos; } if (!(posDrag == newPos)) { + const CaretPolicies dragCaretPolicies = { + CaretPolicy(CARET_SLOP | CARET_STRICT | CARET_EVEN, 50), + CaretPolicy(CARET_SLOP | CARET_STRICT | CARET_EVEN, 2) + }; + MovedCaret(newPos, posDrag, true, dragCaretPolicies); + caret.on = true; FineTickerCancel(tickCaret); if ((caret.active) && (caret.period > 0) && (newPos.Position() < 0)) @@ -4411,7 +4432,8 @@ void Editor::TrimAndSetSelection(Sci::Position currentPos_, Sci::Position anchor } void Editor::LineSelection(Sci::Position lineCurrentPos_, Sci::Position lineAnchorPos_, bool wholeLine) { - Sci::Position selCurrentPos, selAnchorPos; + Sci::Position selCurrentPos; + Sci::Position selAnchorPos; if (wholeLine) { const Sci::Line lineCurrent_ = pdoc->SciLineFromPosition(lineCurrentPos_); const Sci::Line lineAnchor_ = pdoc->SciLineFromPosition(lineAnchorPos_); @@ -4481,6 +4503,7 @@ void Editor::DwellEnd(bool mouseMoved) { void Editor::MouseLeave() { SetHotSpotRange(nullptr); + SetHoverIndicatorPosition(Sci::invalidPosition); if (!HaveMouseCapture()) { ptMouseLast = Point(-1, -1); DwellEnd(true); @@ -4526,41 +4549,42 @@ void Editor::ButtonDownWithModifiers(Point pt, unsigned int curTime, int modifie //Platform::DebugPrintf("Double click %d %d = %d\n", curTime, lastClickTime, curTime - lastClickTime); SetMouseCapture(true); FineTickerStart(tickScroll, 100, 10); - if (!ctrl || !multipleSelection || (selectionType != selChar && selectionType != selWord)) + if (!ctrl || !multipleSelection || (selectionUnit != TextUnit::character && selectionUnit != TextUnit::word)) SetEmptySelection(newPos.Position()); bool doubleClick = false; if (inSelMargin) { - // Inside margin selection type should be either selSubLine or selWholeLine. - if (selectionType == selSubLine) { - // If it is selSubLine, we're inside a *double* click and word wrap is enabled, - // so we switch to selWholeLine in order to select whole line. - selectionType = selWholeLine; - } else if (selectionType != selSubLine && selectionType != selWholeLine) { + // Inside margin selection type should be either subLine or wholeLine. + if (selectionUnit == TextUnit::subLine) { + // If it is subLine, we're inside a *double* click and word wrap is enabled, + // so we switch to wholeLine in order to select whole line. + selectionUnit = TextUnit::wholeLine; + } else if (selectionUnit != TextUnit::subLine && selectionUnit != TextUnit::wholeLine) { // If it is neither, reset selection type to line selection. - selectionType = (Wrapping() && (marginOptions & SC_MARGINOPTION_SUBLINESELECT)) ? selSubLine : selWholeLine; + selectionUnit = (Wrapping() && (marginOptions & SC_MARGINOPTION_SUBLINESELECT)) ? TextUnit::subLine : TextUnit::wholeLine; } } else { - if (selectionType == selChar) { - selectionType = selWord; + if (selectionUnit == TextUnit::character) { + selectionUnit = TextUnit::word; doubleClick = true; - } else if (selectionType == selWord) { + } else if (selectionUnit == TextUnit::word) { // Since we ended up here, we're inside a *triple* click, which should always select // whole line regardless of word wrap being enabled or not. - selectionType = selWholeLine; + selectionUnit = TextUnit::wholeLine; } else { - selectionType = selChar; + selectionUnit = TextUnit::character; originalAnchorPos = sel.MainCaret(); } } - if (selectionType == selWord) { + if (selectionUnit == TextUnit::word) { Sci::Position charPos = originalAnchorPos; if (sel.MainCaret() == originalAnchorPos) { charPos = PositionFromLocation(pt, false, true); charPos = MovePositionOutsideChar(charPos, -1); } - Sci::Position startWord, endWord; + Sci::Position startWord; + Sci::Position endWord; if ((sel.MainCaret() >= originalAnchorPos) && !pdoc->IsLineEndPosition(charPos)) { startWord = pdoc->ExtendWordSelect(pdoc->MovePositionOutsideChar(charPos + 1, 1), -1); endWord = pdoc->ExtendWordSelect(charPos, 1); @@ -4581,9 +4605,9 @@ void Editor::ButtonDownWithModifiers(Point pt, unsigned int curTime, int modifie wordSelectAnchorEndPos = endWord; wordSelectInitialCaretPos = sel.MainCaret(); WordSelection(wordSelectInitialCaretPos); - } else if (selectionType == selSubLine || selectionType == selWholeLine) { + } else if (selectionUnit == TextUnit::subLine || selectionUnit == TextUnit::wholeLine) { lineAnchorPos = newPos.Position(); - LineSelection(lineAnchorPos, lineAnchorPos, selectionType == selWholeLine); + LineSelection(lineAnchorPos, lineAnchorPos, selectionUnit == TextUnit::wholeLine); //Platform::DebugPrintf("Triple click: %d - %d\n", anchor, currentPos); } else { SetEmptySelection(sel.MainCaret()); @@ -4602,10 +4626,10 @@ void Editor::ButtonDownWithModifiers(Point pt, unsigned int curTime, int modifie } sel.selType = Selection::selStream; if (!shift) { - // Single click in margin: select whole line or only subline if word wrap is enabled + // Single click in margin: select wholeLine or only subLine if word wrap is enabled lineAnchorPos = newPos.Position(); - selectionType = (Wrapping() && (marginOptions & SC_MARGINOPTION_SUBLINESELECT)) ? selSubLine : selWholeLine; - LineSelection(lineAnchorPos, lineAnchorPos, selectionType == selWholeLine); + selectionUnit = (Wrapping() && (marginOptions & SC_MARGINOPTION_SUBLINESELECT)) ? TextUnit::subLine : TextUnit::wholeLine; + LineSelection(lineAnchorPos, lineAnchorPos, selectionUnit == TextUnit::wholeLine); } else { // Single shift+click in margin: select from line anchor to clicked line if (sel.MainAnchor() > sel.MainCaret()) @@ -4614,11 +4638,11 @@ void Editor::ButtonDownWithModifiers(Point pt, unsigned int curTime, int modifie lineAnchorPos = sel.MainAnchor(); // Reset selection type if there is an empty selection. // This ensures that we don't end up stuck in previous selection mode, which is no longer valid. - // Otherwise, if there's a non empty selection, reset selection type only if it differs from selSubLine and selWholeLine. + // Otherwise, if there's a non empty selection, reset selection type only if it differs from subLine and wholeLine. // This ensures that we continue selecting in the same selection mode. - if (sel.Empty() || (selectionType != selSubLine && selectionType != selWholeLine)) - selectionType = (Wrapping() && (marginOptions & SC_MARGINOPTION_SUBLINESELECT)) ? selSubLine : selWholeLine; - LineSelection(newPos.Position(), lineAnchorPos, selectionType == selWholeLine); + if (sel.Empty() || (selectionUnit != TextUnit::subLine && selectionUnit != TextUnit::wholeLine)) + selectionUnit = (Wrapping() && (marginOptions & SC_MARGINOPTION_SUBLINESELECT)) ? TextUnit::subLine : TextUnit::wholeLine; + LineSelection(newPos.Position(), lineAnchorPos, selectionUnit == TextUnit::wholeLine); } SetDragPosition(SelectionPosition(Sci::invalidPosition)); @@ -4659,7 +4683,7 @@ void Editor::ButtonDownWithModifiers(Point pt, unsigned int curTime, int modifie anchorCurrent = sel.IsRectangular() ? sel.Rectangular().anchor : sel.RangeMain().anchor; sel.selType = alt ? Selection::selRectangle : Selection::selStream; - selectionType = selChar; + selectionUnit = TextUnit::character; originalAnchorPos = sel.MainCaret(); sel.Rectangular() = SelectionRange(newPos, anchorCurrent); SetRectangularRange(); @@ -4786,7 +4810,7 @@ void Editor::ButtonMoveWithModifiers(Point pt, unsigned int, int modifiers) { if (posDrag.IsValid()) { SetDragPosition(movePos); } else { - if (selectionType == selChar) { + if (selectionUnit == TextUnit::character) { if (sel.selType == Selection::selStream && (modifiers & SCI_ALT) && mouseSelectionRectangularSwitch) { sel.selType = Selection::selRectangle; } @@ -4801,7 +4825,7 @@ void Editor::ButtonMoveWithModifiers(Point pt, unsigned int, int modifiers) { } else { SetSelection(movePos, sel.RangeMain().anchor); } - } else if (selectionType == selWord) { + } else if (selectionUnit == TextUnit::word) { // Continue selecting by word if (movePos.Position() == wordSelectInitialCaretPos) { // Didn't move // No need to do anything. Previously this case was lumped @@ -4819,13 +4843,13 @@ void Editor::ButtonMoveWithModifiers(Point pt, unsigned int, int modifiers) { } } else { // Continue selecting by line - LineSelection(movePos.Position(), lineAnchorPos, selectionType == selWholeLine); + LineSelection(movePos.Position(), lineAnchorPos, selectionUnit == TextUnit::wholeLine); } } // Autoscroll const Sci::Line lineMove = DisplayFromPosition(movePos.Position()); - if (pt.y > rcClient.bottom) { + if (pt.y >= rcClient.bottom) { ScrollTo(lineMove - LinesOnScreen() + 1); Redraw(); } else if (pt.y < rcClient.top) { @@ -4849,12 +4873,14 @@ void Editor::ButtonMoveWithModifiers(Point pt, unsigned int, int modifiers) { if (PointInSelMargin(pt)) { DisplayCursor(GetMarginCursor(pt)); SetHotSpotRange(nullptr); + SetHoverIndicatorPosition(Sci::invalidPosition); return; // No need to test for selection } } // Display regular (drag) cursor over selection if (PointInSelection(pt) && !SelectionEmpty()) { DisplayCursor(Window::cursorArrow); + SetHoverIndicatorPosition(Sci::invalidPosition); } else { SetHoverIndicatorPoint(pt); if (PointIsHotspot(pt)) { @@ -4881,7 +4907,7 @@ void Editor::ButtonUpWithModifiers(Point pt, unsigned int curTime, int modifiers if (inDragDrop == ddInitial) { inDragDrop = ddNone; SetEmptySelection(newPos); - selectionType = selChar; + selectionUnit = TextUnit::character; originalAnchorPos = sel.MainCaret(); } if (hotSpotClickPos != INVALID_POSITION && PointIsHotspot(pt)) { @@ -4933,10 +4959,10 @@ void Editor::ButtonUpWithModifiers(Point pt, unsigned int curTime, int modifiers } drag.Clear(); } - selectionType = selChar; + selectionUnit = TextUnit::character; } } else { - if (selectionType == selChar) { + if (selectionUnit == TextUnit::character) { if (sel.Count() > 1) { sel.RangeMain() = SelectionRange(newPos, sel.Range(sel.Count() - 1).anchor); @@ -5240,8 +5266,7 @@ void Editor::SetDocPointer(Document *document) { // Ensure all positions within document sel.Clear(); - targetStart = 0; - targetEnd = 0; + targetRange = SelectionSegment(); braces[0] = Sci::invalidPosition; braces[1] = Sci::invalidPosition; @@ -5285,6 +5310,13 @@ void Editor::SetAnnotationVisible(int visible) { } } +void Editor::SetEOLAnnotationVisible(int visible) { + if (vs.eolAnnotationVisible != visible) { + vs.eolAnnotationVisible = visible; + Redraw(); + } +} + /** * Recursively expand a fold, making lines visible except where they have an unexpanded parent. */ @@ -5427,19 +5459,19 @@ void Editor::EnsureLineVisible(Sci::Line lineDoc, bool enforcePolicy) { } if (enforcePolicy) { const Sci::Line lineDisplay = pcs->DisplayFromDoc(lineDoc); - if (visiblePolicy & VISIBLE_SLOP) { - if ((topLine > lineDisplay) || ((visiblePolicy & VISIBLE_STRICT) && (topLine + visibleSlop > lineDisplay))) { - SetTopLine(Sci::clamp(lineDisplay - visibleSlop, static_cast(0), MaxScrollPos())); + if (visiblePolicy.policy & VISIBLE_SLOP) { + if ((topLine > lineDisplay) || ((visiblePolicy.policy & VISIBLE_STRICT) && (topLine + visiblePolicy.slop > lineDisplay))) { + SetTopLine(Sci::clamp(lineDisplay - visiblePolicy.slop, static_cast(0), MaxScrollPos())); SetVerticalScrollPos(); Redraw(); } else if ((lineDisplay > topLine + LinesOnScreen() - 1) || - ((visiblePolicy & VISIBLE_STRICT) && (lineDisplay > topLine + LinesOnScreen() - 1 - visibleSlop))) { - SetTopLine(Sci::clamp(lineDisplay - LinesOnScreen() + 1 + visibleSlop, static_cast(0), MaxScrollPos())); + ((visiblePolicy.policy & VISIBLE_STRICT) && (lineDisplay > topLine + LinesOnScreen() - 1 - visiblePolicy.slop))) { + SetTopLine(Sci::clamp(lineDisplay - LinesOnScreen() + 1 + visiblePolicy.slop, static_cast(0), MaxScrollPos())); SetVerticalScrollPos(); Redraw(); } } else { - if ((topLine > lineDisplay) || (lineDisplay > topLine + LinesOnScreen() - 1) || (visiblePolicy & VISIBLE_STRICT)) { + if ((topLine > lineDisplay) || (lineDisplay > topLine + LinesOnScreen() - 1) || (visiblePolicy.policy & VISIBLE_STRICT)) { SetTopLine(Sci::clamp(lineDisplay - LinesOnScreen() / 2 + 1, static_cast(0), MaxScrollPos())); SetVerticalScrollPos(); Redraw(); @@ -5576,11 +5608,20 @@ Sci::Position Editor::ReplaceTarget(bool replacePatterns, const char *text, Sci: return 0; } } - if (targetStart != targetEnd) - pdoc->DeleteChars(targetStart, targetEnd - targetStart); - targetEnd = targetStart; - const Sci::Position lengthInserted = pdoc->InsertString(targetStart, text, length); - targetEnd = targetStart + lengthInserted; + + // Remove the text inside the range + if (targetRange.Length() > 0) + pdoc->DeleteChars(targetRange.start.Position(), targetRange.Length()); + targetRange.end = targetRange.start; + + // Realize virtual space of target start + const Sci::Position startAfterSpaceInsertion = RealizeVirtualSpace(targetRange.start.Position(), targetRange.start.VirtualSpace()); + targetRange.start.SetPosition(startAfterSpaceInsertion); + targetRange.end = targetRange.start; + + // Insert the new text + const Sci::Position lengthInserted = pdoc->InsertString(targetRange.start.Position(), text, length); + targetRange.end.SetPosition(targetRange.start.Position() + lengthInserted); return length; } @@ -5721,6 +5762,9 @@ sptr_t Editor::StyleGetMessage(unsigned int iMessage, uptr_t wParam, sptr_t lPar } void Editor::SetSelectionNMessage(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { + if (wParam >= sel.Count()) { + return; + } InvalidateRange(sel.Range(wParam).Start().Position(), sel.Range(wParam).End().Position()); switch (iMessage) { @@ -5792,11 +5836,10 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { if (wParam == 0) return 0; char *ptr = CharPtrFromSPtr(lParam); - size_t iChar = 0; - for (; iChar < wParam - 1; iChar++) - ptr[iChar] = pdoc->CharAt(iChar); - ptr[iChar] = '\0'; - return iChar; + const Sci_Position len = std::min(wParam - 1, pdoc->Length()); + pdoc->GetCharRange(ptr, 0, len); + ptr[len] = '\0'; + return len; } case SCI_SETTEXT: { @@ -5884,15 +5927,14 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { pdoc->LineStart(static_cast(wParam)); const Sci::Position lineEnd = pdoc->LineStart(static_cast(wParam + 1)); + // not NUL terminated + const Sci::Position len = lineEnd - lineStart; if (lParam == 0) { - return lineEnd - lineStart; + return len; } char *ptr = CharPtrFromSPtr(lParam); - Sci::Position iPlace = 0; - for (Sci::Position iChar = lineStart; iChar < lineEnd; iChar++) { - ptr[iPlace++] = pdoc->CharAt(iChar); - } - return iPlace; + pdoc->GetCharRange(ptr, lineStart, len); + return len; } case SCI_GETLINECOUNT: @@ -5926,10 +5968,10 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { return selectedText.LengthWithTerminator(); } else { char *ptr = CharPtrFromSPtr(lParam); - size_t iChar = 0; - if (selectedText.Length()) { - for (; iChar < selectedText.LengthWithTerminator(); iChar++) - ptr[iChar] = selectedText.Data()[iChar]; + size_t iChar = selectedText.Length(); + if (iChar) { + memcpy(ptr, selectedText.Data(), iChar); + ptr[iChar++] = '\0'; } else { ptr[0] = '\0'; } @@ -5975,41 +6017,50 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { break; case SCI_SETTARGETSTART: - targetStart = static_cast(wParam); + targetRange.start.SetPosition(static_cast(wParam)); break; case SCI_GETTARGETSTART: - return targetStart; + return targetRange.start.Position(); + + case SCI_SETTARGETSTARTVIRTUALSPACE: + targetRange.start.SetVirtualSpace(static_cast(wParam)); + break; + + case SCI_GETTARGETSTARTVIRTUALSPACE: + return targetRange.start.VirtualSpace(); case SCI_SETTARGETEND: - targetEnd = static_cast(wParam); + targetRange.end.SetPosition(static_cast(wParam)); break; case SCI_GETTARGETEND: - return targetEnd; + return targetRange.end.Position(); + + case SCI_SETTARGETENDVIRTUALSPACE: + targetRange.end.SetVirtualSpace(static_cast(wParam)); + break; + + case SCI_GETTARGETENDVIRTUALSPACE: + return targetRange.end.VirtualSpace(); case SCI_SETTARGETRANGE: - targetStart = static_cast(wParam); - targetEnd = lParam; + targetRange.start.SetPosition(static_cast(wParam)); + targetRange.end.SetPosition(lParam); break; case SCI_TARGETWHOLEDOCUMENT: - targetStart = 0; - targetEnd = pdoc->Length(); + targetRange.start.SetPosition(0); + targetRange.end.SetPosition(pdoc->Length()); break; case SCI_TARGETFROMSELECTION: - if (sel.MainCaret() < sel.MainAnchor()) { - targetStart = sel.MainCaret(); - targetEnd = sel.MainAnchor(); - } else { - targetStart = sel.MainAnchor(); - targetEnd = sel.MainCaret(); - } + targetRange.start = sel.RangeMain().Start(); + targetRange.end = sel.RangeMain().End(); break; case SCI_GETTARGETTEXT: { - std::string text = RangeText(targetStart, targetEnd); + std::string text = RangeText(targetRange.start.Position(), targetRange.end.Position()); return BytesResult(lParam, reinterpret_cast(text.c_str()), text.length()); } @@ -6144,7 +6195,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { InvalidateStyleRedraw(); break; - // Control specific mesages + // Control specific messages case SCI_ADDTEXT: { if (lParam == 0) @@ -6330,11 +6381,11 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { return view.printParameters.colourMode; case SCI_SETPRINTWRAPMODE: - view.printParameters.wrapState = (wParam == SC_WRAP_WORD) ? eWrapWord : eWrapNone; + view.printParameters.wrapState = (wParam == SC_WRAP_WORD) ? WrapMode::word : WrapMode::none; break; case SCI_GETPRINTWRAPMODE: - return view.printParameters.wrapState; + return static_cast(view.printParameters.wrapState); case SCI_GETSTYLEAT: if (static_cast(wParam) >= pdoc->Length()) @@ -6358,8 +6409,8 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { if (lParam == 0) return 0; Sci_TextRange *tr = static_cast(PtrFromSPtr(lParam)); - int iPlace = 0; - for (long iChar = tr->chrg.cpMin; iChar < tr->chrg.cpMax; iChar++) { + Sci::Position iPlace = 0; + for (Sci::Position iChar = tr->chrg.cpMin; iChar < tr->chrg.cpMax; iChar++) { tr->lpstrText[iPlace++] = pdoc->CharAt(iChar); tr->lpstrText[iPlace++] = pdoc->StyleAt(iChar); } @@ -6378,6 +6429,12 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { pdoc->DeleteMarkFromHandle(static_cast(wParam)); break; + case SCI_MARKERHANDLEFROMLINE: + return pdoc->MarkerHandleFromLine(static_cast(wParam), static_cast(lParam)); + + case SCI_MARKERNUMBERFROMLINE: + return pdoc->MarkerNumberFromLine(static_cast(wParam), static_cast(lParam)); + case SCI_GETVIEWWS: return vs.viewWhitespace; @@ -6436,11 +6493,9 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { } PLATFORM_ASSERT(wParam > 0); char *ptr = CharPtrFromSPtr(lParam); - unsigned int iPlace = 0; - for (Sci::Position iChar = lineStart; iChar < lineEnd && iPlace < wParam - 1; iChar++) { - ptr[iPlace++] = pdoc->CharAt(iChar); - } - ptr[iPlace] = '\0'; + const Sci::Position len = std::min(lineEnd - lineStart, wParam - 1); + pdoc->GetCharRange(ptr, lineStart, len); + ptr[len] = '\0'; return sel.MainCaret() - lineStart; } @@ -6530,6 +6585,13 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { case SCI_GETTABWIDTH: return pdoc->tabInChars; + case SCI_SETTABMINIMUMWIDTH: + SetAppearance(view.tabWidthMinimumPixels, static_cast(wParam)); + break; + + case SCI_GETTABMINIMUMWIDTH: + return view.tabWidthMinimumPixels; + case SCI_CLEARTABSTOPS: if (view.ClearTabstops(static_cast(wParam))) { const DocModification mh(SC_MOD_CHANGETABSTOPS, 0, 0, 0, nullptr, static_cast(wParam)); @@ -6625,7 +6687,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { break; case SCI_GETWRAPMODE: - return vs.wrapState; + return static_cast(vs.wrapState); case SCI_SETWRAPVISUALFLAGS: if (vs.SetWrapVisualFlags(static_cast(wParam))) { @@ -7248,18 +7310,15 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { return SearchText(iMessage, wParam, lParam); case SCI_SETXCARETPOLICY: - caretXPolicy = static_cast(wParam); - caretXSlop = static_cast(lParam); + caretPolicies.x = CaretPolicy(wParam, lParam); break; case SCI_SETYCARETPOLICY: - caretYPolicy = static_cast(wParam); - caretYSlop = static_cast(lParam); + caretPolicies.y = CaretPolicy(wParam, lParam); break; case SCI_SETVISIBLEPOLICY: - visiblePolicy = static_cast(wParam); - visibleSlop = static_cast(lParam); + visiblePolicy = CaretPolicy(wParam, lParam); break; case SCI_LINESONSCREEN: @@ -7313,7 +7372,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { return vs.caretcolour.AsInteger(); case SCI_SETCARETSTYLE: - if (wParam <= (CARETSTYLE_BLOCK | CARETSTYLE_OVERSTRIKE_BLOCK)) + if (wParam <= (CARETSTYLE_BLOCK | CARETSTYLE_OVERSTRIKE_BLOCK | CARETSTYLE_BLOCK_AFTER)) vs.caretStyle = static_cast(wParam); else /* Default to the line caret */ @@ -7325,7 +7384,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { return vs.caretStyle; case SCI_SETCARETWIDTH: - vs.caretWidth = Sci::clamp(static_cast(wParam), 0, 3); + vs.caretWidth = Sci::clamp(static_cast(wParam), 0, 20); InvalidateStyleRedraw(); break; @@ -7347,7 +7406,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { break; case SCI_INDICSETSTYLE: - if (wParam <= INDIC_MAX) { + if (wParam <= INDICATOR_MAX) { vs.indicators[wParam].sacNormal.style = static_cast(lParam); vs.indicators[wParam].sacHover.style = static_cast(lParam); InvalidateStyleRedraw(); @@ -7355,10 +7414,10 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { break; case SCI_INDICGETSTYLE: - return (wParam <= INDIC_MAX) ? vs.indicators[wParam].sacNormal.style : 0; + return (wParam <= INDICATOR_MAX) ? vs.indicators[wParam].sacNormal.style : 0; case SCI_INDICSETFORE: - if (wParam <= INDIC_MAX) { + if (wParam <= INDICATOR_MAX) { vs.indicators[wParam].sacNormal.fore = ColourDesired(static_cast(lParam)); vs.indicators[wParam].sacHover.fore = ColourDesired(static_cast(lParam)); InvalidateStyleRedraw(); @@ -7366,67 +7425,67 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { break; case SCI_INDICGETFORE: - return (wParam <= INDIC_MAX) ? vs.indicators[wParam].sacNormal.fore.AsInteger() : 0; + return (wParam <= INDICATOR_MAX) ? vs.indicators[wParam].sacNormal.fore.AsInteger() : 0; case SCI_INDICSETHOVERSTYLE: - if (wParam <= INDIC_MAX) { + if (wParam <= INDICATOR_MAX) { vs.indicators[wParam].sacHover.style = static_cast(lParam); InvalidateStyleRedraw(); } break; case SCI_INDICGETHOVERSTYLE: - return (wParam <= INDIC_MAX) ? vs.indicators[wParam].sacHover.style : 0; + return (wParam <= INDICATOR_MAX) ? vs.indicators[wParam].sacHover.style : 0; case SCI_INDICSETHOVERFORE: - if (wParam <= INDIC_MAX) { + if (wParam <= INDICATOR_MAX) { vs.indicators[wParam].sacHover.fore = ColourDesired(static_cast(lParam)); InvalidateStyleRedraw(); } break; case SCI_INDICGETHOVERFORE: - return (wParam <= INDIC_MAX) ? vs.indicators[wParam].sacHover.fore.AsInteger() : 0; + return (wParam <= INDICATOR_MAX) ? vs.indicators[wParam].sacHover.fore.AsInteger() : 0; case SCI_INDICSETFLAGS: - if (wParam <= INDIC_MAX) { + if (wParam <= INDICATOR_MAX) { vs.indicators[wParam].SetFlags(static_cast(lParam)); InvalidateStyleRedraw(); } break; case SCI_INDICGETFLAGS: - return (wParam <= INDIC_MAX) ? vs.indicators[wParam].Flags() : 0; + return (wParam <= INDICATOR_MAX) ? vs.indicators[wParam].Flags() : 0; case SCI_INDICSETUNDER: - if (wParam <= INDIC_MAX) { + if (wParam <= INDICATOR_MAX) { vs.indicators[wParam].under = lParam != 0; InvalidateStyleRedraw(); } break; case SCI_INDICGETUNDER: - return (wParam <= INDIC_MAX) ? vs.indicators[wParam].under : 0; + return (wParam <= INDICATOR_MAX) ? vs.indicators[wParam].under : 0; case SCI_INDICSETALPHA: - if (wParam <= INDIC_MAX && lParam >=0 && lParam <= 255) { + if (wParam <= INDICATOR_MAX && lParam >=0 && lParam <= 255) { vs.indicators[wParam].fillAlpha = static_cast(lParam); InvalidateStyleRedraw(); } break; case SCI_INDICGETALPHA: - return (wParam <= INDIC_MAX) ? vs.indicators[wParam].fillAlpha : 0; + return (wParam <= INDICATOR_MAX) ? vs.indicators[wParam].fillAlpha : 0; case SCI_INDICSETOUTLINEALPHA: - if (wParam <= INDIC_MAX && lParam >=0 && lParam <= 255) { + if (wParam <= INDICATOR_MAX && lParam >=0 && lParam <= 255) { vs.indicators[wParam].outlineAlpha = static_cast(lParam); InvalidateStyleRedraw(); } break; case SCI_INDICGETOUTLINEALPHA: - return (wParam <= INDIC_MAX) ? vs.indicators[wParam].outlineAlpha : 0; + return (wParam <= INDICATOR_MAX) ? vs.indicators[wParam].outlineAlpha : 0; case SCI_SETINDICATORCURRENT: pdoc->DecorationSetCurrentIndicator(static_cast(wParam)); @@ -7561,7 +7620,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { break; case SCI_BRACEHIGHLIGHTINDICATOR: - if (lParam >= 0 && lParam <= INDIC_MAX) { + if (lParam >= 0 && lParam <= INDICATOR_MAX) { vs.braceHighlightIndicatorSet = wParam != 0; vs.braceHighlightIndicator = static_cast(lParam); } @@ -7572,7 +7631,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { break; case SCI_BRACEBADLIGHTINDICATOR: - if (lParam >= 0 && lParam <= INDIC_MAX) { + if (lParam >= 0 && lParam <= INDICATOR_MAX) { vs.braceBadLightIndicatorSet = wParam != 0; vs.braceBadLightIndicator = static_cast(lParam); } @@ -7581,7 +7640,10 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { case SCI_BRACEMATCH: // wParam is position of char to find brace for, // lParam is maximum amount of text to restyle to find it - return pdoc->BraceMatch(static_cast(wParam), lParam); + return pdoc->BraceMatch(static_cast(wParam), lParam, 0, false); + + case SCI_BRACEMATCHNEXT: + return pdoc->BraceMatch(static_cast(wParam), 0, lParam, true); case SCI_GETVIEWEOL: return vs.viewEOL; @@ -7629,7 +7691,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { break; case SCI_MULTIEDGEADDLINE: - vs.theMultiEdge.push_back(EdgeProperties(wParam, lParam)); + vs.AddMultiEdge(wParam, lParam); InvalidateStyleRedraw(); break; @@ -7638,6 +7700,15 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { InvalidateStyleRedraw(); break; + case SCI_GETMULTIEDGECOLUMN: { + const size_t which = wParam; + // size_t is unsigned so this also handles negative inputs. + if (which >= vs.theMultiEdge.size()) { + return -1; + } + return vs.theMultiEdge[which].column; + } + case SCI_GETACCESSIBILITY: return SC_ACCESSIBILITY_DISABLED; @@ -8018,6 +8089,43 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { case SCI_ANNOTATIONGETSTYLEOFFSET: return vs.annotationStyleOffset; + case SCI_EOLANNOTATIONSETTEXT: + pdoc->EOLAnnotationSetText(static_cast(wParam), CharPtrFromSPtr(lParam)); + break; + + case SCI_EOLANNOTATIONGETTEXT: { + const StyledText st = pdoc->EOLAnnotationStyledText(static_cast(wParam)); + return BytesResult(lParam, reinterpret_cast(st.text), st.length); + } + + case SCI_EOLANNOTATIONGETSTYLE: { + const StyledText st = pdoc->EOLAnnotationStyledText(static_cast(wParam)); + return st.style; + } + + case SCI_EOLANNOTATIONSETSTYLE: + pdoc->EOLAnnotationSetStyle(static_cast(wParam), static_cast(lParam)); + break; + + case SCI_EOLANNOTATIONCLEARALL: + pdoc->EOLAnnotationClearAll(); + break; + + case SCI_EOLANNOTATIONSETVISIBLE: + SetEOLAnnotationVisible(static_cast(wParam)); + break; + + case SCI_EOLANNOTATIONGETVISIBLE: + return vs.eolAnnotationVisible; + + case SCI_EOLANNOTATIONSETSTYLEOFFSET: + vs.eolAnnotationStyleOffset = static_cast(wParam); + InvalidateStyleRedraw(); + break; + + case SCI_EOLANNOTATIONGETSTYLEOFFSET: + return vs.eolAnnotationStyleOffset; + case SCI_RELEASEALLEXTENDEDSTYLES: vs.ReleaseAllExtendedStyles(); break; @@ -8137,9 +8245,15 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { case SCI_GETSELECTIONNSTART: return sel.Range(wParam).Start().Position(); + case SCI_GETSELECTIONNSTARTVIRTUALSPACE: + return sel.Range(wParam).Start().VirtualSpace(); + case SCI_GETSELECTIONNEND: return sel.Range(wParam).End().Position(); + case SCI_GETSELECTIONNENDVIRTUALSPACE: + return sel.Range(wParam).End().VirtualSpace(); + case SCI_SETRECTANGULARSELECTIONCARET: if (!sel.IsRectangular()) sel.Clear(); @@ -8232,11 +8346,11 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { break; case SCI_MULTIPLESELECTADDNEXT: - MultipleSelectAdd(addOne); + MultipleSelectAdd(AddNumber::one); break; case SCI_MULTIPLESELECTADDEACH: - MultipleSelectAdd(addEach); + MultipleSelectAdd(AddNumber::each); break; case SCI_CHANGELEXERSTATE: diff --git a/scintilla/src/Editor.h b/scintilla/src/Editor.h index e8d1ed48e4..cf77c8d789 100644 --- a/scintilla/src/Editor.h +++ b/scintilla/src/Editor.h @@ -143,6 +143,18 @@ struct WrapPending { } }; +struct CaretPolicy { + int policy; // Combination from CARET_SLOP, CARET_STRICT, CARET_JUMPS, CARET_EVEN + int slop; // Pixels for X, lines for Y + CaretPolicy(uptr_t policy_=0, sptr_t slop_=0) noexcept : + policy(static_cast(policy_)), slop(static_cast(slop_)) {} +}; + +struct CaretPolicies { + CaretPolicy x; + CaretPolicy y; +}; + /** */ class Editor : public EditModel, public DocWatcher { @@ -198,7 +210,7 @@ class Editor : public EditModel, public DocWatcher { int dwellDelay; int ticksToDwell; bool dwelling; - enum { selChar, selWord, selSubLine, selWholeLine } selectionType; + enum class TextUnit { character, word, subLine, wholeLine } selectionUnit; Point ptMouseLast; enum { ddNone, ddInitial, ddDragging } inDragDrop; bool dropWentOutside; @@ -210,8 +222,7 @@ class Editor : public EditModel, public DocWatcher { Sci::Position wordSelectAnchorStartPos; Sci::Position wordSelectAnchorEndPos; Sci::Position wordSelectInitialCaretPos; - Sci::Position targetStart; - Sci::Position targetEnd; + SelectionSegment targetRange; int searchFlags; Sci::Line topLine; Sci::Position posTopLine; @@ -233,14 +244,9 @@ class Editor : public EditModel, public DocWatcher { SelectionText drag; - int caretXPolicy; - int caretXSlop; ///< Ensure this many pixels visible on both sides of caret - - int caretYPolicy; - int caretYSlop; ///< Ensure this many lines visible on both sides of caret + CaretPolicies caretPolicies; - int visiblePolicy; - int visibleSlop; + CaretPolicy visiblePolicy; Sci::Position searchAnchor; @@ -306,7 +312,7 @@ class Editor : public EditModel, public DocWatcher { return ((virtualSpaceOptions & SCVS_USERACCESSIBLE) != 0); } Sci::Position CurrentPosition() const; - bool SelectionEmpty() const; + bool SelectionEmpty() const noexcept; SelectionPosition SelectionStart(); SelectionPosition SelectionEnd(); void SetRectangularRange(); @@ -320,13 +326,14 @@ class Editor : public EditModel, public DocWatcher { void SetSelection(int currentPos_); void SetEmptySelection(SelectionPosition currentPos_); void SetEmptySelection(Sci::Position currentPos_); - enum AddNumber { addOne, addEach }; + enum class AddNumber { one, each }; void MultipleSelectAdd(AddNumber addNumber); - bool RangeContainsProtected(Sci::Position start, Sci::Position end) const; - bool SelectionContainsProtected(); + bool RangeContainsProtected(Sci::Position start, Sci::Position end) const noexcept; + bool SelectionContainsProtected() const; Sci::Position MovePositionOutsideChar(Sci::Position pos, Sci::Position moveDir, bool checkLineEnd=true) const; SelectionPosition MovePositionOutsideChar(SelectionPosition pos, Sci::Position moveDir, bool checkLineEnd=true) const; - void MovedCaret(SelectionPosition newPos, SelectionPosition previousPos, bool ensureVisible); + void MovedCaret(SelectionPosition newPos, SelectionPosition previousPos, + bool ensureVisible, CaretPolicies policies); void MovePositionTo(SelectionPosition newPos, Selection::selTypes selt=Selection::noSel, bool ensureVisible=true); void MovePositionTo(Sci::Position newPos, Selection::selTypes selt=Selection::noSel, bool ensureVisible=true); SelectionPosition MovePositionSoVisible(SelectionPosition pos, int moveDir); @@ -357,7 +364,8 @@ class Editor : public EditModel, public DocWatcher { xysVertical=0x2, xysHorizontal=0x4, xysDefault=xysUseMargin|xysVertical|xysHorizontal}; - XYScrollPosition XYScrollToMakeVisible(const SelectionRange &range, const XYScrollOptions options); + XYScrollPosition XYScrollToMakeVisible(const SelectionRange &range, + const XYScrollOptions options, CaretPolicies policies); void SetXYScroll(XYScrollPosition newXY); void EnsureCaretVisible(bool useMargin=true, bool vert=true, bool horiz=true); void ScrollRange(SelectionRange range); @@ -380,7 +388,7 @@ class Editor : public EditModel, public DocWatcher { void RefreshPixMaps(Surface *surfaceWindow); void Paint(Surface *surfaceWindow, PRectangle rcArea); Sci::Position FormatRange(bool draw, const Sci_RangeToFormat *pfr); - int TextWidth(int style, const char *text); + long TextWidth(uptr_t style, const char *text); virtual void SetVerticalScrollPos() = 0; virtual void SetHorizontalScrollPos() = 0; @@ -393,7 +401,7 @@ class Editor : public EditModel, public DocWatcher { Sci::Position RealizeVirtualSpace(Sci::Position position, Sci::Position virtualSpace); SelectionPosition RealizeVirtualSpace(const SelectionPosition &position); void AddChar(char ch); - virtual void AddCharUTF(const char *s, unsigned int len, bool treatAsDBCS=false); + virtual void InsertCharacter(const char *s, unsigned int len, CharacterSource charSource); void ClearBeforeTentativeStart(); void InsertPaste(const char *text, Sci::Position len); enum PasteShape { pasteStream=0, pasteRectangular = 1, pasteLine = 2 }; @@ -404,7 +412,7 @@ class Editor : public EditModel, public DocWatcher { virtual void Cut(); void PasteRectangular(SelectionPosition pos, const char *ptr, Sci::Position len); virtual void Copy() = 0; - virtual void CopyAllowLine(); + void CopyAllowLine(); virtual bool CanPaste(); virtual void Paste() = 0; void Clear(); @@ -421,7 +429,7 @@ class Editor : public EditModel, public DocWatcher { virtual int GetCtrlID() { return ctrlID; } virtual void NotifyParent(SCNotification scn) = 0; virtual void NotifyStyleToNeeded(Sci::Position endStyleNeeded); - void NotifyChar(int ch); + void NotifyChar(int ch, CharacterSource charSource); void NotifySavePoint(bool isSavePoint); void NotifyModifyAttempt(); virtual void NotifyDoubleClick(Point pt, int modifiers); @@ -538,6 +546,7 @@ class Editor : public EditModel, public DocWatcher { virtual void SetDocPointer(Document *document); void SetAnnotationVisible(int visible); + void SetEOLAnnotationVisible(int visible); Sci::Line ExpandLine(Sci::Line line); void SetFoldExpanded(Sci::Line lineDoc, bool expanded); @@ -598,6 +607,19 @@ class Editor : public EditModel, public DocWatcher { static sptr_t StringResult(sptr_t lParam, const char *val) noexcept; static sptr_t BytesResult(sptr_t lParam, const unsigned char *val, size_t len) noexcept; + // Set a variable controlling appearance to a value and invalidates the display + // if a change was made. Avoids extra text and the possibility of mistyping. + template + bool SetAppearance(T &variable, T value) { + // Using ! and == as more types have == defined than !=. + const bool changed = !(variable == value); + if (changed) { + variable = value; + InvalidateStyleRedraw(); + } + return changed; + } + public: ~Editor() override; @@ -619,7 +641,7 @@ class AutoSurface { private: std::unique_ptr surf; public: - AutoSurface(Editor *ed, int technology = -1) { + AutoSurface(const Editor *ed, int technology = -1) { if (ed->wMain.GetID()) { surf.reset(Surface::Allocate(technology != -1 ? technology : ed->technology)); surf->Init(ed->wMain.GetID()); diff --git a/scintilla/src/ElapsedPeriod.h b/scintilla/src/ElapsedPeriod.h index 6f8cdabdfa..e083c0dda0 100644 --- a/scintilla/src/ElapsedPeriod.h +++ b/scintilla/src/ElapsedPeriod.h @@ -18,7 +18,7 @@ class ElapsedPeriod { ElapsedPeriod() noexcept : tp(std::chrono::high_resolution_clock::now()) { } /// Return duration as floating point seconds - double Duration(bool reset=false) { + double Duration(bool reset=false) noexcept { const std::chrono::high_resolution_clock::time_point tpNow = std::chrono::high_resolution_clock::now(); const std::chrono::duration stylingDuration = diff --git a/scintilla/src/ExternalLexer.cxx b/scintilla/src/ExternalLexer.cxx index 4f2ab987b0..748789ed09 100644 --- a/scintilla/src/ExternalLexer.cxx +++ b/scintilla/src/ExternalLexer.cxx @@ -26,6 +26,78 @@ using namespace Scintilla; +#if PLAT_WIN +#define EXT_LEXER_DECL __stdcall +#else +#define EXT_LEXER_DECL +#endif + +namespace { + +int nextLanguage = SCLEX_AUTOMATIC + 1; + +typedef int (EXT_LEXER_DECL *GetLexerCountFn)(); +typedef void (EXT_LEXER_DECL *GetLexerNameFn)(unsigned int Index, char *name, int buflength); +typedef LexerFactoryFunction(EXT_LEXER_DECL *GetLexerFactoryFunction)(unsigned int Index); + +/// Generic function to convert from a void* to a function pointer. +/// This avoids undefined and conditionally defined behaviour. +template +T FunctionPointer(void *function) noexcept { + static_assert(sizeof(T) == sizeof(function), "size mismatch"); + T fp; + memcpy(&fp, &function, sizeof(T)); + return fp; +} + +/// Sub-class of LexerModule to use an external lexer. +class ExternalLexerModule : public LexerModule { +protected: + GetLexerFactoryFunction fneFactory; + std::string name; +public: + ExternalLexerModule(int language_, LexerFunction fnLexer_, + const char *languageName_=nullptr, LexerFunction fnFolder_=nullptr) : + LexerModule(language_, fnLexer_, nullptr, fnFolder_), + fneFactory(nullptr), name(languageName_){ + languageName = name.c_str(); + } + void SetExternal(GetLexerFactoryFunction fFactory, int index) noexcept; +}; + +/// LexerLibrary exists for every External Lexer DLL, contains ExternalLexerModules. +class LexerLibrary { + std::unique_ptr lib; + std::vector> modules; +public: + explicit LexerLibrary(const char *moduleName_); + ~LexerLibrary(); + + std::string moduleName; +}; + +/// LexerManager manages external lexers, contains LexerLibrarys. +class LexerManager { +public: + ~LexerManager(); + + static LexerManager *GetInstance(); + static void DeleteInstance() noexcept; + + void Load(const char *path); + void Clear() noexcept; + +private: + LexerManager(); + static std::unique_ptr theInstance; + std::vector> libraries; +}; + +class LMMinder { +public: + ~LMMinder(); +}; + std::unique_ptr LexerManager::theInstance; //------------------------------------------ @@ -34,7 +106,7 @@ std::unique_ptr LexerManager::theInstance; // //------------------------------------------ -void ExternalLexerModule::SetExternal(GetLexerFactoryFunction fFactory, int index) { +void ExternalLexerModule::SetExternal(GetLexerFactoryFunction fFactory, int index) noexcept { fneFactory = fFactory; fnFactory = fFactory(index); } @@ -50,13 +122,16 @@ LexerLibrary::LexerLibrary(const char *moduleName_) { lib.reset(DynamicLibrary::Load(moduleName_)); if (lib->IsValid()) { moduleName = moduleName_; - //Cannot use reinterpret_cast because: ANSI C++ forbids casting between pointers to functions and objects - GetLexerCountFn GetLexerCount = (GetLexerCountFn)(sptr_t)lib->FindFunction("GetLexerCount"); + GetLexerCountFn GetLexerCount = FunctionPointer(lib->FindFunction("GetLexerCount")); if (GetLexerCount) { // Find functions in the DLL - GetLexerNameFn GetLexerName = (GetLexerNameFn)(sptr_t)lib->FindFunction("GetLexerName"); - GetLexerFactoryFunction fnFactory = (GetLexerFactoryFunction)(sptr_t)lib->FindFunction("GetLexerFactory"); + GetLexerNameFn GetLexerName = FunctionPointer(lib->FindFunction("GetLexerName")); + GetLexerFactoryFunction fnFactory = FunctionPointer(lib->FindFunction("GetLexerFactory")); + + if (!GetLexerName || !fnFactory) { + return; + } const int nl = GetLexerCount(); @@ -64,7 +139,9 @@ LexerLibrary::LexerLibrary(const char *moduleName_) { // Assign a buffer for the lexer name. char lexname[100] = ""; GetLexerName(i, lexname, sizeof(lexname)); - ExternalLexerModule *lex = new ExternalLexerModule(SCLEX_AUTOMATIC, nullptr, lexname, nullptr); + ExternalLexerModule *lex = new ExternalLexerModule(nextLanguage, nullptr, lexname, nullptr); + nextLanguage++; + // This is storing a second reference to lex in the Catalogue as well as in modules. // TODO: Should use std::shared_ptr or similar to ensure allocation safety. Catalogue::AddLexerModule(lex); @@ -74,7 +151,7 @@ LexerLibrary::LexerLibrary(const char *moduleName_) { // The external lexer needs to know how to call into its DLL to // do its lexing and folding, we tell it here. - lex->SetExternal(fnFactory, i); + lex->SetExternal(fnFactory, i); } } } @@ -97,7 +174,7 @@ LexerManager *LexerManager::GetInstance() { } /// Delete any LexerManager instance... -void LexerManager::DeleteInstance() { +void LexerManager::DeleteInstance() noexcept { theInstance.reset(); } @@ -114,11 +191,10 @@ void LexerManager::Load(const char *path) { if (ll->moduleName == path) return; } - LexerLibrary *lib = new LexerLibrary(path); - libraries.push_back(std::unique_ptr(lib)); + libraries.push_back(Sci::make_unique(path)); } -void LexerManager::Clear() { +void LexerManager::Clear() noexcept { libraries.clear(); } @@ -133,3 +209,13 @@ LMMinder::~LMMinder() { } LMMinder minder; + +} + +namespace Scintilla { + +void ExternalLexerLoad(const char *path) { + LexerManager::GetInstance()->Load(path); +} + +} diff --git a/scintilla/src/ExternalLexer.h b/scintilla/src/ExternalLexer.h index f0af9834af..d0a615e31a 100644 --- a/scintilla/src/ExternalLexer.h +++ b/scintilla/src/ExternalLexer.h @@ -8,65 +8,9 @@ #ifndef EXTERNALLEXER_H #define EXTERNALLEXER_H -#if PLAT_WIN -#define EXT_LEXER_DECL __stdcall -#else -#define EXT_LEXER_DECL -#endif - namespace Scintilla { -typedef int (EXT_LEXER_DECL *GetLexerCountFn)(); -typedef void (EXT_LEXER_DECL *GetLexerNameFn)(unsigned int Index, char *name, int buflength); -typedef LexerFactoryFunction(EXT_LEXER_DECL *GetLexerFactoryFunction)(unsigned int Index); - -/// Sub-class of LexerModule to use an external lexer. -class ExternalLexerModule : public LexerModule { -protected: - GetLexerFactoryFunction fneFactory; - std::string name; -public: - ExternalLexerModule(int language_, LexerFunction fnLexer_, - const char *languageName_=nullptr, LexerFunction fnFolder_=nullptr) : - LexerModule(language_, fnLexer_, nullptr, fnFolder_), - fneFactory(nullptr), name(languageName_){ - languageName = name.c_str(); - } - virtual void SetExternal(GetLexerFactoryFunction fFactory, int index); -}; - -/// LexerLibrary exists for every External Lexer DLL, contains ExternalLexerModules. -class LexerLibrary { - std::unique_ptr lib; - std::vector> modules; -public: - explicit LexerLibrary(const char *moduleName_); - ~LexerLibrary(); - - std::string moduleName; -}; - -/// LexerManager manages external lexers, contains LexerLibrarys. -class LexerManager { -public: - ~LexerManager(); - - static LexerManager *GetInstance(); - static void DeleteInstance(); - - void Load(const char *path); - void Clear(); - -private: - LexerManager(); - static std::unique_ptr theInstance; - std::vector> libraries; -}; - -class LMMinder { -public: - ~LMMinder(); -}; +void ExternalLexerLoad(const char *path); } diff --git a/scintilla/src/Indicator.cxx b/scintilla/src/Indicator.cxx index 24cd408205..f721027725 100644 --- a/scintilla/src/Indicator.cxx +++ b/scintilla/src/Indicator.cxx @@ -16,208 +16,258 @@ #include "Platform.h" #include "Scintilla.h" -#include "StringCopy.h" #include "IntegerRectangle.h" #include "Indicator.h" #include "XPM.h" using namespace Scintilla; -static PRectangle PixelGridAlign(const PRectangle &rc) { +static PRectangle PixelGridAlign(const PRectangle &rc) noexcept { // Move left and right side to nearest pixel to avoid blurry visuals - return PRectangle(round(rc.left), std::floor(rc.top), - round(rc.right), std::floor(rc.bottom)); + return PRectangle(Sci::round(rc.left), std::floor(rc.top), + Sci::round(rc.right), std::floor(rc.bottom)); } -void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine, const PRectangle &rcCharacter, DrawState drawState, int value) const { +void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine, const PRectangle &rcCharacter, State state, int value) const { StyleAndColour sacDraw = sacNormal; if (Flags() & SC_INDICFLAG_VALUEFORE) { sacDraw.fore = ColourDesired(value & SC_INDICVALUEMASK); } - if (drawState == drawHover) { + if (state == State::hover) { sacDraw = sacHover; } const IntegerRectangle irc(rc); surface->PenColour(sacDraw.fore); const int ymid = (irc.bottom + irc.top) / 2; - if (sacDraw.style == INDIC_SQUIGGLE) { - const IntegerRectangle ircSquiggle(PixelGridAlign(rc)); - int x = ircSquiggle.left; - const int xLast = ircSquiggle.right; - int y = 0; - surface->MoveTo(x, irc.top + y); - while (x < xLast) { - if ((x + 2) > xLast) { - y = 1; - x = xLast; - } else { - x += 2; - y = 2 - y; + + switch (sacDraw.style) { + case INDIC_SQUIGGLE: { + const IntegerRectangle ircSquiggle(PixelGridAlign(rc)); + int x = ircSquiggle.left; + const int xLast = ircSquiggle.right; + int y = 0; + surface->MoveTo(x, irc.top + y); + while (x < xLast) { + if ((x + 2) > xLast) { + y = 1; + x = xLast; + } else { + x += 2; + y = 2 - y; + } + surface->LineTo(x, irc.top + y); } - surface->LineTo(x, irc.top + y); } - } else if (sacDraw.style == INDIC_SQUIGGLEPIXMAP) { - const PRectangle rcSquiggle = PixelGridAlign(rc); - - const int width = std::min(4000, static_cast(rcSquiggle.Width())); - RGBAImage image(width, 3, 1.0, nullptr); - enum { alphaFull = 0xff, alphaSide = 0x2f, alphaSide2=0x5f }; - for (int x = 0; x < width; x++) { - if (x%2) { - // Two halfway columns have a full pixel in middle flanked by light pixels - image.SetPixel(x, 0, sacDraw.fore, alphaSide); - image.SetPixel(x, 1, sacDraw.fore, alphaFull); - image.SetPixel(x, 2, sacDraw.fore, alphaSide); - } else { - // Extreme columns have a full pixel at bottom or top and a mid-tone pixel in centre - image.SetPixel(x, (x % 4) ? 0 : 2, sacDraw.fore, alphaFull); - image.SetPixel(x, 1, sacDraw.fore, alphaSide2); + break; + + case INDIC_SQUIGGLEPIXMAP: { + const PRectangle rcSquiggle = PixelGridAlign(rc); + + const int width = std::min(4000, static_cast(rcSquiggle.Width())); + RGBAImage image(width, 3, 1.0, nullptr); + enum { alphaFull = 0xff, alphaSide = 0x2f, alphaSide2=0x5f }; + for (int x = 0; x < width; x++) { + if (x%2) { + // Two halfway columns have a full pixel in middle flanked by light pixels + image.SetPixel(x, 0, sacDraw.fore, alphaSide); + image.SetPixel(x, 1, sacDraw.fore, alphaFull); + image.SetPixel(x, 2, sacDraw.fore, alphaSide); + } else { + // Extreme columns have a full pixel at bottom or top and a mid-tone pixel in centre + image.SetPixel(x, (x % 4) ? 0 : 2, sacDraw.fore, alphaFull); + image.SetPixel(x, 1, sacDraw.fore, alphaSide2); + } } + surface->DrawRGBAImage(rcSquiggle, image.GetWidth(), image.GetHeight(), image.Pixels()); } - surface->DrawRGBAImage(rcSquiggle, image.GetWidth(), image.GetHeight(), image.Pixels()); - } else if (sacDraw.style == INDIC_SQUIGGLELOW) { - surface->MoveTo(irc.left, irc.top); - int x = irc.left + 3; - int y = 0; - while (x < rc.right) { - surface->LineTo(x - 1, irc.top + y); - y = 1 - y; - surface->LineTo(x, irc.top + y); - x += 3; - } - surface->LineTo(irc.right, irc.top + y); // Finish the line - } else if (sacDraw.style == INDIC_TT) { - surface->MoveTo(irc.left, ymid); - int x = irc.left + 5; - while (x < rc.right) { - surface->LineTo(x, ymid); - surface->MoveTo(x-3, ymid); - surface->LineTo(x-3, ymid+2); - x++; - surface->MoveTo(x, ymid); - x += 5; + break; + + case INDIC_SQUIGGLELOW: { + surface->MoveTo(irc.left, irc.top); + int x = irc.left + 3; + int y = 0; + while (x < rc.right) { + surface->LineTo(x - 1, irc.top + y); + y = 1 - y; + surface->LineTo(x, irc.top + y); + x += 3; + } + surface->LineTo(irc.right, irc.top + y); // Finish the line } - surface->LineTo(irc.right, ymid); // Finish the line - if (x - 3 <= rc.right) { - surface->MoveTo(x-3, ymid); - surface->LineTo(x-3, ymid+2); + break; + + case INDIC_TT: { + surface->MoveTo(irc.left, ymid); + int x = irc.left + 5; + while (x < rc.right) { + surface->LineTo(x, ymid); + surface->MoveTo(x-3, ymid); + surface->LineTo(x-3, ymid+2); + x++; + surface->MoveTo(x, ymid); + x += 5; + } + surface->LineTo(irc.right, ymid); // Finish the line + if (x - 3 <= rc.right) { + surface->MoveTo(x-3, ymid); + surface->LineTo(x-3, ymid+2); + } } - } else if (sacDraw.style == INDIC_DIAGONAL) { - int x = irc.left; - while (x < rc.right) { - surface->MoveTo(x, irc.top + 2); - int endX = x+3; - int endY = irc.top - 1; - if (endX > rc.right) { - endY += endX - irc.right; - endX = irc.right; + break; + + case INDIC_DIAGONAL: { + int x = irc.left; + while (x < rc.right) { + surface->MoveTo(x, irc.top + 2); + int endX = x+3; + int endY = irc.top - 1; + if (endX > rc.right) { + endY += endX - irc.right; + endX = irc.right; + } + surface->LineTo(endX, endY); + x += 4; } - surface->LineTo(endX, endY); - x += 4; } - } else if (sacDraw.style == INDIC_STRIKE) { - surface->MoveTo(irc.left, irc.top - 4); - surface->LineTo(irc.right, irc.top - 4); - } else if ((sacDraw.style == INDIC_HIDDEN) || (sacDraw.style == INDIC_TEXTFORE)) { + break; + + case INDIC_STRIKE: { + surface->MoveTo(irc.left, irc.top - 4); + surface->LineTo(irc.right, irc.top - 4); + } + break; + + case INDIC_HIDDEN: + case INDIC_TEXTFORE: // Draw nothing - } else if (sacDraw.style == INDIC_BOX) { - surface->MoveTo(irc.left, ymid + 1); - surface->LineTo(irc.right, ymid + 1); - const int lineTop = static_cast(rcLine.top) + 1; - surface->LineTo(irc.right, lineTop); - surface->LineTo(irc.left, lineTop); - surface->LineTo(irc.left, ymid + 1); - } else if (sacDraw.style == INDIC_ROUNDBOX || - sacDraw.style == INDIC_STRAIGHTBOX || - sacDraw.style == INDIC_FULLBOX) { - PRectangle rcBox = rcLine; - if (sacDraw.style != INDIC_FULLBOX) + break; + + case INDIC_BOX: { + surface->MoveTo(irc.left, ymid + 1); + surface->LineTo(irc.right, ymid + 1); + const int lineTop = static_cast(rcLine.top) + 1; + surface->LineTo(irc.right, lineTop); + surface->LineTo(irc.left, lineTop); + surface->LineTo(irc.left, ymid + 1); + } + break; + + case INDIC_ROUNDBOX: + case INDIC_STRAIGHTBOX: + case INDIC_FULLBOX: { + PRectangle rcBox = rcLine; + if (sacDraw.style != INDIC_FULLBOX) + rcBox.top = rcLine.top + 1; + rcBox.left = rc.left; + rcBox.right = rc.right; + surface->AlphaRectangle(rcBox, (sacDraw.style == INDIC_ROUNDBOX) ? 1 : 0, + sacDraw.fore, fillAlpha, sacDraw.fore, outlineAlpha, 0); + } + break; + + case INDIC_GRADIENT: + case INDIC_GRADIENTCENTRE: { + PRectangle rcBox = rc; + rcBox.top = rcLine.top + 1; + rcBox.bottom = rcLine.bottom; + const Surface::GradientOptions options = Surface::GradientOptions::topToBottom; + const ColourAlpha start(sacDraw.fore, fillAlpha); + const ColourAlpha end(sacDraw.fore, 0); + std::vector stops; + switch (sacDraw.style) { + case INDIC_GRADIENT: + stops.push_back(ColourStop(0.0, start)); + stops.push_back(ColourStop(1.0, end)); + break; + case INDIC_GRADIENTCENTRE: + stops.push_back(ColourStop(0.0, end)); + stops.push_back(ColourStop(0.5, start)); + stops.push_back(ColourStop(1.0, end)); + break; + } + surface->GradientRectangle(rcBox, stops, options); + } + break; + + case INDIC_DOTBOX: { + PRectangle rcBox = PixelGridAlign(rc); rcBox.top = rcLine.top + 1; - rcBox.left = rc.left; - rcBox.right = rc.right; - surface->AlphaRectangle(rcBox, (sacDraw.style == INDIC_ROUNDBOX) ? 1 : 0, - sacDraw.fore, fillAlpha, sacDraw.fore, outlineAlpha, 0); - } else if (sacDraw.style == INDIC_GRADIENT || - sacDraw.style == INDIC_GRADIENTCENTRE) { - PRectangle rcBox = rc; - rcBox.top = rcLine.top + 1; - rcBox.bottom = rcLine.bottom; - const Surface::GradientOptions options = Surface::GradientOptions::topToBottom; - const ColourAlpha start(sacNormal.fore, fillAlpha); - const ColourAlpha end(sacNormal.fore, 0); - std::vector stops; - switch (sacDraw.style) { - case INDIC_GRADIENT: - stops.push_back(ColourStop(0.0, start)); - stops.push_back(ColourStop(1.0, end)); - break; - case INDIC_GRADIENTCENTRE: - stops.push_back(ColourStop(0.0, end)); - stops.push_back(ColourStop(0.5, start)); - stops.push_back(ColourStop(1.0, end)); - break; + rcBox.bottom = rcLine.bottom; + const IntegerRectangle ircBox(rcBox); + // Cap width at 4000 to avoid large allocations when mistakes made + const int width = std::min(ircBox.Width(), 4000); + RGBAImage image(width, ircBox.Height(), 1.0, nullptr); + // Draw horizontal lines top and bottom + for (int x=0; xDrawRGBAImage(rcBox, image.GetWidth(), image.GetHeight(), image.Pixels()); } - surface->GradientRectangle(rcBox, stops, options); - } else if (sacDraw.style == INDIC_DOTBOX) { - PRectangle rcBox = PixelGridAlign(rc); - rcBox.top = rcLine.top + 1; - rcBox.bottom = rcLine.bottom; - IntegerRectangle ircBox(rcBox); - // Cap width at 4000 to avoid large allocations when mistakes made - const int width = std::min(ircBox.Width(), 4000); - RGBAImage image(width, ircBox.Height(), 1.0, nullptr); - // Draw horizontal lines top and bottom - for (int x=0; xMoveTo(x, ymid); + surface->LineTo(std::min(x + 4, irc.right), ymid); + x += 7; } } - // Draw vertical lines left and right - for (int y = 1; yFillRectangle(rcDot, sacDraw.fore); + x += 2; } } - surface->DrawRGBAImage(rcBox, image.GetWidth(), image.GetHeight(), image.Pixels()); - } else if (sacDraw.style == INDIC_DASH) { - int x = irc.left; - while (x < rc.right) { - surface->MoveTo(x, ymid); - surface->LineTo(std::min(x + 4, irc.right), ymid); - x += 7; + break; + + case INDIC_COMPOSITIONTHICK: { + const PRectangle rcComposition(rc.left+1, rcLine.bottom-2, rc.right-1, rcLine.bottom); + surface->FillRectangle(rcComposition, sacDraw.fore); } - } else if (sacDraw.style == INDIC_DOTS) { - int x = irc.left; - while (x < irc.right) { - const PRectangle rcDot = PRectangle::FromInts(x, ymid, x + 1, ymid + 1); - surface->FillRectangle(rcDot, sacDraw.fore); - x += 2; + break; + + case INDIC_COMPOSITIONTHIN: { + const PRectangle rcComposition(rc.left+1, rcLine.bottom-2, rc.right-1, rcLine.bottom-1); + surface->FillRectangle(rcComposition, sacDraw.fore); } - } else if (sacDraw.style == INDIC_COMPOSITIONTHICK) { - const PRectangle rcComposition(rc.left+1, rcLine.bottom-2, rc.right-1, rcLine.bottom); - surface->FillRectangle(rcComposition, sacDraw.fore); - } else if (sacDraw.style == INDIC_COMPOSITIONTHIN) { - const PRectangle rcComposition(rc.left+1, rcLine.bottom-2, rc.right-1, rcLine.bottom-1); - surface->FillRectangle(rcComposition, sacDraw.fore); - } else if (sacDraw.style == INDIC_POINT || sacDraw.style == INDIC_POINTCHARACTER) { + break; + + case INDIC_POINT: + case INDIC_POINTCHARACTER: if (rcCharacter.Width() >= 0.1) { const XYPOSITION pixelHeight = std::floor(rc.Height() - 1.0f); // 1 pixel onto next line if multiphase const XYPOSITION x = (sacDraw.style == INDIC_POINT) ? (rcCharacter.left) : ((rcCharacter.right + rcCharacter.left) / 2); - const XYPOSITION ix = round(x); + const XYPOSITION ix = Sci::round(x); const XYPOSITION iy = std::floor(rc.top + 1.0f); Point pts[] = { Point(ix - pixelHeight, iy + pixelHeight), // Left Point(ix + pixelHeight, iy + pixelHeight), // Right Point(ix, iy) // Top }; - surface->Polygon(pts, ELEMENTS(pts), sacDraw.fore, sacDraw.fore); + surface->Polygon(pts, Sci::size(pts), sacDraw.fore, sacDraw.fore); } - } else { // Either INDIC_PLAIN or unknown + break; + + default: + // Either INDIC_PLAIN or unknown surface->MoveTo(irc.left, ymid); surface->LineTo(irc.right, ymid); } } -void Indicator::SetFlags(int attributes_) { +void Indicator::SetFlags(int attributes_) noexcept { attributes = attributes_; } diff --git a/scintilla/src/Indicator.h b/scintilla/src/Indicator.h index 9e5fda2213..669d9a2d87 100644 --- a/scintilla/src/Indicator.h +++ b/scintilla/src/Indicator.h @@ -17,7 +17,7 @@ struct StyleAndColour { } StyleAndColour(int style_, ColourDesired fore_ = ColourDesired(0, 0, 0)) noexcept : style(style_), fore(fore_) { } - bool operator==(const StyleAndColour &other) const { + bool operator==(const StyleAndColour &other) const noexcept { return (style == other.style) && (fore == other.fore); } }; @@ -26,7 +26,7 @@ struct StyleAndColour { */ class Indicator { public: - enum DrawState { drawNormal, drawHover }; + enum class State { normal, hover }; StyleAndColour sacNormal; StyleAndColour sacHover; bool under; @@ -38,17 +38,17 @@ class Indicator { Indicator(int style_, ColourDesired fore_=ColourDesired(0,0,0), bool under_=false, int fillAlpha_=30, int outlineAlpha_=50) noexcept : sacNormal(style_, fore_), sacHover(style_, fore_), under(under_), fillAlpha(fillAlpha_), outlineAlpha(outlineAlpha_), attributes(0) { } - void Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine, const PRectangle &rcCharacter, DrawState drawState, int value) const; - bool IsDynamic() const { + void Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine, const PRectangle &rcCharacter, State drawState, int value) const; + bool IsDynamic() const noexcept { return !(sacNormal == sacHover); } - bool OverridesTextFore() const { + bool OverridesTextFore() const noexcept { return sacNormal.style == INDIC_TEXTFORE || sacHover.style == INDIC_TEXTFORE; } - int Flags() const { + int Flags() const noexcept { return attributes; } - void SetFlags(int attributes_); + void SetFlags(int attributes_) noexcept; }; } diff --git a/scintilla/src/KeyMap.cxx b/scintilla/src/KeyMap.cxx index 42982b4f75..8dc4feff92 100644 --- a/scintilla/src/KeyMap.cxx +++ b/scintilla/src/KeyMap.cxx @@ -32,7 +32,7 @@ KeyMap::~KeyMap() { Clear(); } -void KeyMap::Clear() { +void KeyMap::Clear() noexcept { kmap.clear(); } @@ -45,7 +45,7 @@ unsigned int KeyMap::Find(int key, int modifiers) const { return (it == kmap.end()) ? 0 : it->second; } -const std::map &KeyMap::GetKeyMap() const { +const std::map &KeyMap::GetKeyMap() const noexcept { return kmap; } diff --git a/scintilla/src/KeyMap.h b/scintilla/src/KeyMap.h index 6f30abf003..245b6daaa9 100644 --- a/scintilla/src/KeyMap.h +++ b/scintilla/src/KeyMap.h @@ -27,7 +27,7 @@ class KeyModifiers { int modifiers; KeyModifiers(int key_, int modifiers_) noexcept : key(key_), modifiers(modifiers_) { } - bool operator<(const KeyModifiers &other) const { + bool operator<(const KeyModifiers &other) const noexcept { if (key == other.key) return modifiers < other.modifiers; else @@ -53,10 +53,10 @@ class KeyMap { public: KeyMap(); ~KeyMap(); - void Clear(); + void Clear() noexcept; void AssignCmdKey(int key, int modifiers, unsigned int msg); unsigned int Find(int key, int modifiers) const; // 0 returned on failure - const std::map &GetKeyMap() const; + const std::map &GetKeyMap() const noexcept; }; } diff --git a/scintilla/src/LineMarker.cxx b/scintilla/src/LineMarker.cxx index d2c906d083..c7ab08966a 100644 --- a/scintilla/src/LineMarker.cxx +++ b/scintilla/src/LineMarker.cxx @@ -18,7 +18,6 @@ #include "Scintilla.h" -#include "StringCopy.h" #include "IntegerRectangle.h" #include "XPM.h" #include "LineMarker.h" @@ -33,11 +32,11 @@ LineMarker::LineMarker(const LineMarker &other) { backSelected = other.backSelected; alpha = other.alpha; if (other.pxpm) - pxpm.reset(new XPM(*other.pxpm)); + pxpm = Sci::make_unique(*other.pxpm); else pxpm = nullptr; if (other.image) - image.reset(new RGBAImage(*other.image)); + image = Sci::make_unique(*other.image); else image = nullptr; customDraw = other.customDraw; @@ -52,11 +51,11 @@ LineMarker &LineMarker::operator=(const LineMarker &other) { backSelected = other.backSelected; alpha = other.alpha; if (other.pxpm) - pxpm.reset(new XPM(*other.pxpm)); + pxpm = Sci::make_unique(*other.pxpm); else pxpm = nullptr; if (other.image) - image.reset(new RGBAImage(*other.image)); + image = Sci::make_unique(*other.image); else image = nullptr; customDraw = other.customDraw; @@ -65,35 +64,35 @@ LineMarker &LineMarker::operator=(const LineMarker &other) { } void LineMarker::SetXPM(const char *textForm) { - pxpm.reset(new XPM(textForm)); + pxpm = Sci::make_unique(textForm); markType = SC_MARK_PIXMAP; } void LineMarker::SetXPM(const char *const *linesForm) { - pxpm.reset(new XPM(linesForm)); + pxpm = Sci::make_unique(linesForm); markType = SC_MARK_PIXMAP; } void LineMarker::SetRGBAImage(Point sizeRGBAImage, float scale, const unsigned char *pixelsRGBAImage) { - image.reset(new RGBAImage(static_cast(sizeRGBAImage.x), static_cast(sizeRGBAImage.y), scale, pixelsRGBAImage)); + image = Sci::make_unique(static_cast(sizeRGBAImage.x), static_cast(sizeRGBAImage.y), scale, pixelsRGBAImage); markType = SC_MARK_RGBAIMAGE; } static void DrawBox(Surface *surface, int centreX, int centreY, int armSize, ColourDesired fore, ColourDesired back) { const PRectangle rc = PRectangle::FromInts( - centreX - armSize, - centreY - armSize, - centreX + armSize + 1, - centreY + armSize + 1); + centreX - armSize, + centreY - armSize, + centreX + armSize + 1, + centreY + armSize + 1); surface->RectangleDraw(rc, back, fore); } static void DrawCircle(Surface *surface, int centreX, int centreY, int armSize, ColourDesired fore, ColourDesired back) { const PRectangle rcCircle = PRectangle::FromInts( - centreX - armSize, - centreY - armSize, - centreX + armSize + 1, - centreY + armSize + 1); + centreX - armSize, + centreY - armSize, + centreX + armSize + 1, + centreY + armSize + 1); surface->Ellipse(rcCircle, back, fore); } @@ -109,9 +108,9 @@ static void DrawMinus(Surface *surface, int centreX, int centreY, int armSize, C surface->FillRectangle(rcH, fore); } -void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter, typeOfFold tFold, int marginStyle) const { +void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter, FoldPart part, int marginStyle) const { if (customDraw) { - customDraw(surface, rcWhole, fontForCharacter, tFold, marginStyle, this); + customDraw(surface, rcWhole, fontForCharacter, static_cast(part), marginStyle, this); return; } @@ -119,22 +118,22 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharac ColourDesired colourBody = back; ColourDesired colourTail = back; - switch (tFold) { - case LineMarker::head : - case LineMarker::headWithTail : + switch (part) { + case FoldPart::head: + case FoldPart::headWithTail: colourHead = backSelected; colourTail = backSelected; break; - case LineMarker::body : + case FoldPart::body: colourHead = backSelected; colourBody = backSelected; break; - case LineMarker::tail : + case FoldPart::tail: colourBody = backSelected; colourTail = backSelected; break; - default : - // LineMarker::undefined + default: + // FoldPart::undefined break; } @@ -152,295 +151,370 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharac surface->DrawRGBAImage(rcImage, image->GetWidth(), image->GetHeight(), image->Pixels()); return; } + const IntegerRectangle ircWhole(rcWhole); // Restrict most shapes a bit const PRectangle rc(rcWhole.left, rcWhole.top + 1, rcWhole.right, rcWhole.bottom - 1); // Ensure does not go beyond edge - const int minDim = std::min(ircWhole.Width(), ircWhole.Height()-2) - 1; + const int minDim = std::min(ircWhole.Width(), ircWhole.Height() - 2) - 1; int centreX = (ircWhole.right + ircWhole.left) / 2; const int centreY = (ircWhole.bottom + ircWhole.top) / 2; const int dimOn2 = minDim / 2; const int dimOn4 = minDim / 4; - const int blobSize = dimOn2-1; - const int armSize = dimOn2-2; + const int blobSize = dimOn2 - 1; + const int armSize = dimOn2 - 2; if (marginStyle == SC_MARGIN_NUMBER || marginStyle == SC_MARGIN_TEXT || marginStyle == SC_MARGIN_RTEXT) { // On textual margins move marker to the left to try to avoid overlapping the text centreX = ircWhole.left + dimOn2 + 1; } - if (markType == SC_MARK_ROUNDRECT) { - PRectangle rcRounded = rc; - rcRounded.left = rc.left + 1; - rcRounded.right = rc.right - 1; - surface->RoundedRectangle(rcRounded, fore, back); - } else if (markType == SC_MARK_CIRCLE) { - const PRectangle rcCircle = PRectangle::FromInts( - centreX - dimOn2, - centreY - dimOn2, - centreX + dimOn2, - centreY + dimOn2); - surface->Ellipse(rcCircle, fore, back); - } else if (markType == SC_MARK_ARROW) { - Point pts[] = { - Point::FromInts(centreX - dimOn4, centreY - dimOn2), - Point::FromInts(centreX - dimOn4, centreY + dimOn2), - Point::FromInts(centreX + dimOn2 - dimOn4, centreY), - }; - surface->Polygon(pts, ELEMENTS(pts), fore, back); - - } else if (markType == SC_MARK_ARROWDOWN) { - Point pts[] = { - Point::FromInts(centreX - dimOn2, centreY - dimOn4), - Point::FromInts(centreX + dimOn2, centreY - dimOn4), - Point::FromInts(centreX, centreY + dimOn2 - dimOn4), - }; - surface->Polygon(pts, ELEMENTS(pts), fore, back); - - } else if (markType == SC_MARK_PLUS) { - Point pts[] = { - Point::FromInts(centreX - armSize, centreY - 1), - Point::FromInts(centreX - 1, centreY - 1), - Point::FromInts(centreX - 1, centreY - armSize), - Point::FromInts(centreX + 1, centreY - armSize), - Point::FromInts(centreX + 1, centreY - 1), - Point::FromInts(centreX + armSize, centreY -1), - Point::FromInts(centreX + armSize, centreY +1), - Point::FromInts(centreX + 1, centreY + 1), - Point::FromInts(centreX + 1, centreY + armSize), - Point::FromInts(centreX - 1, centreY + armSize), - Point::FromInts(centreX - 1, centreY + 1), - Point::FromInts(centreX - armSize, centreY + 1), - }; - surface->Polygon(pts, ELEMENTS(pts), fore, back); - - } else if (markType == SC_MARK_MINUS) { - Point pts[] = { - Point::FromInts(centreX - armSize, centreY - 1), - Point::FromInts(centreX + armSize, centreY -1), - Point::FromInts(centreX + armSize, centreY +1), - Point::FromInts(centreX - armSize, centreY + 1), - }; - surface->Polygon(pts, ELEMENTS(pts), fore, back); - - } else if (markType == SC_MARK_SMALLRECT) { - PRectangle rcSmall; - rcSmall.left = rc.left + 1; - rcSmall.top = rc.top + 2; - rcSmall.right = rc.right - 1; - rcSmall.bottom = rc.bottom - 2; - surface->RectangleDraw(rcSmall, fore, back); - - } else if (markType == SC_MARK_EMPTY || markType == SC_MARK_BACKGROUND || - markType == SC_MARK_UNDERLINE || markType == SC_MARK_AVAILABLE) { + + switch (markType) { + case SC_MARK_ROUNDRECT: { + PRectangle rcRounded = rc; + rcRounded.left = rc.left + 1; + rcRounded.right = rc.right - 1; + surface->RoundedRectangle(rcRounded, fore, back); + } + break; + + case SC_MARK_CIRCLE: { + const PRectangle rcCircle = PRectangle::FromInts( + centreX - dimOn2, + centreY - dimOn2, + centreX + dimOn2, + centreY + dimOn2); + surface->Ellipse(rcCircle, fore, back); + } + break; + + case SC_MARK_ARROW: { + Point pts[] = { + Point::FromInts(centreX - dimOn4, centreY - dimOn2), + Point::FromInts(centreX - dimOn4, centreY + dimOn2), + Point::FromInts(centreX + dimOn2 - dimOn4, centreY), + }; + surface->Polygon(pts, Sci::size(pts), fore, back); + } + break; + + case SC_MARK_ARROWDOWN: { + Point pts[] = { + Point::FromInts(centreX - dimOn2, centreY - dimOn4), + Point::FromInts(centreX + dimOn2, centreY - dimOn4), + Point::FromInts(centreX, centreY + dimOn2 - dimOn4), + }; + surface->Polygon(pts, Sci::size(pts), fore, back); + } + break; + + case SC_MARK_PLUS: { + Point pts[] = { + Point::FromInts(centreX - armSize, centreY - 1), + Point::FromInts(centreX - 1, centreY - 1), + Point::FromInts(centreX - 1, centreY - armSize), + Point::FromInts(centreX + 1, centreY - armSize), + Point::FromInts(centreX + 1, centreY - 1), + Point::FromInts(centreX + armSize, centreY - 1), + Point::FromInts(centreX + armSize, centreY + 1), + Point::FromInts(centreX + 1, centreY + 1), + Point::FromInts(centreX + 1, centreY + armSize), + Point::FromInts(centreX - 1, centreY + armSize), + Point::FromInts(centreX - 1, centreY + 1), + Point::FromInts(centreX - armSize, centreY + 1), + }; + surface->Polygon(pts, Sci::size(pts), fore, back); + } + break; + + case SC_MARK_MINUS: { + Point pts[] = { + Point::FromInts(centreX - armSize, centreY - 1), + Point::FromInts(centreX + armSize, centreY - 1), + Point::FromInts(centreX + armSize, centreY + 1), + Point::FromInts(centreX - armSize, centreY + 1), + }; + surface->Polygon(pts, Sci::size(pts), fore, back); + } + break; + + case SC_MARK_SMALLRECT: { + PRectangle rcSmall; + rcSmall.left = rc.left + 1; + rcSmall.top = rc.top + 2; + rcSmall.right = rc.right - 1; + rcSmall.bottom = rc.bottom - 2; + surface->RectangleDraw(rcSmall, fore, back); + } + break; + + case SC_MARK_EMPTY: + case SC_MARK_BACKGROUND: + case SC_MARK_UNDERLINE: + case SC_MARK_AVAILABLE: // An invisible marker so don't draw anything + break; + + case SC_MARK_VLINE: { + surface->PenColour(colourBody); + surface->MoveTo(centreX, ircWhole.top); + surface->LineTo(centreX, ircWhole.bottom); + } + break; - } else if (markType == SC_MARK_VLINE) { - surface->PenColour(colourBody); - surface->MoveTo(centreX, ircWhole.top); - surface->LineTo(centreX, ircWhole.bottom); - - } else if (markType == SC_MARK_LCORNER) { - surface->PenColour(colourTail); - surface->MoveTo(centreX, ircWhole.top); - surface->LineTo(centreX, centreY); - surface->LineTo(ircWhole.right - 1, centreY); - - } else if (markType == SC_MARK_TCORNER) { - surface->PenColour(colourTail); - surface->MoveTo(centreX, centreY); - surface->LineTo(ircWhole.right - 1, centreY); - - surface->PenColour(colourBody); - surface->MoveTo(centreX, ircWhole.top); - surface->LineTo(centreX, centreY + 1); - - surface->PenColour(colourHead); - surface->LineTo(centreX, ircWhole.bottom); - - } else if (markType == SC_MARK_LCORNERCURVE) { - surface->PenColour(colourTail); - surface->MoveTo(centreX, ircWhole.top); - surface->LineTo(centreX, centreY-3); - surface->LineTo(centreX+3, centreY); - surface->LineTo(ircWhole.right - 1, centreY); - - } else if (markType == SC_MARK_TCORNERCURVE) { - surface->PenColour(colourTail); - surface->MoveTo(centreX, centreY-3); - surface->LineTo(centreX+3, centreY); - surface->LineTo(ircWhole.right - 1, centreY); - - surface->PenColour(colourBody); - surface->MoveTo(centreX, ircWhole.top); - surface->LineTo(centreX, centreY-2); - - surface->PenColour(colourHead); - surface->LineTo(centreX, ircWhole.bottom); - - } else if (markType == SC_MARK_BOXPLUS) { - DrawBox(surface, centreX, centreY, blobSize, fore, colourHead); - DrawPlus(surface, centreX, centreY, blobSize, colourTail); - - } else if (markType == SC_MARK_BOXPLUSCONNECTED) { - if (tFold == LineMarker::headWithTail) + case SC_MARK_LCORNER: { surface->PenColour(colourTail); - else + surface->MoveTo(centreX, ircWhole.top); + surface->LineTo(centreX, centreY); + surface->LineTo(ircWhole.right - 1, centreY); + } + break; + + case SC_MARK_TCORNER: { + surface->PenColour(colourTail); + surface->MoveTo(centreX, centreY); + surface->LineTo(ircWhole.right - 1, centreY); + surface->PenColour(colourBody); - surface->MoveTo(centreX, centreY + blobSize); - surface->LineTo(centreX, ircWhole.bottom); + surface->MoveTo(centreX, ircWhole.top); + surface->LineTo(centreX, centreY + 1); - surface->PenColour(colourBody); - surface->MoveTo(centreX, ircWhole.top); - surface->LineTo(centreX, centreY - blobSize); + surface->PenColour(colourHead); + surface->LineTo(centreX, ircWhole.bottom); + } + break; - DrawBox(surface, centreX, centreY, blobSize, fore, colourHead); - DrawPlus(surface, centreX, centreY, blobSize, colourTail); + case SC_MARK_LCORNERCURVE: { + surface->PenColour(colourTail); + surface->MoveTo(centreX, ircWhole.top); + surface->LineTo(centreX, centreY - 3); + surface->LineTo(centreX + 3, centreY); + surface->LineTo(ircWhole.right - 1, centreY); + } + break; - if (tFold == LineMarker::body) { + case SC_MARK_TCORNERCURVE: { surface->PenColour(colourTail); - surface->MoveTo(centreX + 1, centreY + blobSize); - surface->LineTo(centreX + blobSize + 1, centreY + blobSize); + surface->MoveTo(centreX, centreY - 3); + surface->LineTo(centreX + 3, centreY); + surface->LineTo(ircWhole.right - 1, centreY); - surface->MoveTo(centreX + blobSize, centreY + blobSize); - surface->LineTo(centreX + blobSize, centreY - blobSize); + surface->PenColour(colourBody); + surface->MoveTo(centreX, ircWhole.top); + surface->LineTo(centreX, centreY - 2); - surface->MoveTo(centreX + 1, centreY - blobSize); - surface->LineTo(centreX + blobSize + 1, centreY - blobSize); + surface->PenColour(colourHead); + surface->LineTo(centreX, ircWhole.bottom); } - } else if (markType == SC_MARK_BOXMINUS) { - DrawBox(surface, centreX, centreY, blobSize, fore, colourHead); - DrawMinus(surface, centreX, centreY, blobSize, colourTail); + break; - surface->PenColour(colourHead); - surface->MoveTo(centreX, centreY + blobSize); - surface->LineTo(centreX, ircWhole.bottom); + case SC_MARK_BOXPLUS: { + DrawBox(surface, centreX, centreY, blobSize, fore, colourHead); + DrawPlus(surface, centreX, centreY, blobSize, colourTail); + } + break; - } else if (markType == SC_MARK_BOXMINUSCONNECTED) { - DrawBox(surface, centreX, centreY, blobSize, fore, colourHead); - DrawMinus(surface, centreX, centreY, blobSize, colourTail); + case SC_MARK_BOXPLUSCONNECTED: { + if (part == FoldPart::headWithTail) + surface->PenColour(colourTail); + else + surface->PenColour(colourBody); + surface->MoveTo(centreX, centreY + blobSize); + surface->LineTo(centreX, ircWhole.bottom); - surface->PenColour(colourHead); - surface->MoveTo(centreX, centreY + blobSize); - surface->LineTo(centreX, ircWhole.bottom); + surface->PenColour(colourBody); + surface->MoveTo(centreX, ircWhole.top); + surface->LineTo(centreX, centreY - blobSize); - surface->PenColour(colourBody); - surface->MoveTo(centreX, ircWhole.top); - surface->LineTo(centreX, centreY - blobSize); + DrawBox(surface, centreX, centreY, blobSize, fore, colourHead); + DrawPlus(surface, centreX, centreY, blobSize, colourTail); - if (tFold == LineMarker::body) { - surface->PenColour(colourTail); - surface->MoveTo(centreX + 1, centreY + blobSize); - surface->LineTo(centreX + blobSize + 1, centreY + blobSize); + if (part == FoldPart::body) { + surface->PenColour(colourTail); + surface->MoveTo(centreX + 1, centreY + blobSize); + surface->LineTo(centreX + blobSize + 1, centreY + blobSize); - surface->MoveTo(centreX + blobSize, centreY + blobSize); - surface->LineTo(centreX + blobSize, centreY - blobSize); + surface->MoveTo(centreX + blobSize, centreY + blobSize); + surface->LineTo(centreX + blobSize, centreY - blobSize); - surface->MoveTo(centreX + 1, centreY - blobSize); - surface->LineTo(centreX + blobSize + 1, centreY - blobSize); + surface->MoveTo(centreX + 1, centreY - blobSize); + surface->LineTo(centreX + blobSize + 1, centreY - blobSize); + } } - } else if (markType == SC_MARK_CIRCLEPLUS) { - DrawCircle(surface, centreX, centreY, blobSize, fore, colourHead); - DrawPlus(surface, centreX, centreY, blobSize, colourTail); + break; + + case SC_MARK_BOXMINUS: { + DrawBox(surface, centreX, centreY, blobSize, fore, colourHead); + DrawMinus(surface, centreX, centreY, blobSize, colourTail); + + surface->PenColour(colourHead); + surface->MoveTo(centreX, centreY + blobSize); + surface->LineTo(centreX, ircWhole.bottom); + } + break; + + case SC_MARK_BOXMINUSCONNECTED: { + DrawBox(surface, centreX, centreY, blobSize, fore, colourHead); + DrawMinus(surface, centreX, centreY, blobSize, colourTail); + + surface->PenColour(colourHead); + surface->MoveTo(centreX, centreY + blobSize); + surface->LineTo(centreX, ircWhole.bottom); - } else if (markType == SC_MARK_CIRCLEPLUSCONNECTED) { - if (tFold == LineMarker::headWithTail) - surface->PenColour(colourTail); - else surface->PenColour(colourBody); - surface->MoveTo(centreX, centreY + blobSize); - surface->LineTo(centreX, ircWhole.bottom); - - surface->PenColour(colourBody); - surface->MoveTo(centreX, ircWhole.top); - surface->LineTo(centreX, centreY - blobSize); - - DrawCircle(surface, centreX, centreY, blobSize, fore, colourHead); - DrawPlus(surface, centreX, centreY, blobSize, colourTail); - - } else if (markType == SC_MARK_CIRCLEMINUS) { - surface->PenColour(colourHead); - surface->MoveTo(centreX, centreY + blobSize); - surface->LineTo(centreX, ircWhole.bottom); - - DrawCircle(surface, centreX, centreY, blobSize, fore, colourHead); - DrawMinus(surface, centreX, centreY, blobSize, colourTail); - - } else if (markType == SC_MARK_CIRCLEMINUSCONNECTED) { - surface->PenColour(colourHead); - surface->MoveTo(centreX, centreY + blobSize); - surface->LineTo(centreX, ircWhole.bottom); - - surface->PenColour(colourBody); - surface->MoveTo(centreX, ircWhole.top); - surface->LineTo(centreX, centreY - blobSize); - - DrawCircle(surface, centreX, centreY, blobSize, fore, colourHead); - DrawMinus(surface, centreX, centreY, blobSize, colourTail); - - } else if (markType >= SC_MARK_CHARACTER) { - char character[1]; - character[0] = static_cast(markType - SC_MARK_CHARACTER); - const XYPOSITION width = surface->WidthText(fontForCharacter, character, 1); - PRectangle rcText = rc; - rcText.left += (rc.Width() - width) / 2; - rcText.right = rc.left + width; - surface->DrawTextClipped(rcText, fontForCharacter, rcText.bottom - 2, - character, 1, fore, back); - - } else if (markType == SC_MARK_DOTDOTDOT) { - XYPOSITION right = static_cast(centreX - 6); - for (int b=0; b<3; b++) { - const PRectangle rcBlob(right, rc.bottom - 4, right + 2, rc.bottom-2); - surface->FillRectangle(rcBlob, fore); - right += 5.0f; + surface->MoveTo(centreX, ircWhole.top); + surface->LineTo(centreX, centreY - blobSize); + + if (part == FoldPart::body) { + surface->PenColour(colourTail); + surface->MoveTo(centreX + 1, centreY + blobSize); + surface->LineTo(centreX + blobSize + 1, centreY + blobSize); + + surface->MoveTo(centreX + blobSize, centreY + blobSize); + surface->LineTo(centreX + blobSize, centreY - blobSize); + + surface->MoveTo(centreX + 1, centreY - blobSize); + surface->LineTo(centreX + blobSize + 1, centreY - blobSize); + } } - } else if (markType == SC_MARK_ARROWS) { - surface->PenColour(fore); - int right = centreX - 2; - const int armLength = dimOn2 - 1; - for (int b = 0; b<3; b++) { - surface->MoveTo(right, centreY); - surface->LineTo(right - armLength, centreY - armLength); - surface->MoveTo(right, centreY); - surface->LineTo(right - armLength, centreY + armLength); - right += 4; + break; + + case SC_MARK_CIRCLEPLUS: { + DrawCircle(surface, centreX, centreY, blobSize, fore, colourHead); + DrawPlus(surface, centreX, centreY, blobSize, colourTail); + } + break; + + case SC_MARK_CIRCLEPLUSCONNECTED: { + if (part == FoldPart::headWithTail) + surface->PenColour(colourTail); + else + surface->PenColour(colourBody); + surface->MoveTo(centreX, centreY + blobSize); + surface->LineTo(centreX, ircWhole.bottom); + + surface->PenColour(colourBody); + surface->MoveTo(centreX, ircWhole.top); + surface->LineTo(centreX, centreY - blobSize); + + DrawCircle(surface, centreX, centreY, blobSize, fore, colourHead); + DrawPlus(surface, centreX, centreY, blobSize, colourTail); + } + break; + + case SC_MARK_CIRCLEMINUS: { + surface->PenColour(colourHead); + surface->MoveTo(centreX, centreY + blobSize); + surface->LineTo(centreX, ircWhole.bottom); + + DrawCircle(surface, centreX, centreY, blobSize, fore, colourHead); + DrawMinus(surface, centreX, centreY, blobSize, colourTail); + } + break; + + case SC_MARK_CIRCLEMINUSCONNECTED: { + surface->PenColour(colourHead); + surface->MoveTo(centreX, centreY + blobSize); + surface->LineTo(centreX, ircWhole.bottom); + + surface->PenColour(colourBody); + surface->MoveTo(centreX, ircWhole.top); + surface->LineTo(centreX, centreY - blobSize); + + DrawCircle(surface, centreX, centreY, blobSize, fore, colourHead); + DrawMinus(surface, centreX, centreY, blobSize, colourTail); } - } else if (markType == SC_MARK_SHORTARROW) { - Point pts[] = { - Point::FromInts(centreX, centreY + dimOn2), - Point::FromInts(centreX + dimOn2, centreY), - Point::FromInts(centreX, centreY - dimOn2), - Point::FromInts(centreX, centreY - dimOn4), - Point::FromInts(centreX - dimOn4, centreY - dimOn4), - Point::FromInts(centreX - dimOn4, centreY + dimOn4), - Point::FromInts(centreX, centreY + dimOn4), - Point::FromInts(centreX, centreY + dimOn2), - }; - surface->Polygon(pts, ELEMENTS(pts), fore, back); - } else if (markType == SC_MARK_LEFTRECT) { - PRectangle rcLeft = rcWhole; - rcLeft.right = rcLeft.left + 4; - surface->FillRectangle(rcLeft, back); - } else if (markType == SC_MARK_BOOKMARK) { - const int halfHeight = minDim / 3; - Point pts[] = { - Point::FromInts(ircWhole.left, centreY-halfHeight), - Point::FromInts(ircWhole.right - 3, centreY - halfHeight), - Point::FromInts(ircWhole.right - 3 - halfHeight, centreY), - Point::FromInts(ircWhole.right - 3, centreY + halfHeight), - Point::FromInts(ircWhole.left, centreY + halfHeight), - }; - surface->Polygon(pts, ELEMENTS(pts), fore, back); - } else if (markType == SC_MARK_VERTICALBOOKMARK) { - const int halfWidth = minDim / 3; - Point pts[] = { - Point::FromInts(centreX - halfWidth, centreY - dimOn2), - Point::FromInts(centreX + halfWidth, centreY - dimOn2), - Point::FromInts(centreX + halfWidth, centreY + dimOn2), - Point::FromInts(centreX, centreY + dimOn2 - halfWidth), - Point::FromInts(centreX - halfWidth, centreY + dimOn2), - }; - surface->Polygon(pts, ELEMENTS(pts), fore, back); - } else { // SC_MARK_FULLRECT + break; + + case SC_MARK_DOTDOTDOT: { + XYPOSITION right = static_cast(centreX - 6); + for (int b = 0; b < 3; b++) { + const PRectangle rcBlob(right, rc.bottom - 4, right + 2, rc.bottom - 2); + surface->FillRectangle(rcBlob, fore); + right += 5.0f; + } + } + break; + + case SC_MARK_ARROWS: { + surface->PenColour(fore); + int right = centreX - 2; + const int armLength = dimOn2 - 1; + for (int b = 0; b < 3; b++) { + surface->MoveTo(right, centreY); + surface->LineTo(right - armLength, centreY - armLength); + surface->MoveTo(right, centreY); + surface->LineTo(right - armLength, centreY + armLength); + right += 4; + } + } + break; + + case SC_MARK_SHORTARROW: { + Point pts[] = { + Point::FromInts(centreX, centreY + dimOn2), + Point::FromInts(centreX + dimOn2, centreY), + Point::FromInts(centreX, centreY - dimOn2), + Point::FromInts(centreX, centreY - dimOn4), + Point::FromInts(centreX - dimOn4, centreY - dimOn4), + Point::FromInts(centreX - dimOn4, centreY + dimOn4), + Point::FromInts(centreX, centreY + dimOn4), + Point::FromInts(centreX, centreY + dimOn2), + }; + surface->Polygon(pts, Sci::size(pts), fore, back); + } + break; + + case SC_MARK_FULLRECT: surface->FillRectangle(rcWhole, back); + break; + + case SC_MARK_LEFTRECT: { + PRectangle rcLeft = rcWhole; + rcLeft.right = rcLeft.left + 4; + surface->FillRectangle(rcLeft, back); + } + break; + + case SC_MARK_BOOKMARK: { + const int halfHeight = minDim / 3; + Point pts[] = { + Point::FromInts(ircWhole.left, centreY - halfHeight), + Point::FromInts(ircWhole.right - 3, centreY - halfHeight), + Point::FromInts(ircWhole.right - 3 - halfHeight, centreY), + Point::FromInts(ircWhole.right - 3, centreY + halfHeight), + Point::FromInts(ircWhole.left, centreY + halfHeight), + }; + surface->Polygon(pts, Sci::size(pts), fore, back); + } + break; + + case SC_MARK_VERTICALBOOKMARK: { + const int halfWidth = minDim / 3; + Point pts[] = { + Point::FromInts(centreX - halfWidth, centreY - dimOn2), + Point::FromInts(centreX + halfWidth, centreY - dimOn2), + Point::FromInts(centreX + halfWidth, centreY + dimOn2), + Point::FromInts(centreX, centreY + dimOn2 - halfWidth), + Point::FromInts(centreX - halfWidth, centreY + dimOn2), + }; + surface->Polygon(pts, Sci::size(pts), fore, back); + } + break; + + default: + if (markType >= SC_MARK_CHARACTER) { + char character[1]; + character[0] = static_cast(markType - SC_MARK_CHARACTER); + const XYPOSITION width = surface->WidthText(fontForCharacter, character, 1); + PRectangle rcText = rc; + rcText.left += (rc.Width() - width) / 2; + rcText.right = rc.left + width; + surface->DrawTextClipped(rcText, fontForCharacter, rcText.bottom - 2, + character, 1, fore, back); + } else { + // treat as SC_MARK_FULLRECT + surface->FillRectangle(rcWhole, back); + } + break; } } diff --git a/scintilla/src/LineMarker.h b/scintilla/src/LineMarker.h index 8a15327d2e..00fe0b7e0c 100644 --- a/scintilla/src/LineMarker.h +++ b/scintilla/src/LineMarker.h @@ -19,7 +19,7 @@ typedef void (*DrawLineMarkerFn)(Surface *surface, PRectangle &rcWhole, Font &fo */ class LineMarker { public: - enum typeOfFold { undefined, head, body, tail, headWithTail }; + enum class FoldPart { undefined, head, body, tail, headWithTail }; int markType = SC_MARK_CIRCLE; ColourDesired fore = ColourDesired(0, 0, 0); @@ -34,7 +34,7 @@ class LineMarker { * platforms must implement as empty. */ DrawLineMarkerFn customDraw = nullptr; - LineMarker() noexcept = default; + LineMarker() = default; LineMarker(const LineMarker &other); LineMarker(LineMarker &&) noexcept = default; LineMarker &operator=(const LineMarker& other); @@ -44,7 +44,7 @@ class LineMarker { void SetXPM(const char *textForm); void SetXPM(const char *const *linesForm); void SetRGBAImage(Point sizeRGBAImage, float scale, const unsigned char *pixelsRGBAImage); - void Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter, typeOfFold tFold, int marginStyle) const; + void Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter, FoldPart part, int marginStyle) const; }; } diff --git a/scintilla/src/MarginView.cxx b/scintilla/src/MarginView.cxx index a2fea70a7c..a742bdc4bc 100644 --- a/scintilla/src/MarginView.cxx +++ b/scintilla/src/MarginView.cxx @@ -171,7 +171,7 @@ void MarginView::RefreshPixMaps(Surface *surfaceWindow, WindowID wid, const View } } -static int SubstituteMarkerIfEmpty(int markerCheck, int markerDefault, const ViewStyle &vs) { +static int SubstituteMarkerIfEmpty(int markerCheck, int markerDefault, const ViewStyle &vs) noexcept { if (vs.markers[markerCheck].markType == SC_MARK_EMPTY) return markerDefault; return markerCheck; @@ -364,9 +364,11 @@ void MarginView::PaintMargin(Surface *surface, Sci::Line topLine, PRectangle rc, marks &= vs.ms[margin].mask; - PRectangle rcMarker = rcSelMargin; - rcMarker.top = static_cast(yposScreen); - rcMarker.bottom = static_cast(yposScreen + vs.lineHeight); + PRectangle rcMarker( + rcSelMargin.left, + static_cast(yposScreen), + rcSelMargin.right, + static_cast(yposScreen + vs.lineHeight)); if (vs.ms[margin].style == SC_MARGIN_NUMBER) { if (firstSubLine) { std::string sNumber; @@ -412,14 +414,15 @@ void MarginView::PaintMargin(Surface *surface, Sci::Line topLine, PRectangle rc, if (firstSubLine) { surface->FillRectangle(rcMarker, vs.styles[stMargin.StyleAt(0) + vs.marginStyleOffset].back); + PRectangle rcText = rcMarker; if (vs.ms[margin].style == SC_MARGIN_RTEXT) { const int width = WidestLineWidth(surface, vs, vs.marginStyleOffset, stMargin); - rcMarker.left = rcMarker.right - width - 3; + rcText.left = rcText.right - width - 3; } - DrawStyledText(surface, vs, vs.marginStyleOffset, rcMarker, + DrawStyledText(surface, vs, vs.marginStyleOffset, rcText, stMargin, 0, stMargin.length, drawAll); } else { - // if we're displaying annotation lines, color the margin to match the associated document line + // if we're displaying annotation lines, colour the margin to match the associated document line const int annotationLines = model.pdoc->AnnotationLines(lineDoc); if (annotationLines && (visibleLine > lastVisibleLine - annotationLines)) { surface->FillRectangle(rcMarker, vs.styles[stMargin.StyleAt(0) + vs.marginStyleOffset].back); @@ -431,25 +434,25 @@ void MarginView::PaintMargin(Surface *surface, Sci::Line topLine, PRectangle rc, if (marks) { for (int markBit = 0; (markBit < 32) && marks; markBit++) { if (marks & 1) { - LineMarker::typeOfFold tFold = LineMarker::undefined; + LineMarker::FoldPart part = LineMarker::FoldPart::undefined; if ((vs.ms[margin].mask & SC_MASK_FOLDERS) && highlightDelimiter.IsFoldBlockHighlighted(lineDoc)) { if (highlightDelimiter.IsBodyOfFoldBlock(lineDoc)) { - tFold = LineMarker::body; + part = LineMarker::FoldPart::body; } else if (highlightDelimiter.IsHeadOfFoldBlock(lineDoc)) { if (firstSubLine) { - tFold = headWithTail ? LineMarker::headWithTail : LineMarker::head; + part = headWithTail ? LineMarker::FoldPart::headWithTail : LineMarker::FoldPart::head; } else { if (model.pcs->GetExpanded(lineDoc) || headWithTail) { - tFold = LineMarker::body; + part = LineMarker::FoldPart::body; } else { - tFold = LineMarker::undefined; + part = LineMarker::FoldPart::undefined; } } } else if (highlightDelimiter.IsTailOfFoldBlock(lineDoc)) { - tFold = LineMarker::tail; + part = LineMarker::FoldPart::tail; } } - vs.markers[markBit].Draw(surface, rcMarker, fontLineNumber, tFold, vs.ms[margin].style); + vs.markers[markBit].Draw(surface, rcMarker, fontLineNumber, part, vs.ms[margin].style); } marks >>= 1; } diff --git a/scintilla/src/Partitioning.h b/scintilla/src/Partitioning.h index a92e55b53b..171a694d97 100644 --- a/scintilla/src/Partitioning.h +++ b/scintilla/src/Partitioning.h @@ -8,6 +8,8 @@ #ifndef PARTITIONING_H #define PARTITIONING_H +#include "Compat.h" + namespace Scintilla { /// A split vector of integers with a method for adding a value to all elements @@ -85,7 +87,7 @@ class Partitioning { } void Allocate(ptrdiff_t growSize) { - body.reset(new SplitVectorWithRangeAdd(growSize)); + body = Sci::make_unique>(growSize); stepPartition = 0; stepLength = 0; body->Insert(0, 0); // This value stays 0 for ever @@ -110,6 +112,10 @@ class Partitioning { return static_cast(body->Length())-1; } + T Length() const noexcept { + return PositionFromPartition(Partitions()); + } + void InsertPartition(T partition, T pos) { if (stepPartition < partition) { ApplyStep(partition); @@ -118,6 +124,26 @@ class Partitioning { stepPartition++; } + void InsertPartitions(T partition, const T *positions, size_t length) { + if (stepPartition < partition) { + ApplyStep(partition); + } + body->InsertFromArray(partition, positions, 0, length); + stepPartition += static_cast(length); + } + + void InsertPartitionsWithCast(T partition, const ptrdiff_t *positions, size_t length) { + // Used for 64-bit builds when T is 32-bits + if (stepPartition < partition) { + ApplyStep(partition); + } + T *pInsertion = body->InsertEmpty(partition, length); + for (size_t i = 0; i < length; i++) { + pInsertion[i] = static_cast(positions[i]); + } + stepPartition += static_cast(length); + } + void SetPartitionStartPosition(T partition, T pos) noexcept { ApplyStep(partition+1); if ((partition < 0) || (partition > body->Length())) { @@ -126,7 +152,7 @@ class Partitioning { body->SetValueAt(partition, pos); } - void InsertText(T partitionInsert, T delta) { + void InsertText(T partitionInsert, T delta) noexcept { // Point all the partitions after the insertion point further along in the buffer if (stepLength != 0) { if (partitionInsert >= stepPartition) { @@ -196,6 +222,34 @@ class Partitioning { void DeleteAll() { Allocate(body->GetGrowSize()); } + + void Check() const { +#ifdef CHECK_CORRECTNESS + if (Length() < 0) { + throw std::runtime_error("Partitioning: Length can not be negative."); + } + if (Partitions() < 1) { + throw std::runtime_error("Partitioning: Must always have 1 or more partitions."); + } + if (Length() == 0) { + if ((PositionFromPartition(0) != 0) || (PositionFromPartition(1) != 0)) { + throw std::runtime_error("Partitioning: Invalid empty partitioning."); + } + } else { + // Positions should be a strictly ascending sequence + for (T i = 0; i < Partitions(); i++) { + const T pos = PositionFromPartition(i); + const T posNext = PositionFromPartition(i+1); + if (pos > posNext) { + throw std::runtime_error("Partitioning: Negative partition."); + } else if (pos == posNext) { + throw std::runtime_error("Partitioning: Empty partition."); + } + } + } +#endif + } + }; diff --git a/scintilla/src/PerLine.cxx b/scintilla/src/PerLine.cxx index 5375122907..3c8272372f 100644 --- a/scintilla/src/PerLine.cxx +++ b/scintilla/src/PerLine.cxx @@ -54,18 +54,27 @@ bool MarkerHandleSet::Contains(int handle) const noexcept { return false; } +MarkerHandleNumber const *MarkerHandleSet::GetMarkerHandleNumber(int which) const noexcept { + for (const MarkerHandleNumber &mhn : mhList) { + if (which == 0) + return &mhn; + which--; + } + return nullptr; +} + bool MarkerHandleSet::InsertHandle(int handle, int markerNum) { mhList.push_front(MarkerHandleNumber(handle, markerNum)); return true; } void MarkerHandleSet::RemoveHandle(int handle) { - mhList.remove_if([handle](const MarkerHandleNumber &mhn) { return mhn.handle == handle; }); + mhList.remove_if([handle](const MarkerHandleNumber &mhn) noexcept { return mhn.handle == handle; }); } bool MarkerHandleSet::RemoveNumber(int markerNum, bool all) { bool performedDeletion = false; - mhList.remove_if([&](const MarkerHandleNumber &mhn) { + mhList.remove_if([&](const MarkerHandleNumber &mhn) noexcept { if ((all || !performedDeletion) && (mhn.number == markerNum)) { performedDeletion = true; return true; @@ -75,12 +84,11 @@ bool MarkerHandleSet::RemoveNumber(int markerNum, bool all) { return performedDeletion; } -void MarkerHandleSet::CombineWith(MarkerHandleSet *other) { +void MarkerHandleSet::CombineWith(MarkerHandleSet *other) noexcept { mhList.splice_after(mhList.before_begin(), other->mhList); } LineMarkers::~LineMarkers() { - markers.DeleteAll(); } void LineMarkers::Init() { @@ -93,6 +101,12 @@ void LineMarkers::InsertLine(Sci::Line line) { } } +void LineMarkers::InsertLines(Sci::Line line, Sci::Line lines) { + if (markers.Length()) { + markers.InsertEmpty(line, lines); + } +} + void LineMarkers::RemoveLine(Sci::Line line) { // Retain the markers from the deleted line by oring them into the previous line if (markers.Length()) { @@ -103,39 +117,51 @@ void LineMarkers::RemoveLine(Sci::Line line) { } } -Sci::Line LineMarkers::LineFromHandle(int markerHandle) { - if (markers.Length()) { - for (Sci::Line line = 0; line < markers.Length(); line++) { - if (markers[line]) { - if (markers[line]->Contains(markerHandle)) { - return line; - } - } +Sci::Line LineMarkers::LineFromHandle(int markerHandle) const noexcept { + for (Sci::Line line = 0; line < markers.Length(); line++) { + if (markers[line] && markers[line]->Contains(markerHandle)) { + return line; } } return -1; } +int LineMarkers::HandleFromLine(Sci::Line line, int which) const noexcept { + if (markers.Length() && (line >= 0) && (line < markers.Length()) && markers[line]) { + MarkerHandleNumber const *pnmh = markers[line]->GetMarkerHandleNumber(which); + return pnmh ? pnmh->handle : -1; + } + return -1; +} + +int LineMarkers::NumberFromLine(Sci::Line line, int which) const noexcept { + if (markers.Length() && (line >= 0) && (line < markers.Length()) && markers[line]) { + MarkerHandleNumber const *pnmh = markers[line]->GetMarkerHandleNumber(which); + return pnmh ? pnmh->number : -1; + } + return -1; +} + void LineMarkers::MergeMarkers(Sci::Line line) { if (markers[line + 1]) { if (!markers[line]) - markers[line].reset(new MarkerHandleSet); + markers[line] = Sci::make_unique(); markers[line]->CombineWith(markers[line + 1].get()); markers[line + 1].reset(); } } -int LineMarkers::MarkValue(Sci::Line line) noexcept { +int LineMarkers::MarkValue(Sci::Line line) const noexcept { if (markers.Length() && (line >= 0) && (line < markers.Length()) && markers[line]) return markers[line]->MarkValue(); else return 0; } -Sci::Line LineMarkers::MarkerNext(Sci::Line lineStart, int mask) const { +Sci::Line LineMarkers::MarkerNext(Sci::Line lineStart, int mask) const noexcept { if (lineStart < 0) lineStart = 0; - const Sci::Line length = static_cast(markers.Length()); + const Sci::Line length = markers.Length(); for (Sci::Line iLine = lineStart; iLine < length; iLine++) { const MarkerHandleSet *onLine = markers[iLine].get(); if (onLine && ((onLine->MarkValue() & mask) != 0)) @@ -155,7 +181,7 @@ int LineMarkers::AddMark(Sci::Line line, int markerNum, Sci::Line lines) { } if (!markers[line]) { // Need new structure to hold marker handle - markers[line].reset(new MarkerHandleSet()); + markers[line] = Sci::make_unique(); } markers[line]->InsertHandle(handleCurrent, markerNum); @@ -198,14 +224,21 @@ void LineLevels::Init() { void LineLevels::InsertLine(Sci::Line line) { if (levels.Length()) { const int level = (line < levels.Length()) ? levels[line] : SC_FOLDLEVELBASE; - levels.InsertValue(line, 1, level); + levels.Insert(line, level); + } +} + +void LineLevels::InsertLines(Sci::Line line, Sci::Line lines) { + if (levels.Length()) { + const int level = (line < levels.Length()) ? levels[line] : SC_FOLDLEVELBASE; + levels.InsertValue(line, lines, level); } } void LineLevels::RemoveLine(Sci::Line line) { if (levels.Length()) { // Move up following lines but merge header flag from this line - // to line before to avoid a temporary disappearence causing expansion. + // to line before to avoid a temporary disappearance causing expansion. int firstHeader = levels[line] & SC_FOLDLEVELHEADERFLAG; levels.Delete(line); if (line == levels.Length()-1) // Last line loses the header flag @@ -237,7 +270,7 @@ int LineLevels::SetLevel(Sci::Line line, int level, Sci::Line lines) { return prev; } -int LineLevels::GetLevel(Sci::Line line) const { +int LineLevels::GetLevel(Sci::Line line) const noexcept { if (levels.Length() && (line >= 0) && (line < levels.Length())) { return levels[line]; } else { @@ -260,6 +293,14 @@ void LineState::InsertLine(Sci::Line line) { } } +void LineState::InsertLines(Sci::Line line, Sci::Line lines) { + if (lineStates.Length()) { + lineStates.EnsureLength(line); + const int val = (line < lineStates.Length()) ? lineStates[line] : 0; + lineStates.InsertValue(line, lines, val); + } +} + void LineState::RemoveLine(Sci::Line line) { if (lineStates.Length() > line) { lineStates.Delete(line); @@ -280,37 +321,43 @@ int LineState::GetLineState(Sci::Line line) { return lineStates[line]; } -Sci::Line LineState::GetMaxLineState() const { - return static_cast(lineStates.Length()); +Sci::Line LineState::GetMaxLineState() const noexcept { + return lineStates.Length(); } -static int NumberLines(const char *text) noexcept { +// Each allocated LineAnnotation is a char array which starts with an AnnotationHeader +// and then has text and optional styles. + +struct AnnotationHeader { + short style; // Style IndividualStyles implies array of styles + short lines; + int length; +}; + +namespace { + +constexpr int IndividualStyles = 0x100; + +size_t NumberLines(const char *text) noexcept { + int lines = 1; if (text) { - int newLines = 0; while (*text) { if (*text == '\n') - newLines++; + lines++; text++; } - return newLines+1; - } else { - return 0; } + return lines; } -// Each allocated LineAnnotation is a char array which starts with an AnnotationHeader -// and then has text and optional styles. - -static const int IndividualStyles = 0x100; +std::unique_ptrAllocateAnnotation(size_t length, int style) { + const size_t len = sizeof(AnnotationHeader) + length + ((style == IndividualStyles) ? length : 0); + return Sci::make_unique(len); +} -struct AnnotationHeader { - short style; // Style IndividualStyles implies array of styles - short lines; - int length; -}; +} LineAnnotation::~LineAnnotation() { - ClearAll(); } void LineAnnotation::Init() { @@ -324,6 +371,13 @@ void LineAnnotation::InsertLine(Sci::Line line) { } } +void LineAnnotation::InsertLines(Sci::Line line, Sci::Line lines) { + if (annotations.Length()) { + annotations.EnsureLength(line); + annotations.InsertEmpty(line, lines); + } +} + void LineAnnotation::RemoveLine(Sci::Line line) { if (annotations.Length() && (line > 0) && (line <= annotations.Length())) { annotations[line-1].reset(); @@ -331,45 +385,39 @@ void LineAnnotation::RemoveLine(Sci::Line line) { } } -bool LineAnnotation::MultipleStyles(Sci::Line line) const { +bool LineAnnotation::MultipleStyles(Sci::Line line) const noexcept { if (annotations.Length() && (line >= 0) && (line < annotations.Length()) && annotations[line]) return reinterpret_cast(annotations[line].get())->style == IndividualStyles; else return false; } -int LineAnnotation::Style(Sci::Line line) const { +int LineAnnotation::Style(Sci::Line line) const noexcept { if (annotations.Length() && (line >= 0) && (line < annotations.Length()) && annotations[line]) return reinterpret_cast(annotations[line].get())->style; else return 0; } -const char *LineAnnotation::Text(Sci::Line line) const { +const char *LineAnnotation::Text(Sci::Line line) const noexcept { if (annotations.Length() && (line >= 0) && (line < annotations.Length()) && annotations[line]) return annotations[line].get()+sizeof(AnnotationHeader); else return nullptr; } -const unsigned char *LineAnnotation::Styles(Sci::Line line) const { +const unsigned char *LineAnnotation::Styles(Sci::Line line) const noexcept { if (annotations.Length() && (line >= 0) && (line < annotations.Length()) && annotations[line] && MultipleStyles(line)) return reinterpret_cast(annotations[line].get() + sizeof(AnnotationHeader) + Length(line)); else return nullptr; } -static char *AllocateAnnotation(int length, int style) { - const size_t len = sizeof(AnnotationHeader) + length + ((style == IndividualStyles) ? length : 0); - char *ret = new char[len](); - return ret; -} - void LineAnnotation::SetText(Sci::Line line, const char *text) { if (text && (line >= 0)) { annotations.EnsureLength(line+1); const int style = Style(line); - annotations[line].reset(AllocateAnnotation(static_cast(strlen(text)), style)); + annotations[line] = AllocateAnnotation(strlen(text), style); char *pa = annotations[line].get(); assert(pa); AnnotationHeader *pah = reinterpret_cast(pa); @@ -391,7 +439,7 @@ void LineAnnotation::ClearAll() { void LineAnnotation::SetStyle(Sci::Line line, int style) { annotations.EnsureLength(line+1); if (!annotations[line]) { - annotations[line].reset(AllocateAnnotation(0, style)); + annotations[line] = AllocateAnnotation(0, style); } reinterpret_cast(annotations[line].get())->style = static_cast(style); } @@ -400,16 +448,16 @@ void LineAnnotation::SetStyles(Sci::Line line, const unsigned char *styles) { if (line >= 0) { annotations.EnsureLength(line+1); if (!annotations[line]) { - annotations[line].reset(AllocateAnnotation(0, IndividualStyles)); + annotations[line] = AllocateAnnotation(0, IndividualStyles); } else { const AnnotationHeader *pahSource = reinterpret_cast(annotations[line].get()); if (pahSource->style != IndividualStyles) { - char *allocation = AllocateAnnotation(pahSource->length, IndividualStyles); - AnnotationHeader *pahAlloc = reinterpret_cast(allocation); + std::unique_ptrallocation = AllocateAnnotation(pahSource->length, IndividualStyles); + AnnotationHeader *pahAlloc = reinterpret_cast(allocation.get()); pahAlloc->length = pahSource->length; pahAlloc->lines = pahSource->lines; - memcpy(allocation + sizeof(AnnotationHeader), annotations[line].get() + sizeof(AnnotationHeader), pahSource->length); - annotations[line].reset(allocation); + memcpy(allocation.get() + sizeof(AnnotationHeader), annotations[line].get() + sizeof(AnnotationHeader), pahSource->length); + annotations[line] = std::move(allocation); } } AnnotationHeader *pah = reinterpret_cast(annotations[line].get()); @@ -418,14 +466,14 @@ void LineAnnotation::SetStyles(Sci::Line line, const unsigned char *styles) { } } -int LineAnnotation::Length(Sci::Line line) const { +int LineAnnotation::Length(Sci::Line line) const noexcept { if (annotations.Length() && (line >= 0) && (line < annotations.Length()) && annotations[line]) return reinterpret_cast(annotations[line].get())->length; else return 0; } -int LineAnnotation::Lines(Sci::Line line) const { +int LineAnnotation::Lines(Sci::Line line) const noexcept { if (annotations.Length() && (line >= 0) && (line < annotations.Length()) && annotations[line]) return reinterpret_cast(annotations[line].get())->lines; else @@ -433,7 +481,6 @@ int LineAnnotation::Lines(Sci::Line line) const { } LineTabstops::~LineTabstops() { - tabstops.DeleteAll(); } void LineTabstops::Init() { @@ -447,6 +494,13 @@ void LineTabstops::InsertLine(Sci::Line line) { } } +void LineTabstops::InsertLines(Sci::Line line, Sci::Line lines) { + if (tabstops.Length()) { + tabstops.EnsureLength(line); + tabstops.InsertEmpty(line, lines); + } +} + void LineTabstops::RemoveLine(Sci::Line line) { if (tabstops.Length() > line) { tabstops[line].reset(); @@ -454,7 +508,7 @@ void LineTabstops::RemoveLine(Sci::Line line) { } } -bool LineTabstops::ClearTabstops(Sci::Line line) { +bool LineTabstops::ClearTabstops(Sci::Line line) noexcept { if (line < tabstops.Length()) { TabstopList *tl = tabstops[line].get(); if (tl) { @@ -468,7 +522,7 @@ bool LineTabstops::ClearTabstops(Sci::Line line) { bool LineTabstops::AddTabstop(Sci::Line line, int x) { tabstops.EnsureLength(line + 1); if (!tabstops[line]) { - tabstops[line].reset(new TabstopList()); + tabstops[line] = Sci::make_unique(); } TabstopList *tl = tabstops[line].get(); @@ -484,7 +538,7 @@ bool LineTabstops::AddTabstop(Sci::Line line, int x) { return false; } -int LineTabstops::GetNextTabstop(Sci::Line line, int x) const { +int LineTabstops::GetNextTabstop(Sci::Line line, int x) const noexcept { if (line < tabstops.Length()) { TabstopList *tl = tabstops[line].get(); if (tl) { diff --git a/scintilla/src/PerLine.h b/scintilla/src/PerLine.h index 94dc17a204..b43b0a18be 100644 --- a/scintilla/src/PerLine.h +++ b/scintilla/src/PerLine.h @@ -40,7 +40,8 @@ class MarkerHandleSet { bool InsertHandle(int handle, int markerNum); void RemoveHandle(int handle); bool RemoveNumber(int markerNum, bool all); - void CombineWith(MarkerHandleSet *other); + void CombineWith(MarkerHandleSet *other) noexcept; + MarkerHandleNumber const *GetMarkerHandleNumber(int which) const noexcept; }; class LineMarkers : public PerLine { @@ -58,15 +59,18 @@ class LineMarkers : public PerLine { ~LineMarkers() override; void Init() override; void InsertLine(Sci::Line line) override; + void InsertLines(Sci::Line line, Sci::Line lines) override; void RemoveLine(Sci::Line line) override; - int MarkValue(Sci::Line line) noexcept; - Sci::Line MarkerNext(Sci::Line lineStart, int mask) const; + int MarkValue(Sci::Line line) const noexcept; + Sci::Line MarkerNext(Sci::Line lineStart, int mask) const noexcept; int AddMark(Sci::Line line, int markerNum, Sci::Line lines); void MergeMarkers(Sci::Line line); bool DeleteMark(Sci::Line line, int markerNum, bool all); void DeleteMarkFromHandle(int markerHandle); - Sci::Line LineFromHandle(int markerHandle); + Sci::Line LineFromHandle(int markerHandle) const noexcept; + int HandleFromLine(Sci::Line line, int which) const noexcept; + int NumberFromLine(Sci::Line line, int which) const noexcept; }; class LineLevels : public PerLine { @@ -82,12 +86,13 @@ class LineLevels : public PerLine { ~LineLevels() override; void Init() override; void InsertLine(Sci::Line line) override; + void InsertLines(Sci::Line line, Sci::Line lines) override; void RemoveLine(Sci::Line line) override; void ExpandLevels(Sci::Line sizeNew=-1); void ClearLevels(); int SetLevel(Sci::Line line, int level, Sci::Line lines); - int GetLevel(Sci::Line line) const; + int GetLevel(Sci::Line line) const noexcept; }; class LineState : public PerLine { @@ -103,11 +108,12 @@ class LineState : public PerLine { ~LineState() override; void Init() override; void InsertLine(Sci::Line line) override; + void InsertLines(Sci::Line line, Sci::Line lines) override; void RemoveLine(Sci::Line line) override; int SetLineState(Sci::Line line, int state); int GetLineState(Sci::Line line); - Sci::Line GetMaxLineState() const; + Sci::Line GetMaxLineState() const noexcept; }; class LineAnnotation : public PerLine { @@ -123,18 +129,19 @@ class LineAnnotation : public PerLine { ~LineAnnotation() override; void Init() override; void InsertLine(Sci::Line line) override; + void InsertLines(Sci::Line line, Sci::Line lines) override; void RemoveLine(Sci::Line line) override; - bool MultipleStyles(Sci::Line line) const; - int Style(Sci::Line line) const; - const char *Text(Sci::Line line) const; - const unsigned char *Styles(Sci::Line line) const; + bool MultipleStyles(Sci::Line line) const noexcept; + int Style(Sci::Line line) const noexcept; + const char *Text(Sci::Line line) const noexcept; + const unsigned char *Styles(Sci::Line line) const noexcept; void SetText(Sci::Line line, const char *text); void ClearAll(); void SetStyle(Sci::Line line, int style); void SetStyles(Sci::Line line, const unsigned char *styles); - int Length(Sci::Line line) const; - int Lines(Sci::Line line) const; + int Length(Sci::Line line) const noexcept; + int Lines(Sci::Line line) const noexcept; }; typedef std::vector TabstopList; @@ -152,11 +159,12 @@ class LineTabstops : public PerLine { ~LineTabstops() override; void Init() override; void InsertLine(Sci::Line line) override; + void InsertLines(Sci::Line line, Sci::Line lines) override; void RemoveLine(Sci::Line line) override; - bool ClearTabstops(Sci::Line line); + bool ClearTabstops(Sci::Line line) noexcept; bool AddTabstop(Sci::Line line, int x); - int GetNextTabstop(Sci::Line line, int x) const; + int GetNextTabstop(Sci::Line line, int x) const noexcept; }; } diff --git a/scintilla/src/Position.h b/scintilla/src/Position.h index ab8223b54e..e0bbcb53f7 100644 --- a/scintilla/src/Position.h +++ b/scintilla/src/Position.h @@ -21,11 +21,6 @@ typedef ptrdiff_t Line; const Position invalidPosition = -1; -template -inline constexpr T clamp(T val, T minVal, T maxVal) { - return (val > maxVal) ? maxVal : ((val < minVal) ? minVal : val); -} - } #endif diff --git a/scintilla/src/PositionCache.cxx b/scintilla/src/PositionCache.cxx index b1b55bd500..bb581d84a0 100644 --- a/scintilla/src/PositionCache.cxx +++ b/scintilla/src/PositionCache.cxx @@ -54,7 +54,7 @@ LineLayout::LineLayout(int maxLineLength_) : maxLineLength(-1), numCharsInLine(0), numCharsBeforeEOL(0), - validity(llInvalid), + validity(ValidLevel::invalid), xHighlightGuide(0), highlightColumn(false), containsCaret(false), @@ -74,11 +74,11 @@ LineLayout::~LineLayout() { void LineLayout::Resize(int maxLineLength_) { if (maxLineLength_ > maxLineLength) { Free(); - chars.reset(new char[maxLineLength_ + 1]); - styles.reset(new unsigned char[maxLineLength_ + 1]); + chars = Sci::make_unique(maxLineLength_ + 1); + styles = Sci::make_unique(maxLineLength_ + 1); // Extra position allocated as sometimes the Windows // GetTextExtentExPoint API writes an extra element. - positions.reset(new XYPOSITION[maxLineLength_ + 1 + 1]); + positions = Sci::make_unique(maxLineLength_ + 1 + 1); maxLineLength = maxLineLength_; } } @@ -90,12 +90,12 @@ void LineLayout::Free() noexcept { lineStarts.reset(); } -void LineLayout::Invalidate(validLevel validity_) { +void LineLayout::Invalidate(ValidLevel validity_) noexcept { if (validity > validity_) validity = validity_; } -int LineLayout::LineStart(int line) const { +int LineLayout::LineStart(int line) const noexcept { if (line <= 0) { return 0; } else if ((line >= lines) || !lineStarts) { @@ -105,7 +105,7 @@ int LineLayout::LineStart(int line) const { } } -int LineLayout::LineLastVisible(int line, Scope scope) const { +int LineLayout::LineLastVisible(int line, Scope scope) const noexcept { if (line < 0) { return 0; } else if ((line >= lines-1) || !lineStarts) { @@ -115,26 +115,26 @@ int LineLayout::LineLastVisible(int line, Scope scope) const { } } -Range LineLayout::SubLineRange(int subLine, Scope scope) const { +Range LineLayout::SubLineRange(int subLine, Scope scope) const noexcept { return Range(LineStart(subLine), LineLastVisible(subLine, scope)); } -bool LineLayout::InLine(int offset, int line) const { +bool LineLayout::InLine(int offset, int line) const noexcept { return ((offset >= LineStart(line)) && (offset < LineStart(line + 1))) || ((offset == numCharsInLine) && (line == (lines-1))); } void LineLayout::SetLineStart(int line, int start) { if ((line >= lenLineStarts) && (line != 0)) { - int newMaxLines = line + 20; - int *newLineStarts = new int[newMaxLines]; + const int newMaxLines = line + 20; + std::unique_ptr newLineStarts = Sci::make_unique(newMaxLines); for (int i = 0; i < newMaxLines; i++) { if (i < lenLineStarts) newLineStarts[i] = lineStarts[i]; else newLineStarts[i] = 0; } - lineStarts.reset(newLineStarts); + lineStarts = std::move(newLineStarts); lenLineStarts = newMaxLines; } lineStarts[line] = start; @@ -178,7 +178,7 @@ void LineLayout::RestoreBracesHighlight(Range rangeLine, const Sci::Position bra xHighlightGuide = 0; } -int LineLayout::FindBefore(XYPOSITION x, Range range) const { +int LineLayout::FindBefore(XYPOSITION x, Range range) const noexcept { Sci::Position lower = range.start; Sci::Position upper = range.end; do { @@ -194,7 +194,7 @@ int LineLayout::FindBefore(XYPOSITION x, Range range) const { } -int LineLayout::FindPositionFromX(XYPOSITION x, Range range, bool charPosition) const { +int LineLayout::FindPositionFromX(XYPOSITION x, Range range, bool charPosition) const noexcept { int pos = FindBefore(x, range); while (pos < range.end) { if (charPosition) { @@ -211,7 +211,7 @@ int LineLayout::FindPositionFromX(XYPOSITION x, Range range, bool charPosition) return static_cast(range.end); } -Point LineLayout::PointFromPosition(int posInLine, int lineHeight, PointEnd pe) const { +Point LineLayout::PointFromPosition(int posInLine, int lineHeight, PointEnd pe) const noexcept { Point pt; // In case of very long line put x at arbitrary large position if (posInLine > maxLineLength) { @@ -240,7 +240,7 @@ Point LineLayout::PointFromPosition(int posInLine, int lineHeight, PointEnd pe) return pt; } -int LineLayout::EndLineStyle() const { +int LineLayout::EndLineStyle() const noexcept { return styles[numCharsBeforeEOL > 0 ? numCharsBeforeEOL-1 : 0]; } @@ -289,14 +289,14 @@ void LineLayoutCache::Deallocate() noexcept { cache.clear(); } -void LineLayoutCache::Invalidate(LineLayout::validLevel validity_) { +void LineLayoutCache::Invalidate(LineLayout::ValidLevel validity_) noexcept { if (!cache.empty() && !allInvalidated) { for (const std::unique_ptr &ll : cache) { if (ll) { ll->Invalidate(validity_); } } - if (validity_ == LineLayout::llInvalid) { + if (validity_ == LineLayout::ValidLevel::invalid) { allInvalidated = true; } } @@ -314,7 +314,7 @@ LineLayout *LineLayoutCache::Retrieve(Sci::Line lineNumber, Sci::Line lineCaret, Sci::Line linesOnScreen, Sci::Line linesInDoc) { AllocateForLevel(linesOnScreen, linesInDoc); if (styleClock != styleClock_) { - Invalidate(LineLayout::llCheckTextAndStyle); + Invalidate(LineLayout::ValidLevel::checkTextAndStyle); styleClock = styleClock_; } allInvalidated = false; @@ -341,7 +341,7 @@ LineLayout *LineLayoutCache::Retrieve(Sci::Line lineNumber, Sci::Line lineCaret, } } if (!cache[pos]) { - cache[pos].reset(new LineLayout(maxChars)); + cache[pos] = Sci::make_unique(maxChars); } cache[pos]->lineNumber = lineNumber; cache[pos]->inCache = true; @@ -370,7 +370,7 @@ void LineLayoutCache::Dispose(LineLayout *ll) noexcept { } // Simply pack the (maximum 4) character bytes into an int -static unsigned int KeyFromString(const char *charBytes, size_t len) { +static unsigned int KeyFromString(const char *charBytes, size_t len) noexcept { PLATFORM_ASSERT(len <= 4); unsigned int k=0; for (size_t i=0; i(&ll->chars[nextBreak]), static_cast(lineRange.end - nextBreak)); - else if (encodingFamily == efDBCS) + else if (encodingFamily == EncodingFamily::dbcs) charWidth = pdoc->DBCSDrawBytes( &ll->chars[nextBreak], static_cast(lineRange.end - nextBreak)); const Representation *repr = preprs->RepresentationFromCharacter(&ll->chars[nextBreak], charWidth); @@ -570,7 +570,7 @@ PositionCacheEntry::PositionCacheEntry(const PositionCacheEntry &other) : styleNumber(other.styleNumber), len(other.styleNumber), clock(other.styleNumber), positions(nullptr) { if (other.positions) { const size_t lenData = len + (len / sizeof(XYPOSITION)) + 1; - positions.reset(new XYPOSITION[lenData]); + positions = Sci::make_unique(lenData); memcpy(positions.get(), other.positions.get(), lenData * sizeof(XYPOSITION)); } } @@ -582,7 +582,7 @@ void PositionCacheEntry::Set(unsigned int styleNumber_, const char *s_, len = len_; clock = clock_; if (s_ && positions_) { - positions.reset(new XYPOSITION[len + (len / sizeof(XYPOSITION)) + 1]); + positions = Sci::make_unique(len + (len / sizeof(XYPOSITION)) + 1); for (unsigned int i=0; i BreakFinder::lengthStartSubdivision) { // Break up into segments unsigned int startSegment = 0; XYPOSITION xStartSegment = 0; while (startSegment < len) { const unsigned int lenSegment = pdoc->SafeSegment(s + startSegment, len - startSegment, BreakFinder::lengthEachSubdivision); - FontAlias fontStyle = vstyle.styles[styleNumber].font; surface->MeasureWidths(fontStyle, s + startSegment, lenSegment, positions + startSegment); for (unsigned int inSeg = 0; inSeg < lenSegment; inSeg++) { positions[startSegment + inSeg] += xStartSegment; @@ -701,7 +701,6 @@ void PositionCache::MeasureWidths(Surface *surface, const ViewStyle &vstyle, uns startSegment += lenSegment; } } else { - FontAlias fontStyle = vstyle.styles[styleNumber].font; surface->MeasureWidths(fontStyle, s, len, positions); } if (probe < pces.size()) { diff --git a/scintilla/src/PositionCache.h b/scintilla/src/PositionCache.h index 6899ba99f7..9647255d6f 100644 --- a/scintilla/src/PositionCache.h +++ b/scintilla/src/PositionCache.h @@ -60,7 +60,7 @@ class LineLayout { int maxLineLength; int numCharsInLine; int numCharsBeforeEOL; - enum validLevel { llInvalid, llCheckTextAndStyle, llPositions, llLines } validity; + enum class ValidLevel { invalid, checkTextAndStyle, positions, lines } validity; int xHighlightGuide; bool highlightColumn; bool containsCaret; @@ -87,20 +87,21 @@ class LineLayout { virtual ~LineLayout(); void Resize(int maxLineLength_); void Free() noexcept; - void Invalidate(validLevel validity_); - int LineStart(int line) const; + void Invalidate(ValidLevel validity_) noexcept; + int LineStart(int line) const noexcept; + int LineLength(int line) const noexcept; enum class Scope { visibleOnly, includeEnd }; - int LineLastVisible(int line, Scope scope) const; - Range SubLineRange(int subLine, Scope scope) const; - bool InLine(int offset, int line) const; + int LineLastVisible(int line, Scope scope) const noexcept; + Range SubLineRange(int subLine, Scope scope) const noexcept; + bool InLine(int offset, int line) const noexcept; void SetLineStart(int line, int start); void SetBracesHighlight(Range rangeLine, const Sci::Position braces[], char bracesMatchStyle, int xHighlight, bool ignoreStyle); void RestoreBracesHighlight(Range rangeLine, const Sci::Position braces[], bool ignoreStyle); - int FindBefore(XYPOSITION x, Range range) const; - int FindPositionFromX(XYPOSITION x, Range range, bool charPosition) const; - Point PointFromPosition(int posInLine, int lineHeight, PointEnd pe) const; - int EndLineStyle() const; + int FindBefore(XYPOSITION x, Range range) const noexcept; + int FindPositionFromX(XYPOSITION x, Range range, bool charPosition) const noexcept; + Point PointFromPosition(int posInLine, int lineHeight, PointEnd pe) const noexcept; + int EndLineStyle() const noexcept; }; /** @@ -128,7 +129,7 @@ class LineLayoutCache { llcPage=SC_CACHE_PAGE, llcDocument=SC_CACHE_DOCUMENT }; - void Invalidate(LineLayout::validLevel validity_); + void Invalidate(LineLayout::ValidLevel validity_) noexcept; void SetLevel(int level_) noexcept; int GetLevel() const noexcept { return level; } LineLayout *Retrieve(Sci::Line lineNumber, Sci::Line lineCaret, int maxChars, int styleClock_, @@ -152,7 +153,7 @@ class PositionCacheEntry { ~PositionCacheEntry(); void Set(unsigned int styleNumber_, const char *s_, unsigned int len_, const XYPOSITION *positions_, unsigned int clock_); void Clear() noexcept; - bool Retrieve(unsigned int styleNumber_, const char *s_, unsigned int len_, XYPOSITION *positions_) const; + bool Retrieve(unsigned int styleNumber_, const char *s_, unsigned int len_, XYPOSITION *positions_) const noexcept; static unsigned int Hash(unsigned int styleNumber_, const char *s, unsigned int len_) noexcept; bool NewerThan(const PositionCacheEntry &other) const noexcept; void ResetClock() noexcept; @@ -171,7 +172,7 @@ class SpecialRepresentations { MapRepresentation mapReprs; short startByteHasReprs[0x100]; public: - SpecialRepresentations() noexcept; + SpecialRepresentations(); void SetRepresentation(const char *charBytes, const char *value); void ClearRepresentation(const char *charBytes); const Representation *RepresentationFromCharacter(const char *charBytes, size_t len) const; diff --git a/scintilla/src/RESearch.cxx b/scintilla/src/RESearch.cxx index 5ce073a449..a682016bc8 100644 --- a/scintilla/src/RESearch.cxx +++ b/scintilla/src/RESearch.cxx @@ -139,7 +139,7 @@ * W: any char except alphanumeric & underscore (see above) * * [12] \xHH a backslash followed by x and two hexa digits, - * becomes the character whose Ascii code is equal + * becomes the character whose ASCII code is equal * to these digits. If not followed by two digits, * it is 'x' char itself. * @@ -256,7 +256,7 @@ RESearch::RESearch(CharClassify *charClassTable) { charClass = charClassTable; sta = NOP; /* status of lastpat */ bol = 0; - const unsigned char nul=0; + constexpr unsigned char nul = 0; std::fill(bittab, std::end(bittab), nul); std::fill(tagstk, std::end(tagstk), 0); std::fill(nfa, std::end(nfa), '\0'); @@ -267,7 +267,7 @@ RESearch::~RESearch() { Clear(); } -void RESearch::Clear() { +void RESearch::Clear() noexcept { for (int i = 0; i < MAXTAG; i++) { pat[i].clear(); bopat[i] = NOTFOUND; @@ -278,7 +278,7 @@ void RESearch::Clear() { void RESearch::GrabMatches(const CharacterIndexer &ci) { for (unsigned int i = 0; i < MAXTAG; i++) { if ((bopat[i] != NOTFOUND) && (eopat[i] != NOTFOUND)) { - Sci::Position len = eopat[i] - bopat[i]; + const Sci::Position len = eopat[i] - bopat[i]; pat[i].resize(len); for (Sci::Position j = 0; j < len; j++) pat[i][j] = ci.CharAt(bopat[i] + j); @@ -286,11 +286,11 @@ void RESearch::GrabMatches(const CharacterIndexer &ci) { } } -void RESearch::ChSet(unsigned char c) { +void RESearch::ChSet(unsigned char c) noexcept { bittab[((c) & BLKIND) >> 3] |= bitarr[(c) & BITIND]; } -void RESearch::ChSetWithCase(unsigned char c, bool caseSensitive) { +void RESearch::ChSetWithCase(unsigned char c, bool caseSensitive) noexcept { ChSet(c); if (!caseSensitive) { if ((c >= 'a') && (c <= 'z')) { @@ -301,7 +301,7 @@ void RESearch::ChSetWithCase(unsigned char c, bool caseSensitive) { } } -static unsigned char escapeValue(unsigned char ch) { +static unsigned char escapeValue(unsigned char ch) noexcept { switch (ch) { case 'a': return '\a'; case 'b': return '\b'; @@ -314,7 +314,7 @@ static unsigned char escapeValue(unsigned char ch) { return 0; } -static int GetHexaChar(unsigned char hd1, unsigned char hd2) { +static int GetHexaChar(unsigned char hd1, unsigned char hd2) noexcept { int hexValue = 0; if (hd1 >= '0' && hd1 <= '9') { hexValue += 16 * (hd1 - '0'); @@ -347,10 +347,10 @@ static int GetHexaChar(unsigned char hd1, unsigned char hd2) { */ int RESearch::GetBackslashExpression( const char *pattern, - int &incr) { + int &incr) noexcept { // Since error reporting is primitive and messages are not used anyway, // I choose to interpret unexpected syntax in a logical way instead - // of reporting errors. Otherwise, we can stick on, eg., PCRE behavior. + // of reporting errors. Otherwise, we can stick on, eg., PCRE behaviour. incr = 0; // Most of the time, will skip the char "naturally". int c; int result = -1; @@ -430,7 +430,7 @@ int RESearch::GetBackslashExpression( return result; } -const char *RESearch::Compile(const char *pattern, Sci::Position length, bool caseSensitive, bool posix) { +const char *RESearch::Compile(const char *pattern, Sci::Position length, bool caseSensitive, bool posix) noexcept { char *mp=nfa; /* nfa pointer */ char *lp; /* saved pointer */ char *sp=nfa; /* another one */ @@ -556,7 +556,7 @@ const char *RESearch::Compile(const char *pattern, Sci::Position length, bool ca i++; p++; int incr; - int c = GetBackslashExpression(p, incr); + const int c = GetBackslashExpression(p, incr); i += incr; p += incr; if (c >= 0) { @@ -831,7 +831,7 @@ int RESearch::Execute(const CharacterIndexer &ci, Sci::Position lp, Sci::Positio extern void re_fail(char *,char); -static inline int isinset(const char *ap, unsigned char c) { +static inline int isinset(const char *ap, unsigned char c) noexcept { return ap[(c & BLKIND) >> 3] & bitarr[c & BITIND]; } diff --git a/scintilla/src/RESearch.h b/scintilla/src/RESearch.h index 213055daca..49bfc05414 100644 --- a/scintilla/src/RESearch.h +++ b/scintilla/src/RESearch.h @@ -24,13 +24,13 @@ class RESearch { explicit RESearch(CharClassify *charClassTable); // No dynamic allocation so default copy constructor and assignment operator are OK. ~RESearch(); - void Clear(); + void Clear() noexcept; void GrabMatches(const CharacterIndexer &ci); - const char *Compile(const char *pattern, Sci::Position length, bool caseSensitive, bool posix); + const char *Compile(const char *pattern, Sci::Position length, bool caseSensitive, bool posix) noexcept; int Execute(const CharacterIndexer &ci, Sci::Position lp, Sci::Position endp); - enum { MAXTAG=10 }; - enum { NOTFOUND=-1 }; + static constexpr int MAXTAG = 10; + static constexpr int NOTFOUND = -1; Sci::Position bopat[MAXTAG]; Sci::Position eopat[MAXTAG]; @@ -38,16 +38,16 @@ class RESearch { private: - enum { MAXNFA = 4096 }; - // The following enums are not meant to be changeable. + static constexpr int MAXNFA = 4096; + // The following constants are not meant to be changeable. // They are for readability only. - enum { MAXCHR = 256 }; - enum { CHRBIT = 8 }; - enum { BITBLK = MAXCHR / CHRBIT }; + static constexpr int MAXCHR = 256; + static constexpr int CHRBIT = 8; + static constexpr int BITBLK = MAXCHR / CHRBIT; - void ChSet(unsigned char c); - void ChSetWithCase(unsigned char c, bool caseSensitive); - int GetBackslashExpression(const char *pattern, int &incr); + void ChSet(unsigned char c) noexcept; + void ChSetWithCase(unsigned char c, bool caseSensitive) noexcept; + int GetBackslashExpression(const char *pattern, int &incr) noexcept; Sci::Position PMatch(const CharacterIndexer &ci, Sci::Position lp, Sci::Position endp, char *ap); @@ -58,7 +58,7 @@ class RESearch { unsigned char bittab[BITBLK]; /* bit table for CCL pre-set bits */ int failure; CharClassify *charClass; - bool iswordc(unsigned char x) const { + bool iswordc(unsigned char x) const noexcept { return charClass->IsWord(x); } }; diff --git a/scintilla/src/RunStyles.cxx b/scintilla/src/RunStyles.cxx index 115f51a9a7..da000e69df 100644 --- a/scintilla/src/RunStyles.cxx +++ b/scintilla/src/RunStyles.cxx @@ -78,8 +78,8 @@ void RunStyles::RemoveRunIfSameAsPrevious(DISTANCE run) { template RunStyles::RunStyles() { - starts.reset(new Partitioning(8)); - styles.reset(new SplitVector