Branch: refs/heads/master Author: Jiří Techet techet@gmail.com Committer: Jiří Techet techet@gmail.com Date: Fri, 20 Dec 2024 21:39:09 UTC Commit: 68b6a36f9d0f692cb40806ebce3e9ed9e49251f2 https://github.com/geany/geany/commit/68b6a36f9d0f692cb40806ebce3e9ed9e49251...
Log Message: ----------- Update to Scintilla 5.5.4 and Lexilla 5.4.2
Modified Paths: -------------- meson.build scintilla/Makefile.am scintilla/gtk/PlatGTK.cxx scintilla/gtk/ScintillaGTK.cxx scintilla/gtk/ScintillaGTK.h scintilla/include/ILoader.h scintilla/include/Scintilla.h scintilla/include/Scintilla.iface scintilla/include/ScintillaCall.h scintilla/include/ScintillaMessages.h scintilla/include/ScintillaTypes.h scintilla/lexilla/include/Lexilla.h scintilla/lexilla/include/SciLexer.h scintilla/lexilla/lexers/LexAU3.cxx scintilla/lexilla/lexers/LexAbaqus.cxx scintilla/lexilla/lexers/LexAda.cxx scintilla/lexilla/lexers/LexAsciidoc.cxx scintilla/lexilla/lexers/LexAsm.cxx scintilla/lexilla/lexers/LexBash.cxx scintilla/lexilla/lexers/LexBasic.cxx scintilla/lexilla/lexers/LexBatch.cxx scintilla/lexilla/lexers/LexCIL.cxx scintilla/lexilla/lexers/LexCOBOL.cxx scintilla/lexilla/lexers/LexCPP.cxx scintilla/lexilla/lexers/LexCSS.cxx scintilla/lexilla/lexers/LexCaml.cxx scintilla/lexilla/lexers/LexCmake.cxx scintilla/lexilla/lexers/LexCoffeeScript.cxx scintilla/lexilla/lexers/LexD.cxx scintilla/lexilla/lexers/LexDart.cxx scintilla/lexilla/lexers/LexDiff.cxx scintilla/lexilla/lexers/LexErlang.cxx scintilla/lexilla/lexers/LexForth.cxx scintilla/lexilla/lexers/LexFortran.cxx scintilla/lexilla/lexers/LexGDScript.cxx scintilla/lexilla/lexers/LexHTML.cxx scintilla/lexilla/lexers/LexHaskell.cxx scintilla/lexilla/lexers/LexJulia.cxx scintilla/lexilla/lexers/LexLaTeX.cxx scintilla/lexilla/lexers/LexLisp.cxx scintilla/lexilla/lexers/LexLua.cxx scintilla/lexilla/lexers/LexMake.cxx scintilla/lexilla/lexers/LexMarkdown.cxx scintilla/lexilla/lexers/LexMatlab.cxx scintilla/lexilla/lexers/LexNim.cxx scintilla/lexilla/lexers/LexNsis.cxx scintilla/lexilla/lexers/LexNull.cxx scintilla/lexilla/lexers/LexPO.cxx scintilla/lexilla/lexers/LexPascal.cxx scintilla/lexilla/lexers/LexPerl.cxx scintilla/lexilla/lexers/LexPowerShell.cxx scintilla/lexilla/lexers/LexProps.cxx scintilla/lexilla/lexers/LexPython.cxx scintilla/lexilla/lexers/LexR.cxx scintilla/lexilla/lexers/LexRaku.cxx scintilla/lexilla/lexers/LexRuby.cxx scintilla/lexilla/lexers/LexRust.cxx scintilla/lexilla/lexers/LexSQL.cxx scintilla/lexilla/lexers/LexSmalltalk.cxx scintilla/lexilla/lexers/LexTCL.cxx scintilla/lexilla/lexers/LexTxt2tags.cxx scintilla/lexilla/lexers/LexVHDL.cxx scintilla/lexilla/lexers/LexVerilog.cxx scintilla/lexilla/lexers/LexVisualProlog.cxx scintilla/lexilla/lexers/LexYAML.cxx scintilla/lexilla/lexers/LexZig.cxx scintilla/lexilla/lexlib/CatalogueModules.h scintilla/lexilla/lexlib/CharacterCategory.cxx scintilla/lexilla/lexlib/CharacterCategory.h scintilla/lexilla/lexlib/CharacterSet.cxx scintilla/lexilla/lexlib/CharacterSet.h scintilla/lexilla/lexlib/InList.cxx scintilla/lexilla/lexlib/InList.h scintilla/lexilla/lexlib/LexAccessor.cxx scintilla/lexilla/lexlib/LexAccessor.h scintilla/lexilla/lexlib/LexerSimple.cxx scintilla/lexilla/lexlib/LexerSimple.h scintilla/lexilla/lexlib/OptionSet.h scintilla/lexilla/lexlib/SparseState.h scintilla/lexilla/lexlib/StyleContext.cxx scintilla/lexilla/lexlib/StyleContext.h scintilla/lexilla/lexlib/SubStyles.h scintilla/lexilla/lexlib/WordList.cxx scintilla/lexilla/lexlib/WordList.h scintilla/lexilla/src/Lexilla.cxx scintilla/lexilla/version.txt scintilla/src/AutoComplete.cxx scintilla/src/AutoComplete.h scintilla/src/CallTip.cxx scintilla/src/CallTip.h scintilla/src/CellBuffer.cxx scintilla/src/CellBuffer.h scintilla/src/ChangeHistory.cxx scintilla/src/ChangeHistory.h scintilla/src/CharacterCategoryMap.cxx scintilla/src/CharacterCategoryMap.h scintilla/src/Decoration.cxx scintilla/src/Document.cxx scintilla/src/Document.h scintilla/src/EditModel.cxx scintilla/src/EditModel.h scintilla/src/EditView.cxx scintilla/src/Editor.cxx scintilla/src/Editor.h scintilla/src/Geometry.h scintilla/src/Indicator.cxx scintilla/src/Indicator.h scintilla/src/KeyMap.cxx scintilla/src/LineMarker.cxx scintilla/src/LineMarker.h scintilla/src/MarginView.cxx scintilla/src/Partitioning.h scintilla/src/PerLine.cxx scintilla/src/Platform.h scintilla/src/PositionCache.cxx scintilla/src/PositionCache.h scintilla/src/RESearch.cxx scintilla/src/RESearch.h scintilla/src/RunStyles.cxx scintilla/src/ScintillaBase.cxx scintilla/src/ScintillaBase.h scintilla/src/Selection.cxx scintilla/src/Selection.h scintilla/src/SparseVector.h scintilla/src/Style.cxx scintilla/src/Style.h scintilla/src/UndoHistory.cxx scintilla/src/UndoHistory.h scintilla/src/UniConversion.cxx scintilla/src/UniConversion.h scintilla/src/ViewStyle.cxx scintilla/src/ViewStyle.h scintilla/src/XPM.cxx scintilla/version.txt
Modified: meson.build 4 lines changed, 4 insertions(+), 0 deletions(-) =================================================================== @@ -305,6 +305,8 @@ lexilla = static_library('lexilla', 'scintilla/lexilla/lexlib/CharacterSet.h', 'scintilla/lexilla/lexlib/DefaultLexer.cxx', 'scintilla/lexilla/lexlib/DefaultLexer.h', + 'scintilla/lexilla/lexlib/InList.cxx', + 'scintilla/lexilla/lexlib/InList.h', 'scintilla/lexilla/lexlib/LexAccessor.cxx', 'scintilla/lexilla/lexlib/LexAccessor.h', 'scintilla/lexilla/lexlib/LexerBase.cxx', @@ -421,6 +423,8 @@ scintilla = static_library('scintilla', 'scintilla/src/SplitVector.h', 'scintilla/src/Style.cxx', 'scintilla/src/Style.h', + 'scintilla/src/UndoHistory.cxx', + 'scintilla/src/UndoHistory.h', 'scintilla/src/UniConversion.cxx', 'scintilla/src/UniConversion.h', 'scintilla/src/UniqueString.cxx',
Modified: scintilla/Makefile.am 4 lines changed, 4 insertions(+), 0 deletions(-) =================================================================== @@ -79,6 +79,8 @@ lexilla/lexlib/CharacterSet.cxx \ lexilla/lexlib/CharacterSet.h \ lexilla/lexlib/DefaultLexer.cxx \ lexilla/lexlib/DefaultLexer.h \ +lexilla/lexlib/InList.cxx \ +lexilla/lexlib/InList.h \ lexilla/lexlib/LexAccessor.cxx \ lexilla/lexlib/LexAccessor.h \ lexilla/lexlib/LexerBase.cxx \ @@ -182,6 +184,8 @@ src/SparseVector.h \ src/SplitVector.h \ src/Style.cxx \ src/Style.h \ +src/UndoHistory.cxx \ +src/UndoHistory.h \ src/UniConversion.cxx \ src/UniConversion.h \ src/UniqueString.cxx \
Modified: scintilla/gtk/PlatGTK.cxx 30 lines changed, 28 insertions(+), 2 deletions(-) =================================================================== @@ -5,6 +5,7 @@
#include <cstddef> #include <cstdlib> +#include <cstdint> #include <cstring> #include <cstdio> #include <cmath> @@ -36,6 +37,7 @@
#include "Scintilla.h" #include "ScintillaWidget.h" +#include "CharacterType.h" #include "XPM.h" #include "UniConversion.h"
@@ -99,6 +101,8 @@ class FontHandle : public Font { pango_font_description_set_size(fd.get(), pango_units_from_double(fp.size)); pango_font_description_set_weight(fd.get(), static_cast<PangoWeight>(fp.weight)); pango_font_description_set_style(fd.get(), fp.italic ? PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL); + pango_font_description_set_stretch(fd.get(), + static_cast<PangoStretch>(static_cast<int>(fp.stretch)-1)); } } ~FontHandle() override = default; @@ -1085,6 +1089,27 @@ void SurfaceImpl::MeasureWidthsUTF8(const Font *font_, std::string_view text, XY } while (!iti.finished) { iti.Next(); + if (iti.curIndex < i) { + // Backwards movement indicater bidirectional. + // Divide into ASCII prefix and non-ASCII suffix as this is common case + // and produces accurate positions for the ASCII prefix. + size_t lenASCII=0; + while (lenASCII<text.length() && IsASCII(text[lenASCII])) { + lenASCII++; + } + const std::string_view asciiPrefix = text.substr(0, lenASCII); + const std::string_view bidiSuffix = text.substr(lenASCII); + // Recurse for ASCII prefix. + MeasureWidthsUTF8(font_, asciiPrefix, positions); + // Measure the whole bidiSuffix and spread its width evenly + const XYPOSITION endASCII = positions[lenASCII-1]; + const XYPOSITION widthBidi = WidthText(font_, bidiSuffix); + const XYPOSITION widthByteBidi = widthBidi / bidiSuffix.length(); + for (size_t bidiPos=0; bidiPos<bidiSuffix.length(); bidiPos++) { + positions[bidiPos+lenASCII] = endASCII + widthByteBidi * (bidiPos + 1); + } + return; + } const int places = iti.curIndex - i; while (i < iti.curIndex) { // Evenly distribute space among bytes of this cluster. @@ -1331,7 +1356,8 @@ void Window::SetCursor(Cursor curs) {
if (WindowFromWidget(PWidget(wid))) gdk_window_set_cursor(WindowFromWidget(PWidget(wid)), gdkCurs); - UnRefCursor(gdkCurs); + if (gdkCurs) + UnRefCursor(gdkCurs); }
/* Returns rectangle of monitor pt is on, both rect and pt are in Window's @@ -2149,7 +2175,7 @@ ColourRGBA Platform::Chrome() { }
ColourRGBA Platform::ChromeHighlight() { - return ColourRGBA(0xff, 0xff, 0xff); + return white; }
const char *Platform::DefaultFont() {
Modified: scintilla/gtk/ScintillaGTK.cxx 14 lines changed, 7 insertions(+), 7 deletions(-) =================================================================== @@ -704,10 +704,11 @@ void ScintillaGTK::Init() { timers[tr].reason = static_cast<TickReason>(tr); timers[tr].scintilla = this; } - vs.indicators[SC_INDICATOR_UNKNOWN] = Indicator(IndicatorStyle::Hidden, ColourRGBA(0, 0, 0xff)); - vs.indicators[SC_INDICATOR_INPUT] = Indicator(IndicatorStyle::Dots, ColourRGBA(0, 0, 0xff)); - vs.indicators[SC_INDICATOR_CONVERTED] = Indicator(IndicatorStyle::CompositionThick, ColourRGBA(0, 0, 0xff)); - vs.indicators[SC_INDICATOR_TARGET] = Indicator(IndicatorStyle::StraightBox, ColourRGBA(0, 0, 0xff)); + + vs.indicators[SC_INDICATOR_UNKNOWN] = Indicator(IndicatorStyle::Hidden, colourIME); + vs.indicators[SC_INDICATOR_INPUT] = Indicator(IndicatorStyle::Dots, colourIME); + vs.indicators[SC_INDICATOR_CONVERTED] = Indicator(IndicatorStyle::CompositionThick, colourIME); + vs.indicators[SC_INDICATOR_TARGET] = Indicator(IndicatorStyle::StraightBox, colourIME);
fontOptionsPrevious = FontOptions(PWidget(wText)); } @@ -1501,8 +1502,8 @@ void ScintillaGTK::PrimaryClearSelection(GtkClipboard *clip, gpointer pSci) { void ScintillaGTK::ClaimSelection() { // X Windows has a 'primary selection' as well as the clipboard. // Whenever the user selects some text, we become the primary selection - ClearPrimarySelection(); if (!sel.Empty()) { + ClearPrimarySelection(); if (gtk_clipboard_set_with_data( gtk_clipboard_get(GDK_SELECTION_PRIMARY), clipboardCopyTargets, nClipboardCopyTargets, @@ -2378,8 +2379,7 @@ void ScintillaGTK::MoveImeCarets(Sci::Position pos) { // Move carets relatively by bytes for (size_t r=0; r<sel.Count(); r++) { const Sci::Position positionInsert = sel.Range(r).Start().Position(); - sel.Range(r).caret.SetPosition(positionInsert + pos); - sel.Range(r).anchor.SetPosition(positionInsert + pos); + sel.Range(r) = SelectionRange(positionInsert + pos); } }
Modified: scintilla/gtk/ScintillaGTK.h 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -293,7 +293,7 @@ class ScintillaGTK : public ScintillaBase { class GObjectWatcher { GObject *weakRef;
- void WeakNotifyThis(GObject *obj G_GNUC_UNUSED) { + void WeakNotifyThis([[maybe_unused]] GObject *obj) { PLATFORM_ASSERT(obj == weakRef);
Destroyed();
Modified: scintilla/include/ILoader.h 13 lines changed, 13 insertions(+), 0 deletions(-) =================================================================== @@ -1,6 +1,7 @@ // Scintilla source code edit control /** @file ILoader.h ** Interface for loading into a Scintilla document from a background thread. + ** Interface for manipulating a document without a view. **/ // Copyright 1998-2017 by Neil Hodgson neilh@scintilla.org // The License.txt file describes the conditions under which this software may be distributed. @@ -20,6 +21,18 @@ class ILoader { virtual void * SCI_METHOD ConvertToDocument() = 0; };
+static constexpr int deRelease0 = 0; + +class IDocumentEditable { +public: + // Allow this interface to add methods over time and discover whether new methods available. + virtual int SCI_METHOD DEVersion() const noexcept = 0; + + // Lifetime control + virtual int SCI_METHOD AddRef() noexcept = 0; + virtual int SCI_METHOD Release() = 0; +}; + }
#endif
Modified: scintilla/include/Scintilla.h 42 lines changed, 41 insertions(+), 1 deletions(-) =================================================================== @@ -166,6 +166,7 @@ typedef sptr_t (*SciFnDirectStatus)(sptr_t ptr, unsigned int iMessage, uptr_t wP #define SC_MARKNUM_FOLDERSUB 29 #define SC_MARKNUM_FOLDER 30 #define SC_MARKNUM_FOLDEROPEN 31 +#define SC_MASK_HISTORY 0x01E00000 #define SC_MASK_FOLDERS 0xFE000000 #define SCI_MARKERDEFINE 2040 #define SCI_MARKERSETFORE 2041 @@ -281,6 +282,17 @@ typedef sptr_t (*SciFnDirectStatus)(sptr_t ptr, unsigned int iMessage, uptr_t wP #define SCI_STYLESETHOTSPOT 2409 #define SCI_STYLESETCHECKMONOSPACED 2254 #define SCI_STYLEGETCHECKMONOSPACED 2255 +#define SC_STRETCH_ULTRA_CONDENSED 1 +#define SC_STRETCH_EXTRA_CONDENSED 2 +#define SC_STRETCH_CONDENSED 3 +#define SC_STRETCH_SEMI_CONDENSED 4 +#define SC_STRETCH_NORMAL 5 +#define SC_STRETCH_SEMI_EXPANDED 6 +#define SC_STRETCH_EXPANDED 7 +#define SC_STRETCH_EXTRA_EXPANDED 8 +#define SC_STRETCH_ULTRA_EXPANDED 9 +#define SCI_STYLESETSTRETCH 2258 +#define SCI_STYLEGETSTRETCH 2259 #define SCI_STYLESETINVISIBLEREPRESENTATION 2256 #define SCI_STYLEGETINVISIBLEREPRESENTATION 2257 #define SC_ELEMENT_LIST 0 @@ -295,6 +307,8 @@ typedef sptr_t (*SciFnDirectStatus)(sptr_t ptr, unsigned int iMessage, uptr_t wP #define SC_ELEMENT_SELECTION_SECONDARY_BACK 15 #define SC_ELEMENT_SELECTION_INACTIVE_TEXT 16 #define SC_ELEMENT_SELECTION_INACTIVE_BACK 17 +#define SC_ELEMENT_SELECTION_INACTIVE_ADDITIONAL_TEXT 18 +#define SC_ELEMENT_SELECTION_INACTIVE_ADDITIONAL_BACK 19 #define SC_ELEMENT_CARET 40 #define SC_ELEMENT_CARET_ADDITIONAL 41 #define SC_ELEMENT_CARET_LINE_BACK 50 @@ -339,6 +353,21 @@ typedef sptr_t (*SciFnDirectStatus)(sptr_t ptr, unsigned int iMessage, uptr_t wP #define SCI_GETCHARACTERCATEGORYOPTIMIZATION 2721 #define SCI_BEGINUNDOACTION 2078 #define SCI_ENDUNDOACTION 2079 +#define SCI_GETUNDOSEQUENCE 2799 +#define SCI_GETUNDOACTIONS 2790 +#define SCI_SETUNDOSAVEPOINT 2791 +#define SCI_GETUNDOSAVEPOINT 2792 +#define SCI_SETUNDODETACH 2793 +#define SCI_GETUNDODETACH 2794 +#define SCI_SETUNDOTENTATIVE 2795 +#define SCI_GETUNDOTENTATIVE 2796 +#define SCI_SETUNDOCURRENT 2797 +#define SCI_GETUNDOCURRENT 2798 +#define SCI_PUSHUNDOACTIONTYPE 2800 +#define SCI_CHANGELASTUNDOACTIONTEXT 2801 +#define SCI_GETUNDOACTIONTYPE 2802 +#define SCI_GETUNDOACTIONPOSITION 2803 +#define SCI_GETUNDOACTIONTEXT 2804 #define INDIC_PLAIN 0 #define INDIC_SQUIGGLE 1 #define INDIC_TT 2 @@ -431,6 +460,7 @@ typedef sptr_t (*SciFnDirectStatus)(sptr_t ptr, unsigned int iMessage, uptr_t wP #define SCI_AUTOCGETAUTOHIDE 2119 #define SC_AUTOCOMPLETE_NORMAL 0 #define SC_AUTOCOMPLETE_FIXED_SIZE 1 +#define SC_AUTOCOMPLETE_SELECT_FIRST_ITEM 2 #define SCI_AUTOCSETOPTIONS 2638 #define SCI_AUTOCGETOPTIONS 2639 #define SCI_AUTOCSETDROPRESTOFWORD 2270 @@ -443,6 +473,8 @@ typedef sptr_t (*SciFnDirectStatus)(sptr_t ptr, unsigned int iMessage, uptr_t wP #define SCI_AUTOCGETMAXWIDTH 2209 #define SCI_AUTOCSETMAXHEIGHT 2210 #define SCI_AUTOCGETMAXHEIGHT 2211 +#define SCI_AUTOCSETSTYLE 2109 +#define SCI_AUTOCGETSTYLE 2120 #define SCI_SETINDENT 2122 #define SCI_GETINDENT 2123 #define SCI_SETUSETABS 2124 @@ -735,7 +767,9 @@ typedef sptr_t (*SciFnDirectStatus)(sptr_t ptr, unsigned int iMessage, uptr_t wP #define SCI_CANCEL 2325 #define SCI_DELETEBACK 2326 #define SCI_TAB 2327 +#define SCI_LINEINDENT 2813 #define SCI_BACKTAB 2328 +#define SCI_LINEDEDENT 2814 #define SCI_NEWLINE 2329 #define SCI_FORMFEED 2330 #define SCI_VCHOME 2331 @@ -874,7 +908,9 @@ typedef sptr_t (*SciFnDirectStatus)(sptr_t ptr, unsigned int iMessage, uptr_t wP #define SC_SEL_LINES 2 #define SC_SEL_THIN 3 #define SCI_SETSELECTIONMODE 2422 +#define SCI_CHANGESELECTIONMODE 2659 #define SCI_GETSELECTIONMODE 2423 +#define SCI_SETMOVEEXTENDSSELECTION 2719 #define SCI_GETMOVEEXTENDSSELECTION 2706 #define SCI_GETLINESELSTARTPOSITION 2424 #define SCI_GETLINESELENDPOSITION 2425 @@ -957,6 +993,9 @@ typedef sptr_t (*SciFnDirectStatus)(sptr_t ptr, unsigned int iMessage, uptr_t wP #define SCI_SETLAYOUTTHREADS 2775 #define SCI_GETLAYOUTTHREADS 2776 #define SCI_COPYALLOWLINE 2519 +#define SCI_CUTALLOWLINE 2810 +#define SCI_SETCOPYSEPARATOR 2811 +#define SCI_GETCOPYSEPARATOR 2812 #define SCI_GETCHARACTERPOINTER 2520 #define SCI_GETRANGEPOINTER 2643 #define SCI_GETGAPPOSITION 2644 @@ -1020,6 +1059,7 @@ typedef sptr_t (*SciFnDirectStatus)(sptr_t ptr, unsigned int iMessage, uptr_t wP #define SCI_CLEARSELECTIONS 2571 #define SCI_SETSELECTION 2572 #define SCI_ADDSELECTION 2573 +#define SCI_SELECTIONFROMPOINT 2474 #define SCI_DROPSELECTIONN 2671 #define SCI_SETMAINSELECTION 2574 #define SCI_GETMAINSELECTION 2575 @@ -1354,7 +1394,7 @@ struct Sci_RangeToFormatFull {
#ifndef __cplusplus /* For the GTK+ platform, g-ir-scanner needs to have these typedefs. This - * is not required in C++ code and actually seems to break ScintillaEditPy */ + * is not required in C++ code and has caused problems in the past. */ typedef struct Sci_NotifyHeader Sci_NotifyHeader; typedef struct SCNotification SCNotification; #endif
Modified: scintilla/include/Scintilla.iface 102 lines changed, 101 insertions(+), 1 deletions(-) =================================================================== @@ -410,6 +410,8 @@ ali SC_MARKNUM_FOLDERTAIL=FOLDER_TAIL ali SC_MARKNUM_FOLDERSUB=FOLDER_SUB ali SC_MARKNUM_FOLDEROPEN=FOLDER_OPEN
+val SC_MASK_HISTORY=0x01E00000 + # SC_MASK_FOLDERS doesn't go in an enumeration as larger than max 32-bit positive integer val SC_MASK_FOLDERS=0xFE000000
@@ -698,6 +700,23 @@ set void StyleSetCheckMonospaced=2254(int style, bool checkMonospaced) # Get whether a style may be monospaced. get bool StyleGetCheckMonospaced=2255(int style,)
+enu FontStretch=SC_STRETCH_ +val SC_STRETCH_ULTRA_CONDENSED=1 +val SC_STRETCH_EXTRA_CONDENSED=2 +val SC_STRETCH_CONDENSED=3 +val SC_STRETCH_SEMI_CONDENSED=4 +val SC_STRETCH_NORMAL=5 +val SC_STRETCH_SEMI_EXPANDED=6 +val SC_STRETCH_EXPANDED=7 +val SC_STRETCH_EXTRA_EXPANDED=8 +val SC_STRETCH_ULTRA_EXPANDED=9 + +# Set the stretch of characters of a style. +set void StyleSetStretch=2258(int style, FontStretch stretch) + +# Get the stretch of characters of a style. +get FontStretch StyleGetStretch=2259(int style,) + # Set the invisible representation for a style. set void StyleSetInvisibleRepresentation=2256(int style, string representation)
@@ -717,6 +736,8 @@ val SC_ELEMENT_SELECTION_SECONDARY_TEXT=14 val SC_ELEMENT_SELECTION_SECONDARY_BACK=15 val SC_ELEMENT_SELECTION_INACTIVE_TEXT=16 val SC_ELEMENT_SELECTION_INACTIVE_BACK=17 +val SC_ELEMENT_SELECTION_INACTIVE_ADDITIONAL_TEXT=18 +val SC_ELEMENT_SELECTION_INACTIVE_ADDITIONAL_BACK=19 val SC_ELEMENT_CARET=40 val SC_ELEMENT_CARET_ADDITIONAL=41 val SC_ELEMENT_CARET_LINE_BACK=50 @@ -833,6 +854,51 @@ fun void BeginUndoAction=2078(,) # End a sequence of actions that is undone and redone as a unit. fun void EndUndoAction=2079(,)
+# Is an undo sequence active? +get int GetUndoSequence=2799(,) + +# How many undo actions are in the history? +get int GetUndoActions=2790(,) + +# Set action as the save point +set void SetUndoSavePoint=2791(int action,) + +# Which action is the save point? +get int GetUndoSavePoint=2792(,) + +# Set action as the detach point +set void SetUndoDetach=2793(int action,) + +# Which action is the detach point? +get int GetUndoDetach=2794(,) + +# Set action as the tentative point +set void SetUndoTentative=2795(int action,) + +# Which action is the tentative point? +get int GetUndoTentative=2796(,) + +# Set action as the current point +set void SetUndoCurrent=2797(int action,) + +# Which action is the current point? +get int GetUndoCurrent=2798(,) + +# Push one action onto undo history with no text +fun void PushUndoActionType=2800(int type, position pos) + +# Set the text and length of the most recently pushed action +fun void ChangeLastUndoActionText=2801(position length, string text) + +# What is the type of an action? +get int GetUndoActionType=2802(int action,) + +# What is the position of an action? +get position GetUndoActionPosition=2803(int action,) + +# What is the text of an action? +get int GetUndoActionText=2804(int action, stringresult text) + # Indicator style enumeration and some constants enu IndicatorStyle=INDIC_ val INDIC_PLAIN=0 @@ -1058,6 +1124,8 @@ enu AutoCompleteOption=SC_AUTOCOMPLETE_ val SC_AUTOCOMPLETE_NORMAL=0 # Win32 specific: val SC_AUTOCOMPLETE_FIXED_SIZE=1 +# Always select the first item in the autocompletion list: +val SC_AUTOCOMPLETE_SELECT_FIRST_ITEM=2
# Set autocompletion options. set void AutoCSetOptions=2638(AutoCompleteOption options,) @@ -1100,6 +1168,12 @@ set void AutoCSetMaxHeight=2210(int rowCount,) # Set the maximum height, in rows, of auto-completion and user lists. get int AutoCGetMaxHeight=2211(,)
+# Set the style number used for auto-completion and user lists fonts. +set void AutoCSetStyle=2109(int style,) + +# Get the style number used for auto-completion and user lists fonts. +get int AutoCGetStyle=2120(,) + # Set the number of spaces used for one level of indentation. set void SetIndent=2122(int indentSize,)
@@ -1936,9 +2010,16 @@ fun void DeleteBack=2326(,) # If more than one line selected, indent the lines. fun void Tab=2327(,)
-# Dedent the selected lines. +# Indent the current and selected lines. +fun void LineIndent=2813(,) + +# If selection is empty or all on one line dedent the line if caret is at start, else move caret. +# If more than one line selected, dedent the lines. fun void BackTab=2328(,)
+# Dedent the current and selected lines. +fun void LineDedent=2814(,) + # Insert a new line, may use a CRLF, CR or LF depending on EOL mode. fun void NewLine=2329(,)
@@ -2359,9 +2440,16 @@ val SC_SEL_THIN=3 # by lines (SC_SEL_LINES). set void SetSelectionMode=2422(SelectionMode selectionMode,)
+# Set the selection mode to stream (SC_SEL_STREAM) or rectangular (SC_SEL_RECTANGLE/SC_SEL_THIN) or +# by lines (SC_SEL_LINES) without changing MoveExtendsSelection. +fun void ChangeSelectionMode=2659(SelectionMode selectionMode,) + # Get the mode of the current selection. get SelectionMode GetSelectionMode=2423(,)
+# Set whether or not regular caret moves will extend or reduce the selection. +set void SetMoveExtendsSelection=2719(bool moveExtendsSelection,) + # Get whether or not regular caret moves will extend or reduce the selection. get bool GetMoveExtendsSelection=2706(,)
@@ -2604,6 +2692,15 @@ get int GetLayoutThreads=2776(,) # Copy the selection, if selection empty copy the line with the caret fun void CopyAllowLine=2519(,)
+# Cut the selection, if selection empty cut the line with the caret +fun void CutAllowLine=2810(,) + +# Set the string to separate parts when copying a multiple selection. +set void SetCopySeparator=2811(, string separator) + +# Get the string to separate parts when copying a multiple selection. +get int GetCopySeparator=2812(, stringresult separator) + # Compact the document buffer and return a read-only pointer to the # characters in the document. get pointer GetCharacterPointer=2520(,) @@ -2790,6 +2887,9 @@ fun void SetSelection=2572(position caret, position anchor) # Add a selection fun void AddSelection=2573(position caret, position anchor)
+# Find the selection index for a point. -1 when not at a selection. +fun int SelectionFromPoint=2474(int x, int y) + # Drop one selection fun void DropSelectionN=2671(int selection,)
Modified: scintilla/include/ScintillaCall.h 41 lines changed, 36 insertions(+), 5 deletions(-) =================================================================== @@ -20,6 +20,8 @@ struct TextRangeFull; struct TextToFindFull; struct RangeToFormatFull;
+class IDocumentEditable; + using FunctionDirect = intptr_t(*)(intptr_t ptr, unsigned int iMessage, uintptr_t wParam, intptr_t lParam, int *pStatus);
struct Failure { @@ -207,6 +209,8 @@ class ScintillaCall { void StyleSetHotSpot(int style, bool hotspot); void StyleSetCheckMonospaced(int style, bool checkMonospaced); bool StyleGetCheckMonospaced(int style); + void StyleSetStretch(int style, Scintilla::FontStretch stretch); + Scintilla::FontStretch StyleGetStretch(int style); void StyleSetInvisibleRepresentation(int style, const char *representation); int StyleGetInvisibleRepresentation(int style, char *representation); std::string StyleGetInvisibleRepresentation(int style); @@ -243,6 +247,22 @@ class ScintillaCall { int CharacterCategoryOptimization(); void BeginUndoAction(); void EndUndoAction(); + int UndoSequence(); + int UndoActions(); + void SetUndoSavePoint(int action); + int UndoSavePoint(); + void SetUndoDetach(int action); + int UndoDetach(); + void SetUndoTentative(int action); + int UndoTentative(); + void SetUndoCurrent(int action); + int UndoCurrent(); + void PushUndoActionType(int type, Position pos); + void ChangeLastUndoActionText(Position length, const char *text); + int UndoActionType(int action); + Position UndoActionPosition(int action); + int UndoActionText(int action, char *text); + std::string UndoActionText(int action); void IndicSetStyle(int indicator, Scintilla::IndicatorStyle indicatorStyle); Scintilla::IndicatorStyle IndicGetStyle(int indicator); void IndicSetFore(int indicator, Colour fore); @@ -302,6 +322,8 @@ class ScintillaCall { int AutoCGetMaxWidth(); void AutoCSetMaxHeight(int rowCount); int AutoCGetMaxHeight(); + void AutoCSetStyle(int style); + int AutoCGetStyle(); void SetIndent(int indentSize); int Indent(); void SetUseTabs(bool useTabs); @@ -520,7 +542,9 @@ class ScintillaCall { void Cancel(); void DeleteBack(); void Tab(); + void LineIndent(); void BackTab(); + void LineDedent(); void NewLine(); void FormFeed(); void VCHome(); @@ -561,8 +585,8 @@ class ScintillaCall { Position BraceMatchNext(Position pos, Position startPos); bool ViewEOL(); void SetViewEOL(bool visible); - void *DocPointer(); - void SetDocPointer(void *doc); + IDocumentEditable *DocPointer(); + void SetDocPointer(IDocumentEditable *doc); void SetModEventMask(Scintilla::ModificationFlags eventMask); Position EdgeColumn(); void SetEdgeColumn(Position column); @@ -581,9 +605,9 @@ class ScintillaCall { bool SelectionIsRectangle(); void SetZoom(int zoomInPoints); int Zoom(); - void *CreateDocument(Position bytes, Scintilla::DocumentOption documentOptions); - void AddRefDocument(void *doc); - void ReleaseDocument(void *doc); + IDocumentEditable *CreateDocument(Position bytes, Scintilla::DocumentOption documentOptions); + void AddRefDocument(IDocumentEditable *doc); + void ReleaseDocument(IDocumentEditable *doc); Scintilla::DocumentOption DocumentOptions(); Scintilla::ModificationFlags ModEventMask(); void SetCommandEvents(bool commandEvents); @@ -634,7 +658,9 @@ class ScintillaCall { void CopyRange(Position start, Position end); void CopyText(Position length, const char *text); void SetSelectionMode(Scintilla::SelectionMode selectionMode); + void ChangeSelectionMode(Scintilla::SelectionMode selectionMode); Scintilla::SelectionMode SelectionMode(); + void SetMoveExtendsSelection(bool moveExtendsSelection); bool MoveExtendsSelection(); Position GetLineSelStartPosition(Line line); Position GetLineSelEndPosition(Line line); @@ -704,6 +730,10 @@ class ScintillaCall { void SetLayoutThreads(int threads); int LayoutThreads(); void CopyAllowLine(); + void CutAllowLine(); + void SetCopySeparator(const char *separator); + int CopySeparator(char *separator); + std::string CopySeparator(); void *CharacterPointer(); void *RangePointer(Position start, Position lengthRange); Position GapPosition(); @@ -763,6 +793,7 @@ class ScintillaCall { void ClearSelections(); void SetSelection(Position caret, Position anchor); void AddSelection(Position caret, Position anchor); + int SelectionFromPoint(int x, int y); void DropSelectionN(int selection); void SetMainSelection(int selection); int MainSelection();
Modified: scintilla/include/ScintillaMessages.h 27 lines changed, 27 insertions(+), 0 deletions(-) =================================================================== @@ -137,6 +137,8 @@ enum class Message { StyleSetHotSpot = 2409, StyleSetCheckMonospaced = 2254, StyleGetCheckMonospaced = 2255, + StyleSetStretch = 2258, + StyleGetStretch = 2259, StyleSetInvisibleRepresentation = 2256, StyleGetInvisibleRepresentation = 2257, SetElementColour = 2753, @@ -171,6 +173,21 @@ enum class Message { GetCharacterCategoryOptimization = 2721, BeginUndoAction = 2078, EndUndoAction = 2079, + GetUndoSequence = 2799, + GetUndoActions = 2790, + SetUndoSavePoint = 2791, + GetUndoSavePoint = 2792, + SetUndoDetach = 2793, + GetUndoDetach = 2794, + SetUndoTentative = 2795, + GetUndoTentative = 2796, + SetUndoCurrent = 2797, + GetUndoCurrent = 2798, + PushUndoActionType = 2800, + ChangeLastUndoActionText = 2801, + GetUndoActionType = 2802, + GetUndoActionPosition = 2803, + GetUndoActionText = 2804, IndicSetStyle = 2080, IndicGetStyle = 2081, IndicSetFore = 2082, @@ -230,6 +247,8 @@ enum class Message { AutoCGetMaxWidth = 2209, AutoCSetMaxHeight = 2210, AutoCGetMaxHeight = 2211, + AutoCSetStyle = 2109, + AutoCGetStyle = 2120, SetIndent = 2122, GetIndent = 2123, SetUseTabs = 2124, @@ -442,7 +461,9 @@ enum class Message { Cancel = 2325, DeleteBack = 2326, Tab = 2327, + LineIndent = 2813, BackTab = 2328, + LineDedent = 2814, NewLine = 2329, FormFeed = 2330, VCHome = 2331, @@ -556,7 +577,9 @@ enum class Message { CopyRange = 2419, CopyText = 2420, SetSelectionMode = 2422, + ChangeSelectionMode = 2659, GetSelectionMode = 2423, + SetMoveExtendsSelection = 2719, GetMoveExtendsSelection = 2706, GetLineSelStartPosition = 2424, GetLineSelEndPosition = 2425, @@ -621,6 +644,9 @@ enum class Message { SetLayoutThreads = 2775, GetLayoutThreads = 2776, CopyAllowLine = 2519, + CutAllowLine = 2810, + SetCopySeparator = 2811, + GetCopySeparator = 2812, GetCharacterPointer = 2520, GetRangePointer = 2643, GetGapPosition = 2644, @@ -676,6 +702,7 @@ enum class Message { ClearSelections = 2571, SetSelection = 2572, AddSelection = 2573, + SelectionFromPoint = 2474, DropSelectionN = 2671, SetMainSelection = 2574, GetMainSelection = 2575,
Modified: scintilla/include/ScintillaTypes.h 16 lines changed, 16 insertions(+), 0 deletions(-) =================================================================== @@ -165,6 +165,18 @@ enum class FontWeight { Bold = 700, };
+enum class FontStretch { + UltraCondensed = 1, + ExtraCondensed = 2, + Condensed = 3, + SemiCondensed = 4, + Normal = 5, + SemiExpanded = 6, + Expanded = 7, + ExtraExpanded = 8, + UltraExpanded = 9, +}; + enum class Element { List = 0, ListBack = 1, @@ -178,6 +190,8 @@ enum class Element { SelectionSecondaryBack = 15, SelectionInactiveText = 16, SelectionInactiveBack = 17, + SelectionInactiveAdditionalText = 18, + SelectionInactiveAdditionalBack = 19, Caret = 40, CaretAdditional = 41, CaretLineBack = 50, @@ -249,6 +263,7 @@ enum class IndicFlag { enum class AutoCompleteOption { Normal = 0, FixedSize = 1, + SelectFirstItem = 2, };
enum class IndentView { @@ -687,6 +702,7 @@ using sptr_t = intptr_t; constexpr Position InvalidPosition = -1; constexpr int CpUtf8 = 65001; constexpr int MarkerMax = 31; +constexpr int MaskHistory = 0x01E00000; constexpr int MaskFolders = 0xFE000000; constexpr int MaxMargin = 4; constexpr int FontSizeMultiplier = 100;
Modified: scintilla/lexilla/include/Lexilla.h 16 lines changed, 8 insertions(+), 8 deletions(-) =================================================================== @@ -48,20 +48,20 @@ using Scintilla::ILexer5; typedef void ILexer5; #endif
-typedef ILexer5 *(*LexerFactoryFunction)(); +typedef ILexer5 *(*LexerFactoryFunction)(void);
#if defined(__cplusplus) namespace Lexilla { #endif
-typedef int (LEXILLA_CALL *GetLexerCountFn)(); +typedef int (LEXILLA_CALL *GetLexerCountFn)(void); typedef void (LEXILLA_CALL *GetLexerNameFn)(unsigned int Index, char *name, int buflength); typedef LexerFactoryFunction(LEXILLA_CALL *GetLexerFactoryFn)(unsigned int Index); typedef ILexer5*(LEXILLA_CALL *CreateLexerFn)(const char *name); DEPRECATE_DEFINITION typedef const char *(LEXILLA_CALL *LexerNameFromIDFn)(int identifier); -typedef const char *(LEXILLA_CALL *GetLibraryPropertyNamesFn)(); +typedef const char *(LEXILLA_CALL *GetLibraryPropertyNamesFn)(void); typedef void(LEXILLA_CALL *SetLibraryPropertyFn)(const char *key, const char *value); -typedef const char *(LEXILLA_CALL *GetNameSpaceFn)(); +typedef const char *(LEXILLA_CALL *GetNameSpaceFn)(void);
#if defined(__cplusplus) } @@ -85,13 +85,13 @@ extern "C" { #endif
ILexer5 * LEXILLA_CALL CreateLexer(const char *name); -int LEXILLA_CALL GetLexerCount(); +int LEXILLA_CALL GetLexerCount(void); void LEXILLA_CALL GetLexerName(unsigned int index, char *name, int buflength); LexerFactoryFunction LEXILLA_CALL GetLexerFactory(unsigned int index); DEPRECATE_DEFINITION const char *LEXILLA_CALL LexerNameFromID(int identifier); -const char * LEXILLA_CALL GetLibraryPropertyNames(); +const char * LEXILLA_CALL GetLibraryPropertyNames(void); void LEXILLA_CALL SetLibraryProperty(const char *key, const char *value); -const char *LEXILLA_CALL GetNameSpace(); +const char *LEXILLA_CALL GetNameSpace(void);
#if defined(__cplusplus) } @@ -102,7 +102,7 @@ namespace Lexilla { class LexerModule; } // Add a static lexer (in the same binary) to Lexilla's list -void AddStaticLexerModule(Lexilla::LexerModule *plm); +void AddStaticLexerModule(const Lexilla::LexerModule *plm); #endif
#endif
Modified: scintilla/lexilla/include/SciLexer.h 2 lines changed, 2 insertions(+), 0 deletions(-) =================================================================== @@ -1810,6 +1810,8 @@ #define SCE_RUST_BYTESTRING 21 #define SCE_RUST_BYTESTRINGR 22 #define SCE_RUST_BYTECHARACTER 23 +#define SCE_RUST_CSTRING 24 +#define SCE_RUST_CSTRINGR 25 #define SCE_DMAP_DEFAULT 0 #define SCE_DMAP_COMMENT 1 #define SCE_DMAP_NUMBER 2
Modified: scintilla/lexilla/lexers/LexAU3.cxx 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -908,4 +908,4 @@ static const char * const AU3WordLists[] = { "#autoit UDF", 0 }; -LexerModule lmAU3(SCLEX_AU3, ColouriseAU3Doc, "au3", FoldAU3Doc , AU3WordLists); +extern const LexerModule lmAU3(SCLEX_AU3, ColouriseAU3Doc, "au3", FoldAU3Doc , AU3WordLists);
Modified: scintilla/lexilla/lexers/LexAbaqus.cxx 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -603,4 +603,4 @@ static const char * const abaqusWordListDesc[] = { 0 };
-LexerModule lmAbaqus(SCLEX_ABAQUS, ColouriseABAQUSDoc, "abaqus", FoldABAQUSDoc, abaqusWordListDesc); +extern const LexerModule lmAbaqus(SCLEX_ABAQUS, ColouriseABAQUSDoc, "abaqus", FoldABAQUSDoc, abaqusWordListDesc);
Modified: scintilla/lexilla/lexers/LexAda.cxx 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -44,7 +44,7 @@ static const char * const adaWordListDesc[] = { 0 };
-LexerModule lmAda(SCLEX_ADA, ColouriseDocument, "ada", NULL, adaWordListDesc); +extern const LexerModule lmAda(SCLEX_ADA, ColouriseDocument, "ada", NULL, adaWordListDesc);
/* * Implementation
Modified: scintilla/lexilla/lexers/LexAsciidoc.cxx 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -390,4 +390,4 @@ static void ColorizeAsciidocDoc(Sci_PositionU startPos, Sci_Position length, int sc.Complete(); }
-LexerModule lmAsciidoc(SCLEX_ASCIIDOC, ColorizeAsciidocDoc, "asciidoc"); +extern const LexerModule lmAsciidoc(SCLEX_ASCIIDOC, ColorizeAsciidocDoc, "asciidoc");
Modified: scintilla/lexilla/lexers/LexAsm.cxx 89 lines changed, 44 insertions(+), 45 deletions(-) =================================================================== @@ -9,12 +9,12 @@ // Copyright 1998-2003 by Neil Hodgson neilh@scintilla.org // The License.txt file describes the conditions under which this software may be distributed.
-#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#include <stdarg.h> -#include <assert.h> -#include <ctype.h> +#include <cstdlib> +#include <cassert> +#include <cstring> +#include <cctype> +#include <cstdio> +#include <cstdarg>
#include <string> #include <string_view> @@ -37,17 +37,19 @@ using namespace Scintilla; using namespace Lexilla;
-static inline bool IsAWordChar(const int ch) { +namespace { + +bool IsAWordChar(const int ch) noexcept { return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '?'); }
-static inline bool IsAWordStart(const int ch) { +bool IsAWordStart(const int ch) noexcept { return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.' || ch == '%' || ch == '@' || ch == '$' || ch == '?'); }
-static inline bool IsAsmOperator(const int ch) { +bool IsAsmOperator(const int ch) noexcept { if ((ch < 0x80) && (isalnum(ch))) return false; // '.' left out as it is used to make up numbers @@ -60,16 +62,10 @@ static inline bool IsAsmOperator(const int ch) { return false; }
-static bool IsStreamCommentStyle(int style) { +constexpr bool IsStreamCommentStyle(int style) noexcept { return style == SCE_ASM_COMMENTDIRECTIVE || style == SCE_ASM_COMMENTBLOCK; }
-static inline int LowerCase(int c) { - if (c >= 'A' && c <= 'Z') - return 'a' + c - 'A'; - return c; -} - // An individual named option for use in an OptionSet
// Options used for LexerAsm @@ -98,7 +94,7 @@ struct OptionsAsm { } };
-static const char * const asmWordListDesc[] = { +const char *const asmWordListDesc[] = { "CPU instructions", "FPU instructions", "Registers", @@ -107,7 +103,7 @@ static const char * const asmWordListDesc[] = { "Extended instructions", "Directives4Foldstart", "Directives4Foldend", - 0 + nullptr };
struct OptionSetAsm : public OptionSet<OptionsAsm> { @@ -191,7 +187,7 @@ class LexerAsm : 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; }
static ILexer5 *LexerFactoryAsm() { @@ -211,7 +207,7 @@ Sci_Position SCI_METHOD LexerAsm::PropertySet(const char *key, const char *val) }
Sci_Position SCI_METHOD LexerAsm::WordListSet(int n, const char *wl) { - WordList *wordListN = 0; + WordList *wordListN = nullptr; switch (n) { case 0: wordListN = &cpuInstruction; @@ -240,10 +236,7 @@ Sci_Position SCI_METHOD LexerAsm::WordListSet(int n, const char *wl) { } Sci_Position firstModification = -1; if (wordListN) { - WordList wlNew; - wlNew.Set(wl); - if (*wordListN != wlNew) { - wordListN->Set(wl); + if (wordListN->Set(wl, true)) { firstModification = 0; } } @@ -265,11 +258,19 @@ void SCI_METHOD LexerAsm::Lex(Sci_PositionU startPos, Sci_Position length, int i for (; sc.More(); sc.Forward()) {
- // Prevent SCE_ASM_STRINGEOL from leaking back to previous line - if (sc.atLineStart && (sc.state == SCE_ASM_STRING)) { - sc.SetState(SCE_ASM_STRING); - } else if (sc.atLineStart && (sc.state == SCE_ASM_CHARACTER)) { - sc.SetState(SCE_ASM_CHARACTER); + if (sc.atLineStart) { + switch (sc.state) { + case SCE_ASM_STRING: + case SCE_ASM_CHARACTER: + // Prevent SCE_ASM_STRINGEOL from leaking back to previous line + sc.SetState(sc.state); + break; + case SCE_ASM_COMMENT: + sc.SetState(SCE_ASM_DEFAULT); + break; + default: + break; + } }
// Handle line continuation generically. @@ -314,7 +315,7 @@ void SCI_METHOD LexerAsm::Lex(Sci_PositionU startPos, Sci_Position length, int i } sc.SetState(SCE_ASM_DEFAULT); if (IsDirective && !strcmp(s, "comment")) { - char delimiter = options.delimiter.empty() ? '~' : options.delimiter.c_str()[0]; + const char delimiter = options.delimiter.empty() ? '~' : options.delimiter.c_str()[0]; while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd) { sc.ForwardSetState(SCE_ASM_DEFAULT); } @@ -324,17 +325,13 @@ void SCI_METHOD LexerAsm::Lex(Sci_PositionU startPos, Sci_Position length, int i } } } else if (sc.state == SCE_ASM_COMMENTDIRECTIVE) { - char delimiter = options.delimiter.empty() ? '~' : options.delimiter.c_str()[0]; + const char delimiter = options.delimiter.empty() ? '~' : options.delimiter.c_str()[0]; if (sc.ch == delimiter) { - while (!sc.atLineEnd) { + while (!sc.MatchLineEnd()) { sc.Forward(); } sc.SetState(SCE_ASM_DEFAULT); } - } else if (sc.state == SCE_ASM_COMMENT ) { - if (sc.atLineEnd) { - sc.SetState(SCE_ASM_DEFAULT); - } } else if (sc.state == SCE_ASM_STRING) { if (sc.ch == '\') { if (sc.chNext == '"' || sc.chNext == ''' || sc.chNext == '\') { @@ -391,7 +388,7 @@ void SCI_METHOD LexerAsm::Fold(Sci_PositionU startPos, Sci_Position length, int
LexAccessor styler(pAccess);
- Sci_PositionU endPos = startPos + length; + const Sci_PositionU endPos = startPos + length; int visibleChars = 0; Sci_Position lineCurrent = styler.GetLine(startPos); int levelCurrent = SC_FOLDLEVELBASE; @@ -401,16 +398,16 @@ void SCI_METHOD LexerAsm::Fold(Sci_PositionU startPos, Sci_Position length, int char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); int style = initStyle; - char word[100]; + char word[100]{}; int wordlen = 0; const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty(); for (Sci_PositionU i = startPos; i < endPos; i++) { - char ch = chNext; + const char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); - int stylePrev = style; + const int stylePrev = style; style = styleNext; styleNext = styler.StyleAt(i + 1); - bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); + const bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (options.foldCommentMultiline && IsStreamCommentStyle(style)) { if (!IsStreamCommentStyle(stylePrev)) { levelNext++; @@ -437,7 +434,7 @@ void SCI_METHOD LexerAsm::Fold(Sci_PositionU startPos, Sci_Position length, int } } if (options.foldSyntaxBased && (style == SCE_ASM_DIRECTIVE)) { - word[wordlen++] = static_cast<char>(LowerCase(ch)); + word[wordlen++] = MakeLowerCase(ch); if (wordlen == 100) { // prevent overflow word[0] = '\0'; wordlen = 1; @@ -455,7 +452,7 @@ void SCI_METHOD LexerAsm::Fold(Sci_PositionU startPos, Sci_Position length, int if (!IsASpace(ch)) visibleChars++; if (atEOL || (i == endPos-1)) { - int levelUse = levelCurrent; + const int levelUse = levelCurrent; int lev = levelUse | levelNext << 16; if (visibleChars == 0 && options.foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; @@ -475,6 +472,8 @@ void SCI_METHOD LexerAsm::Fold(Sci_PositionU startPos, Sci_Position length, int } }
-LexerModule lmAsm(SCLEX_ASM, LexerAsm::LexerFactoryAsm, "asm", asmWordListDesc); -LexerModule lmAs(SCLEX_AS, LexerAsm::LexerFactoryAs, "as", asmWordListDesc); +} + +extern const LexerModule lmAsm(SCLEX_ASM, LexerAsm::LexerFactoryAsm, "asm", asmWordListDesc); +extern const LexerModule lmAs(SCLEX_AS, LexerAsm::LexerFactoryAs, "as", asmWordListDesc);
Modified: scintilla/lexilla/lexers/LexBash.cxx 86 lines changed, 51 insertions(+), 35 deletions(-) =================================================================== @@ -16,13 +16,15 @@ #include <string_view> #include <vector> #include <map> +#include <initializer_list> #include <functional>
#include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h"
#include "StringCopy.h" +#include "InList.h" #include "WordList.h" #include "LexAccessor.h" #include "StyleContext.h" @@ -63,7 +65,7 @@ enum class CmdState { Delimiter, };
-enum class CommandSubstitution { +enum class CommandSubstitution : int { Backtick, Inside, InsideTrack, @@ -181,7 +183,7 @@ struct OptionsBash { bool stylingInsideParameter = false; bool stylingInsideHeredoc = false; bool nestedBackticks = true; - int commandSubstitution = static_cast<int>(CommandSubstitution::Backtick); + CommandSubstitution commandSubstitution = CommandSubstitution::Backtick; std::string specialParameter = BASH_SPECIAL_PARAMETER;
[[nodiscard]] bool stylingInside(int state) const noexcept { @@ -333,7 +335,7 @@ class QuoteStackCls { // Class to manage quote pairs that nest } bool CountDown(StyleContext &sc, CmdState &cmdState) { Current.Count--; - if (Current.Count == 1 && sc.Match(')', ')')) { + while (Current.Count > 0 && sc.chNext == Current.Down) { Current.Count--; sc.Forward(); } @@ -380,10 +382,6 @@ class QuoteStackCls { // Class to manage quote pairs that nest sc.ChangeState(SCE_SH_BACKTICKS); } } - if (current == CmdState::Body && sc.Match('(', '(') && state == SCE_SH_DEFAULT && Depth == 0) { - // optimized to avoid track nested delimiter pairs - style = QuoteStyle::Literal; - } } else { // scalar has no delimiter pair if (!setParamStart.Contains(sc.ch)) { @@ -470,7 +468,7 @@ const LexicalClass lexicalClasses[] = { 10, "SCE_SH_PARAM", "identifier", "Parameter", 11, "SCE_SH_BACKTICKS", "literal string", "Backtick quoted command", 12, "SCE_SH_HERE_DELIM", "operator", "Heredoc delimiter", - 13, "SCE_SH_HERE_Q", "literal string", "Heredoc quoted string", + 13, "SCE_SH_HERE_Q", "here-doc literal string", "Heredoc quoted string", };
} @@ -485,12 +483,11 @@ class LexerBash final : public DefaultLexer { OptionSetBash osBash; CharacterSet setParamStart; enum { ssIdentifier, ssScalar }; - SubStyles subStyles; + SubStyles subStyles{styleSubable}; public: LexerBash() : - DefaultLexer("bash", SCLEX_BASH, lexicalClasses, ELEMENTS(lexicalClasses)), - setParamStart(CharacterSet::setAlphaNum, "_" BASH_SPECIAL_PARAMETER), - subStyles(styleSubable, 0x80, 0x40, 0) { + DefaultLexer("bash", SCLEX_BASH, lexicalClasses, std::size(lexicalClasses)), + setParamStart(CharacterSet::setAlphaNum, "_" BASH_SPECIAL_PARAMETER) { cmdDelimiter.Set("| || |& & && ; ;; ( ) { }"); bashStruct.Set("if elif fi while until else then do done esac eval"); bashStruct_in.Set("for case select"); @@ -614,6 +611,7 @@ void SCI_METHOD LexerBash::Lex(Sci_PositionU startPos, Sci_Position length, int bool Quoted = false; // true if Quote in (''','"','`') bool Escaped = false; // backslash in delimiter, common in configure script bool Indent = false; // indented delimiter (for <<-) + int BackslashCount = 0; int DelimiterLength = 0; // strlen(Delimiter) char Delimiter[HERE_DELIM_MAX]{}; // the Delimiter HereDocCls() noexcept = default; @@ -626,7 +624,7 @@ void SCI_METHOD LexerBash::Lex(Sci_PositionU startPos, Sci_Position length, int
QuoteStackCls QuoteStack(setParamStart); QuoteStack.nestedBackticks = options.nestedBackticks; - QuoteStack.commandSubstitution = static_cast<CommandSubstitution>(options.commandSubstitution); + QuoteStack.commandSubstitution = options.commandSubstitution;
const WordClassifier &classifierIdentifiers = subStyles.Classifier(SCE_SH_IDENTIFIER); const WordClassifier &classifierScalars = subStyles.Classifier(SCE_SH_SCALAR); @@ -834,6 +832,7 @@ void SCI_METHOD LexerBash::Lex(Sci_PositionU startPos, Sci_Position length, int HereDoc.Quote = sc.chNext; HereDoc.Quoted = false; HereDoc.Escaped = false; + HereDoc.BackslashCount = 0; HereDoc.DelimiterLength = 0; HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0'; if (sc.chNext == ''' || sc.chNext == '"') { // a quoted here-doc delimiter (' or ") @@ -861,22 +860,21 @@ void SCI_METHOD LexerBash::Lex(Sci_PositionU startPos, Sci_Position length, int } else if (HereDoc.State == 1) { // collect the delimiter // * if single quoted, there's no escape // * if double quoted, there are \ and " escapes - if ((HereDoc.Quote == ''' && sc.ch != HereDoc.Quote) || - (HereDoc.Quoted && sc.ch != HereDoc.Quote && sc.ch != '\') || - (HereDoc.Quote != ''' && sc.chPrev == '\') || - (setHereDoc2.Contains(sc.ch))) { - HereDoc.Append(sc.ch); - } else if (HereDoc.Quoted && sc.ch == HereDoc.Quote) { // closing quote => end of delimiter - sc.ForwardSetState(SCE_SH_DEFAULT); - } else if (sc.ch == '\') { + if (HereDoc.Quoted && sc.ch == HereDoc.Quote && (HereDoc.BackslashCount & 1) == 0) { // closing quote => end of delimiter + sc.ForwardSetState(SCE_SH_DEFAULT | insideCommand); + } else if (sc.ch == '\' && HereDoc.Quote != ''') { HereDoc.Escaped = true; - if (HereDoc.Quoted && sc.chNext != HereDoc.Quote && sc.chNext != '\') { + HereDoc.BackslashCount += 1; + if ((HereDoc.BackslashCount & 1) == 0 || (HereDoc.Quoted && !AnyOf(sc.chNext, '"', '\'))) { // in quoted prefixes only \ and the quote eat the escape HereDoc.Append(sc.ch); } else { // skip escape prefix } - } else if (!HereDoc.Quoted) { + } else if (HereDoc.Quoted || setHereDoc2.Contains(sc.ch) || (sc.ch > 32 && sc.ch < 127 && (HereDoc.BackslashCount & 1) != 0)) { + HereDoc.BackslashCount = 0; + HereDoc.Append(sc.ch); + } else { sc.SetState(SCE_SH_DEFAULT | insideCommand); } if (HereDoc.DelimiterLength >= HERE_DELIM_MAX - 1) { // force blowup @@ -939,7 +937,9 @@ void SCI_METHOD LexerBash::Lex(Sci_PositionU startPos, Sci_Position length, int continue; } } else if (sc.ch == QuoteStack.Current.Up) { - QuoteStack.Current.Count++; + if (QuoteStack.Current.Style != QuoteStyle::Parameter) { + QuoteStack.Current.Count++; + } } else { if (QuoteStack.Current.Style == QuoteStyle::String || QuoteStack.Current.Style == QuoteStyle::HereDoc || @@ -1189,10 +1189,17 @@ void SCI_METHOD LexerBash::Fold(Sci_PositionU startPos_, Sci_Position length, in
LexAccessor styler(pAccess);
- const Sci_Position startPos = startPos_; + Sci_Position startPos = startPos_; const Sci_Position endPos = startPos + length; int visibleChars = 0; Sci_Position lineCurrent = styler.GetLine(startPos); + // Backtrack to previous line in case need to fix its fold status + if (lineCurrent > 0) { + lineCurrent--; + startPos = styler.LineStart(lineCurrent); + initStyle = (startPos > 0) ? styler.StyleIndexAt(startPos - 1) : 0; + } + int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent = levelPrev; char chNext = styler[startPos]; @@ -1217,28 +1224,32 @@ void SCI_METHOD LexerBash::Fold(Sci_PositionU startPos_, Sci_Position length, in && !IsCommentLine(lineCurrent + 1, styler)) levelCurrent--; } - if (style == SCE_SH_WORD) { + + switch (style) { + case SCE_SH_WORD: if ((wordlen + 1) < sizeof(word)) word[wordlen++] = ch; if (styleNext != style) { word[wordlen] = '\0'; wordlen = 0; - if (strcmp(word, "if") == 0 || strcmp(word, "case") == 0 || strcmp(word, "do") == 0) { + if (InList(word, {"if", "case", "do"})) { levelCurrent++; - } else if (strcmp(word, "fi") == 0 || strcmp(word, "esac") == 0 || strcmp(word, "done") == 0) { + } else if (InList(word, {"fi", "esac", "done"})) { levelCurrent--; } } - } - if (style == SCE_SH_OPERATOR) { + break; + + case SCE_SH_OPERATOR: if (ch == '{') { levelCurrent++; } else if (ch == '}') { levelCurrent--; } - } + break; + // Here Document folding - if (style == SCE_SH_HERE_DELIM) { + case SCE_SH_HERE_DELIM: if (stylePrev == SCE_SH_HERE_Q) { levelCurrent--; } else if (stylePrev != SCE_SH_HERE_DELIM) { @@ -1248,9 +1259,14 @@ void SCI_METHOD LexerBash::Fold(Sci_PositionU startPos_, Sci_Position length, in } } } - } else if (style == SCE_SH_HERE_Q && styleNext == SCE_SH_DEFAULT) { - levelCurrent--; + break; + case SCE_SH_HERE_Q: + if (styleNext == SCE_SH_DEFAULT) { + levelCurrent--; + } + break; } + if (atEOL) { int lev = levelPrev; if (visibleChars == 0 && options.foldCompact) @@ -1272,4 +1288,4 @@ void SCI_METHOD LexerBash::Fold(Sci_PositionU startPos_, Sci_Position length, in styler.SetLevel(lineCurrent, levelPrev | flagsNext); }
-LexerModule lmBash(SCLEX_BASH, LexerBash::LexerFactoryBash, "bash", bashWordListDesc); +extern const LexerModule lmBash(SCLEX_BASH, LexerBash::LexerFactoryBash, "bash", bashWordListDesc);
Modified: scintilla/lexilla/lexers/LexBasic.cxx 6 lines changed, 3 insertions(+), 3 deletions(-) =================================================================== @@ -566,8 +566,8 @@ void SCI_METHOD LexerBasic::Fold(Sci_PositionU startPos, Sci_Position length, in } }
-LexerModule lmBlitzBasic(SCLEX_BLITZBASIC, LexerBasic::LexerFactoryBlitzBasic, "blitzbasic", blitzbasicWordListDesc); +extern const LexerModule lmBlitzBasic(SCLEX_BLITZBASIC, LexerBasic::LexerFactoryBlitzBasic, "blitzbasic", blitzbasicWordListDesc);
-LexerModule lmPureBasic(SCLEX_PUREBASIC, LexerBasic::LexerFactoryPureBasic, "purebasic", purebasicWordListDesc); +extern const LexerModule lmPureBasic(SCLEX_PUREBASIC, LexerBasic::LexerFactoryPureBasic, "purebasic", purebasicWordListDesc);
-LexerModule lmFreeBasic(SCLEX_FREEBASIC, LexerBasic::LexerFactoryFreeBasic, "freebasic", freebasicWordListDesc); +extern const LexerModule lmFreeBasic(SCLEX_FREEBASIC, LexerBasic::LexerFactoryFreeBasic, "freebasic", freebasicWordListDesc);
Modified: scintilla/lexilla/lexers/LexBatch.cxx 74 lines changed, 36 insertions(+), 38 deletions(-) =================================================================== @@ -14,11 +14,13 @@
#include <string> #include <string_view> +#include <initializer_list>
#include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h"
+#include "InList.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" @@ -57,7 +59,7 @@ constexpr bool IsBSeparator(char ch) noexcept { }
// Tests for escape character -bool IsEscaped(const char* wordStr, Sci_PositionU pos) noexcept { +constexpr bool IsEscaped(const char* wordStr, Sci_PositionU pos) noexcept { bool isQoted=false; while (pos>0){ pos--; @@ -69,30 +71,24 @@ bool IsEscaped(const char* wordStr, Sci_PositionU pos) noexcept { return isQoted; }
-// Tests for quote character -bool textQuoted(const char *lineBuffer, Sci_PositionU endPos) { - char strBuffer[1024]; - strncpy(strBuffer, lineBuffer, endPos); - strBuffer[endPos] = '\0'; +constexpr bool IsQuotedBy(std::string_view svBuffer, char quote) noexcept { bool CurrentStatus = false; - const char strQuotes[] = ""'"; - const size_t strLength = strlen(strQuotes); - for (size_t i = 0; i < strLength; i++) { - const char *pQuote = strchr(strBuffer, strQuotes[i]); - while (pQuote) - { - if (!IsEscaped(strBuffer, pQuote - strBuffer)) { - CurrentStatus = !CurrentStatus; - } - pQuote = strchr(pQuote + 1, strQuotes[i]); - } - if (CurrentStatus) { - break; + size_t pQuote = svBuffer.find(quote); + while (pQuote != std::string_view::npos) { + if (!IsEscaped(svBuffer.data(), pQuote)) { + CurrentStatus = !CurrentStatus; } + pQuote = svBuffer.find(quote, pQuote + 1); } return CurrentStatus; }
+// Tests for quote character +constexpr bool textQuoted(const char *lineBuffer, Sci_PositionU endPos) noexcept { + const std::string_view svBuffer(lineBuffer, endPos); + return IsQuotedBy(svBuffer, '"') || IsQuotedBy(svBuffer, '''); +} + void ColouriseBatchDoc( Sci_PositionU startPos, Sci_Position length, @@ -200,18 +196,19 @@ void ColouriseBatchDoc( styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT); } char wordBuffer[81]{}; // Word Buffer - large to catch long paths - // Copy word from Line Buffer into Word Buffer + // Copy word from Line Buffer into Word Buffer and convert to lower case Sci_PositionU wbl = 0; // Word Buffer Length for (; offset < lengthLine && wbl < 80 && !isspacechar(lineBuffer[offset]); wbl++, offset++) { - wordBuffer[wbl] = tolower(lineBuffer[offset]); + wordBuffer[wbl] = MakeLowerCase(lineBuffer[offset]); } wordBuffer[wbl] = '\0'; + const std::string_view wordView(wordBuffer); Sci_PositionU wbo = 0; // Word Buffer Offset - also Special Keyword Buffer Length
// Check for Comment - return if found if (continueProcessing) { - if ((CompareCaseInsensitive(wordBuffer, "rem") == 0) || (wordBuffer[0] == ':' && wordBuffer[1] == ':')) { + if ((wordView == "rem") || (wordBuffer[0] == ':' && wordBuffer[1] == ':')) { if ((offset == wbl) || !textQuoted(lineBuffer, offset - wbl)) { styler.ColourTo(startLine + offset - wbl - 1, SCE_BAT_DEFAULT); styler.ColourTo(endPos, SCE_BAT_COMMENT); @@ -248,19 +245,16 @@ void ColouriseBatchDoc( } 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)) { + if (InList(wordView, {"echo", "goto", "prompt"})) { continueProcessing = false; } // SET requires additional processing for the assignment operator - if (CompareCaseInsensitive(wordBuffer, "set") == 0) { + if (wordView == "set") { continueProcessing = false; isNotAssigned=true; } // Identify External Command / Program Location for ERRORLEVEL, and EXIST - if ((CompareCaseInsensitive(wordBuffer, "errorlevel") == 0) || - (CompareCaseInsensitive(wordBuffer, "exist") == 0)) { + if (InList(wordView, {"errorlevel", "exist"})) { // Reset External Command / Program Location cmdLoc = offset; // Skip next spaces @@ -279,17 +273,19 @@ void ColouriseBatchDoc( 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)) { + } else if (InList(wordView, {"call", "do", "loadhigh", "lh"})) { // Reset External Command / Program Location cmdLoc = offset; // Skip next spaces while ((cmdLoc < lengthLine) && (isspacechar(lineBuffer[cmdLoc]))) { cmdLoc++; } + // Check if call is followed by a label + if ((lineBuffer[cmdLoc] == ':') && + (wordView == "call")) { + continueProcessing = false; + } } // Colorize Regular keyword styler.ColourTo(startLine + offset - 1, SCE_BAT_WORD); @@ -317,10 +313,12 @@ void ColouriseBatchDoc( // Check for Special Keyword in list if ((keywords.InList(sKeywordBuffer)) && ((IsBOperator(wordBuffer[wbo])) || - (IsBSeparator(wordBuffer[wbo])))) { + (IsBSeparator(wordBuffer[wbo])) || + (wordBuffer[wbo] == ':' && + (InList(sKeywordBuffer, {"call", "echo", "goto"}) )))) { sKeywordFound = true; // ECHO requires no further Regular Keyword Checking - if (CompareCaseInsensitive(sKeywordBuffer, "echo") == 0) { + if (std::string_view(sKeywordBuffer) == "echo") { continueProcessing = false; } // Colorize Special Keyword as Regular Keyword @@ -347,11 +345,11 @@ void ColouriseBatchDoc( // Reset Offset to re-process remainder of word offset -= (wbl - wbo); // CHOICE requires no further Regular Keyword Checking - if (CompareCaseInsensitive(wordBuffer, "choice") == 0) { + if (wordView == "choice") { continueProcessing = false; } // Check for START (and its switches) - What follows is External Command \ Program - if (CompareCaseInsensitive(wordBuffer, "start") == 0) { + if (wordView == "start") { // Reset External Command / Program Location cmdLoc = offset; // Skip next spaces @@ -576,7 +574,7 @@ void ColouriseBatchDoc( isNotAssigned=false; } // Colorize Other Operators - // Do not Colorize Paranthesis, quoted text and escaped operators + // Do not Colorize Parenthesis, quoted text and escaped operators if (((wordBuffer[0] != ')') && (wordBuffer[0] != '(') && !textQuoted(lineBuffer, offset - wbl) && !IsEscaped(lineBuffer,offset - wbl + wbo)) && !((wordBuffer[0] == '=') && !isNotAssigned )) @@ -645,4 +643,4 @@ const char *const batchWordListDesc[] = {
}
-LexerModule lmBatch(SCLEX_BATCH, ColouriseBatchDoc, "batch", nullptr, batchWordListDesc); +extern const LexerModule lmBatch(SCLEX_BATCH, ColouriseBatchDoc, "batch", nullptr, batchWordListDesc);
Modified: scintilla/lexilla/lexers/LexCIL.cxx 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -407,4 +407,4 @@ void SCI_METHOD LexerCIL::Fold(Sci_PositionU startPos, Sci_Position length, } }
-LexerModule lmCIL(SCLEX_CIL, LexerCIL::LexerFactoryCIL, "cil", cilWordListDesc); \ No newline at end of file +extern const LexerModule lmCIL(SCLEX_CIL, LexerCIL::LexerFactoryCIL, "cil", cilWordListDesc); \ No newline at end of file
Modified: scintilla/lexilla/lexers/LexCOBOL.cxx 262 lines changed, 135 insertions(+), 127 deletions(-) =================================================================== @@ -8,12 +8,11 @@ ** Updated by Rod Falck, Aug 2006 Converted to COBOL **/
-#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#include <stdarg.h> -#include <assert.h> -#include <ctype.h> +#include <cstdlib> +#include <cassert> +#include <cstring> +#include <cctype> +#include <cstdio>
#include <string> #include <string_view> @@ -38,34 +37,36 @@ using namespace Lexilla; #define IN_FLAGS 0xF #define NOT_HEADER 0x10
-inline bool isCOBOLoperator(char ch) +namespace { + +bool isCOBOLoperator(char ch) { return isoperator(ch); }
-inline bool isCOBOLwordchar(char ch) +bool isCOBOLwordchar(char ch) { return IsASCII(ch) && (isalnum(ch) || ch == '-');
}
-inline bool isCOBOLwordstart(char ch) +bool isCOBOLwordstart(char ch) { return IsASCII(ch) && isalnum(ch); }
-static int CountBits(int nBits) - { - int count = 0; - for (int i = 0; i < 32; ++i) - { - count += nBits & 1; - nBits >>= 1; - } - return count; - } - -static void getRange(Sci_PositionU start, +int CountBits(int nBits) + { + int count = 0; + for (int i = 0; i < 32; ++i) + { + count += nBits & 1; + nBits >>= 1; + } + return count; + } + +void getRange(Sci_PositionU start, Sci_PositionU end, Accessor &styler, char *s, @@ -78,79 +79,79 @@ static void getRange(Sci_PositionU start, s[i] = '\0'; }
-static void ColourTo(Accessor &styler, Sci_PositionU end, unsigned int attr) { +void ColourTo(Accessor &styler, Sci_PositionU end, unsigned int attr) { styler.ColourTo(end, attr); }
-static int classifyWordCOBOL(Sci_PositionU start, Sci_PositionU end, /*WordList &keywords*/WordList *keywordlists[], Accessor &styler, int nContainment, bool *bAarea) { +int classifyWordCOBOL(Sci_PositionU start, Sci_PositionU end, /*WordList &keywords*/WordList *keywordlists[], Accessor &styler, int nContainment, bool *bAarea) { int ret = 0;
- WordList& a_keywords = *keywordlists[0]; - WordList& b_keywords = *keywordlists[1]; - WordList& c_keywords = *keywordlists[2]; - char s[100]; s[0] = '\0'; s[1] = '\0'; getRange(start, end, styler, s, sizeof(s));
- char chAttr = SCE_C_IDENTIFIER; + int chAttr = SCE_COBOL_IDENTIFIER; if (isdigit(s[0]) || (s[0] == '.') || (s[0] == 'v')) { - chAttr = SCE_C_NUMBER; - char *p = s + 1; - while (*p) { - if ((!isdigit(*p) && (*p) != 'v') && isCOBOLwordchar(*p)) { - chAttr = SCE_C_IDENTIFIER; - break; - } - ++p; - } + chAttr = SCE_COBOL_NUMBER; + char *p = s + 1; + while (*p) { + if ((!isdigit(*p) && (*p) != 'v') && isCOBOLwordchar(*p)) { + chAttr = SCE_COBOL_IDENTIFIER; + break; + } + ++p; + } } - else { + if (chAttr == SCE_COBOL_IDENTIFIER) { + WordList& a_keywords = *keywordlists[0]; + WordList& b_keywords = *keywordlists[1]; + WordList& c_keywords = *keywordlists[2]; + if (a_keywords.InList(s)) { - chAttr = SCE_C_WORD; + chAttr = SCE_COBOL_WORD; } else if (b_keywords.InList(s)) { - chAttr = SCE_C_WORD2; + chAttr = SCE_COBOL_WORD2; } else if (c_keywords.InList(s)) { - chAttr = SCE_C_UUID; + chAttr = SCE_COBOL_WORD3; } } if (*bAarea) { if (strcmp(s, "division") == 0) { ret = IN_DIVISION; - // we've determined the containment, anything else is just ignored for those purposes - *bAarea = false; - } else if (strcmp(s, "declaratives") == 0) { + // we've determined the containment, anything else is just ignored for those purposes + *bAarea = false; + } else if (strcmp(s, "declaratives") == 0) { ret = IN_DIVISION | IN_DECLARATIVES; - if (nContainment & IN_DECLARATIVES) - ret |= NOT_HEADER | IN_SECTION; - // we've determined the containment, anything else is just ignored for those purposes - *bAarea = false; - } else if (strcmp(s, "section") == 0) { + if (nContainment & IN_DECLARATIVES) + ret |= NOT_HEADER | IN_SECTION; + // we've determined the containment, anything else is just ignored for those purposes + *bAarea = false; + } else if (strcmp(s, "section") == 0) { ret = (nContainment &~ IN_PARAGRAPH) | IN_SECTION; - // we've determined the containment, anything else is just ignored for those purposes - *bAarea = false; - } else if (strcmp(s, "end") == 0 && (nContainment & IN_DECLARATIVES)) { + // we've determined the containment, anything else is just ignored for those purposes + *bAarea = false; + } else if (strcmp(s, "end") == 0 && (nContainment & IN_DECLARATIVES)) { ret = IN_DIVISION | IN_DECLARATIVES | IN_SECTION | NOT_HEADER; - } else { - ret = nContainment | IN_PARAGRAPH; + } else { + ret = nContainment | IN_PARAGRAPH; } } ColourTo(styler, end, chAttr); return ret; }
-static void ColouriseCOBOLDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[], +void ColouriseCOBOLDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[], Accessor &styler) {
styler.StartAt(startPos);
int state = initStyle; - if (state == SCE_C_CHARACTER) // Does not leak onto next line - state = SCE_C_DEFAULT; + if (state == SCE_COBOL_CHARACTER) // Does not leak onto next line + state = SCE_COBOL_DEFAULT; char chPrev = ' '; char chNext = styler[startPos]; Sci_PositionU lengthDoc = startPos + length; @@ -161,7 +162,7 @@ static void ColouriseCOBOLDoc(Sci_PositionU startPos, Sci_Position length, int i if (currentLine > 0) { styler.SetLineState(currentLine, styler.GetLineState(currentLine-1)); nContainment = styler.GetLineState(currentLine); - nContainment &= ~NOT_HEADER; + nContainment &= ~NOT_HEADER; } else { styler.SetLineState(currentLine, 0); nContainment = 0; @@ -170,34 +171,34 @@ static void ColouriseCOBOLDoc(Sci_PositionU startPos, Sci_Position length, int i styler.StartSegment(startPos); bool bNewLine = true; bool bAarea = !isspacechar(chNext); - int column = 0; + int column = 0; for (Sci_PositionU i = startPos; i < lengthDoc; i++) { char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
- ++column; + ++column;
if (bNewLine) { - column = 0; + column = 0; + } + if (column <= 1 && !bAarea) { + bAarea = !isspacechar(ch); } - if (column <= 1 && !bAarea) { - bAarea = !isspacechar(ch); - } bool bSetNewLine = false; if ((ch == '\r' && chNext != '\n') || (ch == '\n')) { // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix) // Avoid triggering two times on Dos/Win // End of line - if (state == SCE_C_CHARACTER) { + if (state == SCE_COBOL_CHARACTER) { ColourTo(styler, i, state); - state = SCE_C_DEFAULT; + state = SCE_COBOL_DEFAULT; } styler.SetLineState(currentLine, nContainment); currentLine++; bSetNewLine = true; - if (nContainment & NOT_HEADER) - nContainment &= ~(NOT_HEADER | IN_DECLARATIVES | IN_SECTION); + if (nContainment & NOT_HEADER) + nContainment &= ~(NOT_HEADER | IN_DECLARATIVES | IN_SECTION); }
if (styler.IsLeadByte(ch)) { @@ -207,44 +208,44 @@ static void ColouriseCOBOLDoc(Sci_PositionU startPos, Sci_Position length, int i continue; }
- if (state == SCE_C_DEFAULT) { + if (state == SCE_COBOL_DEFAULT) { if (isCOBOLwordstart(ch) || (ch == '$' && IsASCII(chNext) && isalpha(chNext))) { ColourTo(styler, i-1, state); - state = SCE_C_IDENTIFIER; - } else if (column == 6 && ch == '*') { + state = SCE_COBOL_IDENTIFIER; + } else if (column == 6 && (ch == '*' || ch == '/')) { // Cobol comment line: asterisk in column 7. ColourTo(styler, i-1, state); - state = SCE_C_COMMENTLINE; + state = SCE_COBOL_COMMENTLINE; } else if (ch == '*' && chNext == '>') { // Cobol inline comment: asterisk, followed by greater than. ColourTo(styler, i-1, state); - state = SCE_C_COMMENTLINE; + state = SCE_COBOL_COMMENTLINE; } else if (column == 0 && ch == '*' && chNext != '*') { ColourTo(styler, i-1, state); - state = SCE_C_COMMENTLINE; + state = SCE_COBOL_COMMENTLINE; } else if (column == 0 && ch == '/' && chNext != '*') { ColourTo(styler, i-1, state); - state = SCE_C_COMMENTLINE; + state = SCE_COBOL_COMMENTLINE; } else if (column == 0 && ch == '*' && chNext == '*') { ColourTo(styler, i-1, state); - state = SCE_C_COMMENTDOC; + state = SCE_COBOL_COMMENTDOC; } else if (column == 0 && ch == '/' && chNext == '*') { ColourTo(styler, i-1, state); - state = SCE_C_COMMENTDOC; + state = SCE_COBOL_COMMENTDOC; } else if (ch == '"') { ColourTo(styler, i-1, state); - state = SCE_C_STRING; + state = SCE_COBOL_STRING; } else if (ch == ''') { ColourTo(styler, i-1, state); - state = SCE_C_CHARACTER; + state = SCE_COBOL_CHARACTER; } else if (ch == '?' && column == 0) { ColourTo(styler, i-1, state); - state = SCE_C_PREPROCESSOR; + state = SCE_COBOL_PREPROCESSOR; } else if (isCOBOLoperator(ch)) { ColourTo(styler, i-1, state); - ColourTo(styler, i, SCE_C_OPERATOR); + ColourTo(styler, i, SCE_COBOL_OPERATOR); } - } else if (state == SCE_C_IDENTIFIER) { + } else if (state == SCE_COBOL_IDENTIFIER) { if (!isCOBOLwordchar(ch)) { int lStateChange = classifyWordCOBOL(styler.GetStartSegment(), i - 1, keywordlists, styler, nContainment, &bAarea);
@@ -253,64 +254,69 @@ static void ColouriseCOBOLDoc(Sci_PositionU startPos, Sci_Position length, int i nContainment = lStateChange; }
- state = SCE_C_DEFAULT; + state = SCE_COBOL_DEFAULT; chNext = styler.SafeGetCharAt(i + 1); - if (ch == '"') { - state = SCE_C_STRING; + if (column == 6 && (ch == '*' || ch == '/')) { + state = SCE_COBOL_COMMENTLINE; + } else if (ch == '"') { + state = SCE_COBOL_STRING; } else if (ch == ''') { - state = SCE_C_CHARACTER; + state = SCE_COBOL_CHARACTER; } else if (isCOBOLoperator(ch)) { - ColourTo(styler, i, SCE_C_OPERATOR); + ColourTo(styler, i, SCE_COBOL_OPERATOR); } } } else { - if (state == SCE_C_PREPROCESSOR) { + if (state == SCE_COBOL_PREPROCESSOR) { if ((ch == '\r' || ch == '\n') && !(chPrev == '\' || chPrev == '\r')) { ColourTo(styler, i-1, state); - state = SCE_C_DEFAULT; + state = SCE_COBOL_DEFAULT; } - } else if (state == SCE_C_COMMENT) { + } else if (state == SCE_COBOL_COMMENT) { if (ch == '\r' || ch == '\n') { - ColourTo(styler, i, state); - state = SCE_C_DEFAULT; + ColourTo(styler, i-1, state); + state = SCE_COBOL_DEFAULT; } - } else if (state == SCE_C_COMMENTDOC) { + } else if (state == SCE_COBOL_COMMENTDOC) { if (ch == '\r' || ch == '\n') { if (((i > styler.GetStartSegment() + 2) || ( - (initStyle == SCE_C_COMMENTDOC) && + (initStyle == SCE_COBOL_COMMENTDOC) && (styler.GetStartSegment() == static_cast<Sci_PositionU>(startPos))))) { - ColourTo(styler, i, state); - state = SCE_C_DEFAULT; + ColourTo(styler, i-1, state); + state = SCE_COBOL_DEFAULT; } } - } else if (state == SCE_C_COMMENTLINE) { + } else if (state == SCE_COBOL_COMMENTLINE) { if (ch == '\r' || ch == '\n') { ColourTo(styler, i-1, state); - state = SCE_C_DEFAULT; + state = SCE_COBOL_DEFAULT; } - } else if (state == SCE_C_STRING) { + } else if (state == SCE_COBOL_STRING) { if (ch == '"') { ColourTo(styler, i, state); - state = SCE_C_DEFAULT; + state = SCE_COBOL_DEFAULT; + } else if (ch == '\r' || ch == '\n') { + ColourTo(styler, i-1, state); + state = SCE_COBOL_DEFAULT; } - } else if (state == SCE_C_CHARACTER) { + } else if (state == SCE_COBOL_CHARACTER) { if (ch == ''') { ColourTo(styler, i, state); - state = SCE_C_DEFAULT; + state = SCE_COBOL_DEFAULT; } } } chPrev = ch; bNewLine = bSetNewLine; - if (bNewLine) - { - bAarea = false; - } + if (bNewLine) + { + bAarea = false; + } } ColourTo(styler, lengthDoc - 1, state); }
-static void FoldCOBOLDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], +void FoldCOBOLDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) { bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; Sci_PositionU endPos = startPos + length; @@ -321,41 +327,41 @@ static void FoldCOBOLDoc(Sci_PositionU startPos, Sci_Position length, int, WordL
bool bNewLine = true; bool bAarea = !isspacechar(chNext); - int column = 0; - bool bComment = false; + int column = 0; + bool bComment = false; for (Sci_PositionU i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); - ++column; + ++column;
if (bNewLine) { - column = 0; - bComment = (ch == '*' || ch == '/' || ch == '?'); + column = 0; + bComment = (ch == '*' || ch == '/' || ch == '?'); + } + if (column <= 1 && !bAarea) { + bAarea = !isspacechar(ch); } - if (column <= 1 && !bAarea) { - bAarea = !isspacechar(ch); - } bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (atEOL) { - int nContainment = styler.GetLineState(lineCurrent); + int nContainment = styler.GetLineState(lineCurrent); int lev = CountBits(nContainment & IN_FLAGS) | SC_FOLDLEVELBASE; - if (bAarea && !bComment) - --lev; + if (bAarea && !bComment) + --lev; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if ((bAarea) && (visibleChars > 0) && !(nContainment & NOT_HEADER) && !bComment) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } - if ((lev & SC_FOLDLEVELNUMBERMASK) <= (levelPrev & SC_FOLDLEVELNUMBERMASK)) { - // this level is at the same level or less than the previous line - // therefore these is nothing for the previous header to collapse, so remove the header - styler.SetLevel(lineCurrent - 1, levelPrev & ~SC_FOLDLEVELHEADERFLAG); - } + if ((lev & SC_FOLDLEVELNUMBERMASK) <= (levelPrev & SC_FOLDLEVELNUMBERMASK)) { + // this level is at the same level or less than the previous line + // therefore these is nothing for the previous header to collapse, so remove the header + styler.SetLevel(lineCurrent - 1, levelPrev & ~SC_FOLDLEVELHEADERFLAG); + } levelPrev = lev; visibleChars = 0; - bAarea = false; + bAarea = false; bNewLine = true; lineCurrent++; } else { @@ -372,11 +378,13 @@ static void FoldCOBOLDoc(Sci_PositionU startPos, Sci_Position length, int, WordL styler.SetLevel(lineCurrent, levelPrev | flagsNext); }
-static const char * const COBOLWordListDesc[] = { +const char * const COBOLWordListDesc[] = { "A Keywords", "B Keywords", "Extended Keywords", - 0 + nullptr };
-LexerModule lmCOBOL(SCLEX_COBOL, ColouriseCOBOLDoc, "COBOL", FoldCOBOLDoc, COBOLWordListDesc); +} + +extern const LexerModule lmCOBOL(SCLEX_COBOL, ColouriseCOBOLDoc, "COBOL", FoldCOBOLDoc, COBOLWordListDesc);
Modified: scintilla/lexilla/lexers/LexCPP.cxx 313 lines changed, 183 insertions(+), 130 deletions(-) =================================================================== @@ -87,17 +87,13 @@ bool followsReturnKeyword(const StyleContext &sc, LexAccessor &styler) { return !*s; }
-constexpr bool IsSpaceOrTab(int ch) noexcept { - return ch == ' ' || ch == '\t'; -} - constexpr bool IsOperatorOrSpace(int ch) noexcept { return isoperator(ch) || IsASpace(ch); }
-bool OnlySpaceOrTab(const std::string &s) noexcept { +bool OnlySpaceOrTab(std::string_view s) noexcept { for (const char ch : s) { - if (!IsSpaceOrTab(ch)) + if (!IsASpaceOrTab(ch)) return false; } return true; @@ -141,7 +137,7 @@ BracketPair FindBracketPair(Tokens &tokens) { }
void highlightTaskMarker(StyleContext &sc, LexAccessor &styler, - int activity, const WordList &markerList, bool caseSensitive){ + int activity, const WordList &markerList, bool caseSensitive) { if (IsOperatorOrSpace(sc.chPrev) && !IsOperatorOrSpace(sc.ch) && markerList.Length()) { std::string marker; for (Sci_PositionU currPos = sc.currentPos; true; currPos++) { @@ -160,16 +156,19 @@ void highlightTaskMarker(StyleContext &sc, LexAccessor &styler, } }
+const CharacterSet setHexDigits(CharacterSet::setDigits, "ABCDEFabcdef"); +const CharacterSet setOctDigits("01234567"); +const CharacterSet setNoneNumeric; + class EscapeSequence { - const CharacterSet setHexDigits = CharacterSet(CharacterSet::setDigits, "ABCDEFabcdef"); - const CharacterSet setOctDigits = CharacterSet("01234567"); - const CharacterSet setNoneNumeric; const CharacterSet *escapeSetValid = nullptr; int digitsLeft = 0; public: + int outerState = SCE_C_DEFAULT; EscapeSequence() = default; - void resetEscapeState(int nextChar) noexcept { + void resetEscapeState(int state, int nextChar) noexcept { digitsLeft = 0; + outerState = state; escapeSetValid = &setNoneNumeric; if (nextChar == 'U') { digitsLeft = 9; @@ -185,7 +184,7 @@ class EscapeSequence { escapeSetValid = &setOctDigits; } } - bool atEscapeEnd(int currChar) const noexcept { + [[nodiscard]] bool atEscapeEnd(int currChar) const noexcept { return (digitsLeft <= 0) || !escapeSetValid->Contains(currChar); } void consumeDigit() noexcept { @@ -233,7 +232,7 @@ struct PPDefinition { std::string value; bool isUndef; std::string arguments; - PPDefinition(Sci_Position line_, const std::string &key_, const std::string &value_, bool isUndef_ = false, const std::string &arguments_="") : + PPDefinition(Sci_Position line_, std::string_view key_, std::string_view value_, bool isUndef_, std::string_view arguments_) : line(line_), key(key_), value(value_), isUndef(isUndef_), arguments(arguments_) { } }; @@ -254,28 +253,27 @@ class LinePPState { // level is the nesting level of #if constructs int level = -1; static const int maximumNestingLevel = 31; - int maskLevel() const noexcept { + [[nodiscard]] int maskLevel() const noexcept { if (level >= 0) { return 1 << level; - } else { - return 1; } + return 1; } public: LinePPState() noexcept = default; - bool ValidLevel() const noexcept { + [[nodiscard]] bool ValidLevel() const noexcept { return level >= 0 && level < maximumNestingLevel; } - bool IsActive() const noexcept { + [[nodiscard]] bool IsActive() const noexcept { return state == 0; } - bool IsInactive() const noexcept { + [[nodiscard]] bool IsInactive() const noexcept { return state != 0; } - int ActiveState() const noexcept { + [[nodiscard]] int ActiveState() const noexcept { return state ? inactiveFlag : 0; } - bool CurrentIfTaken() const noexcept { + [[nodiscard]] bool CurrentIfTaken() const noexcept { return (ifTaken & maskLevel()) != 0; } void StartSection(bool on) noexcept { @@ -310,7 +308,7 @@ class LinePPState { class PPStates { std::vector<LinePPState> vlls; public: - LinePPState ForLine(Sci_Position line) const noexcept { + [[nodiscard]] LinePPState ForLine(Sci_Position line) const noexcept { if ((line > 0) && (vlls.size() > static_cast<size_t>(line))) { return vlls[line]; } @@ -322,6 +320,68 @@ class PPStates { } };
+enum class BackQuotedString : int { + None, + RawString, + TemplateLiteral, +}; + +// string interpolating state +struct InterpolatingState { + int state; + int braceCount; +}; + +struct Definition { + std::string_view name; + std::string_view value; + std::string_view arguments; +}; + +constexpr std::string_view TrimSpaceTab(std::string_view sv) noexcept { + while (!sv.empty() && IsASpaceOrTab(sv.front())) { + sv.remove_prefix(1); + } + return sv; +} + +// Parse a macro definition, either from a #define line in a file or from keywords. +// Either an object macro <NAME> <VALUE> or a function macro <NAME>(<ARGUMENTS>) <VALUE>. +// VALUE is optional and is treated as "1" if missing. +// #define ALLOW_PRINT +// #define VERSION 37 +// #define VER(a,b) a*10+b +// Whitespace separates macro and value in files but keywords use '=' separator. +// 'endName' contains a set of characters that terminate the name of the macro. + +constexpr Definition ParseDefine(std::string_view definition, std::string_view endName) { + Definition ret; + definition = TrimSpaceTab(definition); + const size_t afterName = definition.find_first_of(endName); + if (afterName != std::string_view::npos) { + ret.name = definition.substr(0, afterName); + if (definition.at(afterName) == '(') { + // Macro + definition.remove_prefix(afterName+1); + const size_t closeBracket = definition.find(')'); + if (closeBracket != std::string_view::npos) { + ret.arguments = definition.substr(0, closeBracket); + definition.remove_prefix(closeBracket+1); + if (!definition.empty() && (endName.find(definition.front()) != std::string_view::npos)) { + definition.remove_prefix(1); + } + ret.value = definition; + } // else malformed as requires closing bracket + } else { + ret.value = definition.substr(afterName+1); + } + } else { + ret.name = definition; + ret.value = "1"; + } + return ret; +} + // An individual named option for use in an OptionSet
// Options used for LexerCPP @@ -333,7 +393,7 @@ struct OptionsCPP { bool verbatimStringsAllowEscapes = false; bool triplequotedStrings = false; bool hashquotedStrings = false; - bool backQuotedStrings = false; + BackQuotedString backQuotedStrings = BackQuotedString::None; bool escapeSequence = false; bool fold = false; bool foldSyntaxBased = true; @@ -385,7 +445,10 @@ struct OptionSetCPP : public OptionSet<OptionsCPP> { "Set to 1 to enable highlighting of hash-quoted strings.");
DefineProperty("lexer.cpp.backquoted.strings", &OptionsCPP::backQuotedStrings, - "Set to 1 to enable highlighting of back-quoted raw strings ."); + "Set how to highlighting back-quoted strings. " + "0 (the default) no highlighting. " + "1 highlighted as Go raw string. " + "2 highlighted as JavaScript template literal.");
DefineProperty("lexer.cpp.escape.sequence", &OptionsCPP::escapeSequence, "Set to 1 to enable highlighting of escape sequences in strings"); @@ -480,6 +543,7 @@ class LexerCPP : public ILexer5 { CharacterSet setWordStart; PPStates vlls; std::vector<PPDefinition> ppDefineHistory; + std::map<Sci_Position, std::vector<InterpolatingState>> interpolatingAtEol; WordList keywords; WordList keywords2; WordList keywords3; @@ -490,25 +554,25 @@ class LexerCPP : public ILexer5 { std::string value; std::string arguments; SymbolValue() noexcept = default; - SymbolValue(const std::string &value_, const std::string &arguments_) : value(value_), arguments(arguments_) { + SymbolValue(std::string_view value_, std::string_view arguments_) : value(value_), arguments(arguments_) { } SymbolValue &operator = (const std::string &value_) { value = value_; arguments.clear(); return *this; } - bool IsMacro() const noexcept { + [[nodiscard]] bool IsMacro() const noexcept { return !arguments.empty(); } }; - typedef std::map<std::string, SymbolValue> SymbolTable; + using SymbolTable = std::map<std::string, SymbolValue>; SymbolTable preprocessorDefinitionsStart; OptionsCPP options; OptionSetCPP osCPP; EscapeSequence escapeSeq; SparseStatestd::string rawStringTerminators; enum { ssIdentifier, ssDocKeyword }; - SubStyles subStyles; + SubStyles subStyles{ styleSubable, SubStylesFirst, SubStylesAvailable, inactiveFlag }; std::string returnBuffer; public: explicit LexerCPP(bool caseSensitive_) : @@ -518,40 +582,38 @@ class LexerCPP : public ILexer5 { setAddOp("+-"), setMultOp("*/%"), setRelOp("=!<>"), - setLogicalOp("|&"), - subStyles(styleSubable, 0x80, 0x40, inactiveFlag) { + setLogicalOp("|&") { } // Deleted so LexerCPP objects can not be copied. LexerCPP(const LexerCPP &) = delete; LexerCPP(LexerCPP &&) = delete; void operator=(const LexerCPP &) = delete; void operator=(LexerCPP &&) = delete; - virtual ~LexerCPP() { - } + virtual ~LexerCPP() = default; void SCI_METHOD Release() noexcept override { delete this; } int SCI_METHOD Version() const noexcept override { return lvRelease5; } - const char * SCI_METHOD PropertyNames() override { + const char *SCI_METHOD PropertyNames() override { return osCPP.PropertyNames(); } int SCI_METHOD PropertyType(const char *name) override { return osCPP.PropertyType(name); } - const char * SCI_METHOD DescribeProperty(const char *name) override { + const char *SCI_METHOD DescribeProperty(const char *name) override { return osCPP.DescribeProperty(name); } Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override; - const char * SCI_METHOD DescribeWordListSets() override { + const char *SCI_METHOD DescribeWordListSets() override { return osCPP.DescribeWordListSets(); } Sci_Position SCI_METHOD WordListSet(int n, const char *wl) 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 *) noexcept override { + void *SCI_METHOD PrivateCall(int, void *) noexcept override { return nullptr; }
@@ -585,23 +647,23 @@ class LexerCPP : public ILexer5 { int SCI_METHOD DistanceToSecondaryStyles() noexcept override { return inactiveFlag; } - const char * SCI_METHOD GetSubStyleBases() noexcept override { + const char *SCI_METHOD GetSubStyleBases() noexcept override { return styleSubable; } int SCI_METHOD NamedStyles() override { return std::max(subStyles.LastAllocated() + 1, sizeLexicalClasses) + inactiveFlag; } - const char * SCI_METHOD NameOfStyle(int style) override { + const char *SCI_METHOD NameOfStyle(int style) override { if (style >= NamedStyles()) return ""; if (style < sizeLexicalClasses) return lexicalClasses[style].name; // TODO: inactive and substyles return ""; } - const char * SCI_METHOD TagsOfStyle(int style) override { + const char *SCI_METHOD TagsOfStyle(int style) override { if (style >= NamedStyles()) return "Excess"; returnBuffer.clear(); @@ -633,7 +695,7 @@ class LexerCPP : public ILexer5 { } return ""; } - const char * SCI_METHOD DescriptionOfStyle(int style) override { + const char *SCI_METHOD DescriptionOfStyle(int style) override { if (style >= NamedStyles()) return ""; if (style < sizeLexicalClasses) @@ -643,13 +705,13 @@ class LexerCPP : public ILexer5 { }
// ILexer5 methods - const char * SCI_METHOD GetName() override { + 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; + const char *SCI_METHOD PropertyGet(const char *key) override;
static ILexer5 *LexerFactoryCPP() { return new LexerCPP(true); @@ -661,7 +723,7 @@ class LexerCPP : public ILexer5 { return style & ~inactiveFlag; } void EvaluateTokens(Tokens &tokens, const SymbolTable &preprocessorDefinitions); - Tokens Tokenize(const std::string &expr) const; + [[nodiscard]] Tokens Tokenize(const std::string &expr) const; bool EvaluateExpression(const std::string &expr, const SymbolTable &preprocessorDefinitions); };
@@ -678,7 +740,7 @@ Sci_Position SCI_METHOD LexerCPP::PropertySet(const char *key, const char *val) return -1; }
-const char * SCI_METHOD LexerCPP::PropertyGet(const char *key) { +const char *SCI_METHOD LexerCPP::PropertyGet(const char *key) { return osCPP.PropertyGet(key); }
@@ -714,26 +776,8 @@ Sci_Position SCI_METHOD LexerCPP::WordListSet(int n, const char *wl) { // Rebuild preprocessorDefinitions preprocessorDefinitionsStart.clear(); for (int nDefinition = 0; nDefinition < ppDefinitions.Length(); nDefinition++) { - const char *cpDefinition = ppDefinitions.WordAt(nDefinition); - const char *cpEquals = strchr(cpDefinition, '='); - if (cpEquals) { - std::string name(cpDefinition, cpEquals - cpDefinition); - std::string val(cpEquals+1); - const size_t bracket = name.find('('); - const size_t bracketEnd = name.find(')'); - if ((bracket != std::string::npos) && (bracketEnd != std::string::npos)) { - // Macro - std::string args = name.substr(bracket + 1, bracketEnd - bracket - 1); - name = name.substr(0, bracket); - preprocessorDefinitionsStart[name] = SymbolValue(val, args); - } else { - preprocessorDefinitionsStart[name] = val; - } - } else { - std::string name(cpDefinition); - std::string val("1"); - preprocessorDefinitionsStart[name] = val; - } + const Definition def = ParseDefine(ppDefinitions.WordAt(nDefinition), "(="); + preprocessorDefinitionsStart[std::string(def.name)] = SymbolValue(def.value, def.arguments); } } } @@ -747,7 +791,7 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i const StyleContext::Transform transform = caseSensitive ? StyleContext::Transform::none : StyleContext::Transform::lower;
- const CharacterSet setOKBeforeRE("([{=,:;!%^&*|?~+-"); + const CharacterSet setOKBeforeRE("([{=,:;!%^&*|?~+-> "); const CharacterSet setCouldBePostOp("+-");
const CharacterSet setDoxygen(CharacterSet::setAlpha, "$@\&<>#{}[]"); @@ -771,7 +815,21 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i bool inRERange = false; bool seenDocKeyBrace = false;
+ std::vector<InterpolatingState> interpolatingStack; + Sci_Position lineCurrent = styler.GetLine(startPos); + if (options.backQuotedStrings == BackQuotedString::TemplateLiteral) { + // code copied from LexPython + auto it = interpolatingAtEol.find(lineCurrent - 1); + if (it != interpolatingAtEol.end()) { + interpolatingStack = it->second; + } + it = interpolatingAtEol.lower_bound(lineCurrent); + if (it != interpolatingAtEol.end()) { + interpolatingAtEol.erase(it, interpolatingAtEol.end()); + } + } + if ((MaskActive(initStyle) == SCE_C_PREPROCESSOR) || (MaskActive(initStyle) == SCE_C_COMMENTLINE) || (MaskActive(initStyle) == SCE_C_COMMENTLINEDOC)) { @@ -832,6 +890,12 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i
Sci_PositionU lineEndNext = styler.LineEnd(lineCurrent);
+ if (sc.currentPos == 0 && sc.Match('#', '!')) { + // Shell Shebang at beginning of file + sc.SetState(SCE_C_COMMENTLINE); + sc.Forward(); + } + for (; sc.More();) {
if (sc.atLineStart) { @@ -864,6 +928,9 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i if (!rawStringTerminator.empty()) { rawSTNew.Set(lineCurrent-1, rawStringTerminator); } + if (!interpolatingStack.empty()) { + interpolatingAtEol[sc.currentLine] = interpolatingStack; + } }
// Handle line continuation generically. @@ -899,8 +966,7 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i sc.ChangeState(SCE_C_USERLITERAL|activitySet); } else if (!(setWord.Contains(sc.ch) || (sc.ch == ''') - || ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E' || - sc.chPrev == 'p' || sc.chPrev == 'P')))) { + || (AnyOf(sc.chPrev, 'e', 'E', 'p', 'P') && AnyOf(sc.ch, '+', '-')))) { sc.SetState(SCE_C_DEFAULT|activitySet); } break; @@ -1007,7 +1073,7 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i styleBeforeDCKeyword = SCE_C_COMMENTDOC; sc.SetState(SCE_C_COMMENTDOCKEYWORD|activitySet); } - } else if ((sc.ch == '<' && sc.chNext != '/') + } else if ((sc.ch == '<' && !(IsASpace(sc.chNext) || sc.chNext == '/')) || (sc.ch == '/' && sc.chPrev == '<')) { // XML comment style styleBeforeDCKeyword = SCE_C_COMMENTDOC; sc.ForwardSetState(SCE_C_COMMENTDOCKEYWORD | activitySet); @@ -1045,13 +1111,13 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i } else if (sc.ch == '[' || sc.ch == '{') { seenDocKeyBrace = true; } else if (!setDoxygen.Contains(sc.ch) - && !(seenDocKeyBrace && (sc.ch == ',' || sc.ch == '.'))) { + && !(seenDocKeyBrace && AnyOf(sc.ch, ',', '.'))) { if (!(IsASpace(sc.ch) || (sc.ch == 0))) { sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR|activitySet); } else { sc.GetCurrentString(currentText, transform); assert(!currentText.empty()); - std::string currentSuffix = currentText.substr(1); + const std::string currentSuffix = currentText.substr(1); if (!keywords3.InList(currentSuffix) && !keywords3.InList(currentText)) { const int subStyleCDKW = classifierDocKeyWords.ValueFor(currentSuffix); if (subStyleCDKW >= 0) { @@ -1087,8 +1153,8 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i } } else if (sc.ch == '\') { if (options.escapeSequence) { + escapeSeq.resetEscapeState(sc.state, sc.chNext); sc.SetState(SCE_C_ESCAPESEQUENCE|activitySet); - escapeSeq.resetEscapeState(sc.chNext); } sc.Forward(); // Skip all characters after the backslash } else if (sc.ch == '"') { @@ -1101,20 +1167,9 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i break; case SCE_C_ESCAPESEQUENCE: escapeSeq.consumeDigit(); - if (!escapeSeq.atEscapeEnd(sc.ch)) { - break; - } - if (sc.ch == '"') { - sc.SetState(SCE_C_STRING|activitySet); - sc.ForwardSetState(SCE_C_DEFAULT|activitySet); - } else if (sc.ch == '\') { - escapeSeq.resetEscapeState(sc.chNext); - sc.Forward(); - } else { - sc.SetState(SCE_C_STRING|activitySet); - if (sc.atLineEnd) { - sc.ChangeState(SCE_C_STRINGEOL|activitySet); - } + if (escapeSeq.atEscapeEnd(sc.ch)) { + sc.SetState(escapeSeq.outerState); + continue; } break; case SCE_C_HASHQUOTEDSTRING: @@ -1131,7 +1186,21 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i for (size_t termPos=rawStringTerminator.size(); termPos; termPos--) sc.Forward(); sc.SetState(SCE_C_DEFAULT|activitySet); - rawStringTerminator.clear(); + if (interpolatingStack.empty()) { + rawStringTerminator.clear(); + } + } else if (options.backQuotedStrings == BackQuotedString::TemplateLiteral) { + if (sc.ch == '\') { + if (options.escapeSequence) { + escapeSeq.resetEscapeState(sc.state, sc.chNext); + sc.SetState(SCE_C_ESCAPESEQUENCE|activitySet); + } + sc.Forward(); // Skip all characters after the backslash + } else if (sc.Match('$', '{')) { + interpolatingStack.push_back({sc.state, 1}); + sc.SetState(SCE_C_OPERATOR|activitySet); + sc.Forward(); + } } break; case SCE_C_CHARACTER: @@ -1222,7 +1291,7 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i } else if (options.hashquotedStrings && sc.Match('#', '"')) { sc.SetState(SCE_C_HASHQUOTEDSTRING|activitySet); sc.Forward(); - } else if (options.backQuotedStrings && sc.Match('`')) { + } else if ((options.backQuotedStrings != BackQuotedString::None) && sc.Match('`')) { sc.SetState(SCE_C_STRINGRAW|activitySet); rawStringTerminator = "`"; } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { @@ -1336,7 +1405,7 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i // Inactive, if expression true then may become active if parent scope active assert(sc.state == (SCE_C_PREPROCESSOR | inactiveFlag)); // Similar to #if - std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 4, true); + const std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 4, true); const bool ifGood = EvaluateExpression(restOfLine, preprocessorDefinitions); if (ifGood) { preproc.InvertCurrentLevel(); @@ -1358,41 +1427,11 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i sc.ChangeState(SCE_C_PREPROCESSOR|activitySet); } else if (sc.Match("define")) { if (options.updatePreprocessor && preproc.IsActive()) { - std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 6, true); - size_t startName = 0; - while ((startName < restOfLine.length()) && IsSpaceOrTab(restOfLine[startName])) - startName++; - size_t endName = startName; - while ((endName < restOfLine.length()) && setWord.Contains(restOfLine[endName])) - endName++; - std::string key = restOfLine.substr(startName, endName-startName); - if ((endName < restOfLine.length()) && (restOfLine.at(endName) == '(')) { - // Macro - size_t endArgs = endName; - while ((endArgs < restOfLine.length()) && (restOfLine[endArgs] != ')')) - endArgs++; - std::string args = restOfLine.substr(endName + 1, endArgs - endName - 1); - size_t startValue = endArgs+1; - while ((startValue < restOfLine.length()) && IsSpaceOrTab(restOfLine[startValue])) - startValue++; - std::string value; - if (startValue < restOfLine.length()) - value = restOfLine.substr(startValue); - preprocessorDefinitions[key] = SymbolValue(value, args); - ppDefineHistory.push_back(PPDefinition(lineCurrent, key, value, false, args)); - definitionsChanged = true; - } else { - // Value - size_t startValue = endName; - while ((startValue < restOfLine.length()) && IsSpaceOrTab(restOfLine[startValue])) - startValue++; - std::string value = restOfLine.substr(startValue); - if (OnlySpaceOrTab(value)) - value = "1"; // No value defaults to 1 - preprocessorDefinitions[key] = value; - ppDefineHistory.push_back(PPDefinition(lineCurrent, key, value)); - definitionsChanged = true; - } + const std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 6, true); + const Definition def = ParseDefine(restOfLine, "( \t"); + preprocessorDefinitions[std::string(def.name)] = SymbolValue(def.value, def.arguments); + ppDefineHistory.emplace_back(lineCurrent, def.name, def.value, false, def.arguments); + definitionsChanged = true; } } else if (sc.Match("undef")) { if (options.updatePreprocessor && preproc.IsActive()) { @@ -1401,7 +1440,7 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i if (!tokens.empty()) { const std::string key = tokens[0]; preprocessorDefinitions.erase(key); - ppDefineHistory.push_back(PPDefinition(lineCurrent, key, "", true)); + ppDefineHistory.emplace_back(lineCurrent, key, "", true, ""); definitionsChanged = true; } } @@ -1410,6 +1449,19 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci@@ Diff output truncated at 100000 characters. @@
-------------- This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).