diff options
-rw-r--r-- | cocoa/PlatCocoa.mm | 16 | ||||
-rw-r--r-- | cocoa/ScintillaTest/AppController.mm | 43 | ||||
-rw-r--r-- | doc/ScintillaDownload.html | 10 | ||||
-rw-r--r-- | doc/ScintillaHistory.html | 12 | ||||
-rw-r--r-- | doc/ScintillaRelated.html | 8 | ||||
-rw-r--r-- | doc/index.html | 7 | ||||
-rw-r--r-- | gtk/PlatGTK.cxx | 23 | ||||
-rw-r--r-- | gtk/ScintillaGTK.cxx | 2 | ||||
-rw-r--r-- | include/SciLexer.h | 19 | ||||
-rw-r--r-- | include/Scintilla.iface | 21 | ||||
-rw-r--r-- | lexers/LexAU3.cxx | 2 | ||||
-rw-r--r-- | lexers/LexCPP.cxx | 21 | ||||
-rw-r--r-- | lexers/LexConf.cxx | 2 | ||||
-rw-r--r-- | lexers/LexHTML.cxx | 12 | ||||
-rw-r--r-- | lexers/LexLua.cxx | 82 | ||||
-rw-r--r-- | lexers/LexMagik.cxx | 2 | ||||
-rw-r--r-- | lexers/LexMarkdown.cxx | 23 | ||||
-rw-r--r-- | lexers/LexModula.cxx | 4 | ||||
-rw-r--r-- | lexers/LexOthers.cxx | 250 | ||||
-rw-r--r-- | lexers/LexPerl.cxx | 371 | ||||
-rw-r--r-- | lexers/LexPowerPro.cxx | 2 | ||||
-rw-r--r-- | lexers/LexTeX.cxx | 2 | ||||
-rw-r--r-- | lexers/LexVHDL.cxx | 2 | ||||
-rw-r--r-- | lexlib/SparseState.h | 2 | ||||
-rw-r--r-- | src/Decoration.cxx | 4 | ||||
-rw-r--r-- | src/Document.cxx | 6 | ||||
-rw-r--r-- | src/Editor.cxx | 8 | ||||
-rw-r--r-- | version.txt | 2 | ||||
-rw-r--r-- | win32/PlatWin.cxx | 32 | ||||
-rw-r--r-- | win32/ScintRes.rc | 8 | ||||
-rw-r--r-- | win32/ScintillaWin.cxx | 7 |
31 files changed, 814 insertions, 191 deletions
diff --git a/cocoa/PlatCocoa.mm b/cocoa/PlatCocoa.mm index 9b4455237..ce112f853 100644 --- a/cocoa/PlatCocoa.mm +++ b/cocoa/PlatCocoa.mm @@ -1383,7 +1383,10 @@ static NSImage* ImageFromXPM(XPM* pxpm) img = [NSImage alloc]; [img autorelease]; CGImageRef imageRef = surfaceIXPM->GetImage(); - [img initWithCGImage:imageRef size:NSZeroSize]; + [img initWithSize:NSZeroSize]; + NSBitmapImageRep *bitmapRep = [[NSBitmapImageRep alloc] initWithCGImage: imageRef]; + [img addRepresentation: bitmapRep]; + [bitmapRep release]; CGImageRelease(imageRef); delete surfaceXPM; } @@ -1464,7 +1467,10 @@ public: class ListBoxImpl; @interface AutoCompletionDataSource : -NSObject <NSTableViewDataSource> +NSObject +#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 +<NSTableViewDataSource> +#endif { ListBoxImpl* box; } @@ -1841,7 +1847,10 @@ void ListBoxImpl::RegisterRGBAImage(int type, int width, int height, const unsig [img autorelease]; CGImageRef imageRef = ImageFromRGBA(width, height, pixelsImage, false); NSSize sz = {width, height}; - [img initWithCGImage:imageRef size:sz]; + [img initWithSize: sz]; + NSBitmapImageRep *bitmapRep = [[NSBitmapImageRep alloc] initWithCGImage: imageRef]; + [img addRepresentation: bitmapRep]; + [bitmapRep release]; CGImageRelease(imageRef); [img retain]; ImageMap::iterator it=images.find(type); @@ -1878,7 +1887,6 @@ NSImage* ListBoxImpl::ImageForRow(NSInteger row) if (it != images.end()) { NSImage* img = it->second; - [img retain]; return img; } else diff --git a/cocoa/ScintillaTest/AppController.mm b/cocoa/ScintillaTest/AppController.mm index fbcdad9a8..294704f02 100644 --- a/cocoa/ScintillaTest/AppController.mm +++ b/cocoa/ScintillaTest/AppController.mm @@ -211,6 +211,47 @@ const char user_keywords[] = // Definition of own keywords, not used by MySQL. //-------------------------------------------------------------------------------------------------- +/* XPM */ +static const char * box_xpm[] = { + "12 12 2 1", + " c None", + ". c #800000", + " .........", + " . . ..", + " . . . .", + "......... .", + ". . . .", + ". . . ..", + ". . .. .", + "......... .", + ". . . .", + ". . . . ", + ". . .. ", + "......... "}; + + +- (void) showAutocompletion +{ + const char *words = "Babylon-5?1 Battlestar-Galactica Millenium-Falcon?2 Moya?2 Serenity Voyager"; + [mEditor setGeneralProperty: SCI_AUTOCSETIGNORECASE parameter: 1 value:0]; + [mEditor setGeneralProperty: SCI_REGISTERIMAGE parameter: 1 value:(sptr_t)box_xpm]; + const int imSize = 12; + [mEditor setGeneralProperty: SCI_RGBAIMAGESETWIDTH parameter: imSize value:0]; + [mEditor setGeneralProperty: SCI_RGBAIMAGESETHEIGHT parameter: imSize value:0]; + char image[imSize * imSize * 4]; + for (size_t y = 0; y < imSize; y++) { + for (size_t x = 0; x < imSize; x++) { + char *p = image + (y * imSize + x) * 4; + p[0] = 0xFF; + p[1] = 0xA0; + p[2] = 0; + p[3] = x * 23; + } + } + [mEditor setGeneralProperty: SCI_REGISTERRGBAIMAGE parameter: 2 value:(sptr_t)image]; + [mEditor setGeneralProperty: SCI_AUTOCSHOW parameter: 0 value:(sptr_t)words]; +} + - (IBAction) searchText: (id) sender { NSSearchField* searchField = (NSSearchField*) sender; @@ -219,6 +260,8 @@ const char user_keywords[] = // Definition of own keywords, not used by MySQL. wholeWord: NO scrollTo: YES wrap: YES]; + if ([[searchField stringValue] isEqualToString: @"XX"]) + [self showAutocompletion]; } @end diff --git a/doc/ScintillaDownload.html b/doc/ScintillaDownload.html index a5fa814dc..8744778e8 100644 --- a/doc/ScintillaDownload.html +++ b/doc/ScintillaDownload.html @@ -25,9 +25,9 @@ <table bgcolor="#CCCCCC" width="100%" cellspacing="0" cellpadding="8" border="0"> <tr> <td> - <font size="4"> <a href="http://prdownloads.sourceforge.net/scintilla/scintilla228.zip?download"> + <font size="4"> <a href="http://prdownloads.sourceforge.net/scintilla/scintilla229.zip?download"> Windows</a> - <a href="http://prdownloads.sourceforge.net/scintilla/scintilla228.tgz?download"> + <a href="http://prdownloads.sourceforge.net/scintilla/scintilla229.tgz?download"> GTK+/Linux</a> </font> </td> @@ -41,7 +41,7 @@ containing very few restrictions. </p> <h3> - Release 2.28 + Release 2.29 </h3> <h4> Source Code @@ -49,8 +49,8 @@ The source code package contains all of the source code for Scintilla but no binary executable code and is available in <ul> - <li><a href="http://prdownloads.sourceforge.net/scintilla/scintilla228.zip?download">zip format</a> (1200K) commonly used on Windows</li> - <li><a href="http://prdownloads.sourceforge.net/scintilla/scintilla228.tgz?download">tgz format</a> (1080K) commonly used on Linux and compatible operating systems</li> + <li><a href="http://prdownloads.sourceforge.net/scintilla/scintilla229.zip?download">zip format</a> (1200K) commonly used on Windows</li> + <li><a href="http://prdownloads.sourceforge.net/scintilla/scintilla229.tgz?download">tgz format</a> (1080K) commonly used on Linux and compatible operating systems</li> </ul> Instructions for building on both Windows and Linux are included in the readme file. <h4> diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html index 5f2575fc4..b9423780e 100644 --- a/doc/ScintillaHistory.html +++ b/doc/ScintillaHistory.html @@ -380,6 +380,10 @@ <td>Thomas Linder Puls</td> <td>Artyom Zuikov</td> <td>Gerrit</td> + </tr><tr> + <td>Occam's Razor</td> + <td>Ben Bluemel</td> + <td>David Wolfendale</td> </tr> </table> <p> @@ -392,6 +396,14 @@ </li> </ul> <h3> + <a href="http://prdownloads.sourceforge.net/scintilla/scite229.zip?download">Release 2.29</a> + </h3> + <ul> + <li> + Released 12 September 2011. + </li> + </ul> + <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite228.zip?download">Release 2.28</a> </h3> <ul> diff --git a/doc/ScintillaRelated.html b/doc/ScintillaRelated.html index c4a89f9a0..7c6e6a486 100644 --- a/doc/ScintillaRelated.html +++ b/doc/ScintillaRelated.html @@ -29,6 +29,10 @@ Ports and Bindings of Scintilla </h3> <p> + <a href="https://metacpan.org/module/AZAWAWI/Wx-Scintilla-0.21_03/lib/Wx/Scintilla.pm">Wx::Scintilla</a> + is a Perl Binding for Scintilla on wxWidgets. + </p> + <p> <a href="http://codebrainz.github.com/GtkScintilla/">GtkScintilla</a> is a GTK+ widget which enables easily adding a powerful source code editor to your applications. Harnessing the abilities @@ -115,6 +119,10 @@ Projects using Scintilla </h3> <p> + <a href="http://padre.perlide.org/">Padre</a> + is a wxWidgets-based Perl IDE. + </p> + <p> <a href="http://manoscoder.gr/CoderStudio/CoderStudio.asp">CoderStudio</a> is an IDE for Assembly programming similar to Visual Studio 6.0. </p> diff --git a/doc/index.html b/doc/index.html index 815f35d91..277165c19 100644 --- a/doc/index.html +++ b/doc/index.html @@ -9,7 +9,7 @@ <meta name="keywords" content="Scintilla, SciTE, Editing Component, Text Editor" /> <meta name="Description" content="www.scintilla.org is the home of the Scintilla editing component and SciTE text editor application." /> - <meta name="Date.Modified" content="20110801" /> + <meta name="Date.Modified" content="20110912" /> <style type="text/css"> #versionlist { margin: 0; @@ -55,8 +55,8 @@ GTK+</font> </td> <td width="40%" align="right"> - <font color="#FFCC99" size="3"> Release version 2.28<br /> - Site last modified August 1 2011</font> + <font color="#FFCC99" size="3"> Release version 2.29<br /> + Site last modified September 12 2011</font> </td> <td width="20%"> @@ -71,6 +71,7 @@ </tr> </table> <ul id="versionlist"> + <li>Version 2.29 fixes bugs.</li> <li>Version 2.28 allows translucent images in RGBA format to be used for margin markers and in autocompletion lists.</li> <li>Version 2.27 fixes incorrect colours on some versions of GTK+.</li> <li>Version 2.26 can highlight folding margin symbols for the current folding block. Experimental support for GTK+ 3.</li> diff --git a/gtk/PlatGTK.cxx b/gtk/PlatGTK.cxx index a8bd051a8..ffb04d005 100644 --- a/gtk/PlatGTK.cxx +++ b/gtk/PlatGTK.cxx @@ -43,9 +43,7 @@ #define IS_WIDGET_FOCUSSED(w) (GTK_WIDGET_HAS_FOCUS(w)) #endif -#if GTK_CHECK_VERSION(2,22,0) #define USE_CAIRO 1 -#endif #ifdef USE_CAIRO @@ -1589,7 +1587,6 @@ void SurfaceImpl::DrawTextBase(PRectangle rc, Font &font_, XYPOSITION ybase, con XYPOSITION xText = rc.left; if (PFont(font_)->pfd) { char *utfForm = 0; - bool useGFree = false; if (et == UTF8) { pango_layout_set_text(layout, s, len); } else { @@ -1623,11 +1620,7 @@ void SurfaceImpl::DrawTextBase(PRectangle rc, Font &font_, XYPOSITION ybase, con #else gdk_draw_layout_line(drawable, gc, xText, ybase, pll); #endif - if (useGFree) { - g_free(utfForm); - } else { - delete []utfForm; - } + delete []utfForm; return; } #ifndef DISABLE_GDK_FONT @@ -1805,7 +1798,6 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, XYPOSITION } if (positionsCalculated < 1 ) { // Either Latin1 or DBCS conversion failed so treat as Latin1. - bool useGFree = false; SetConverter(PFont(font_)->characterSet); char *utfForm = UTF8FromIconv(conv, s, len); if (!utfForm) { @@ -1827,11 +1819,7 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, XYPOSITION } clusterStart = clusterEnd; } - if (useGFree) { - g_free(utfForm); - } else { - delete []utfForm; - } + delete []utfForm; PLATFORM_ASSERT(i == lenPositions); } } @@ -1907,7 +1895,6 @@ XYPOSITION SurfaceImpl::WidthText(Font &font_, const char *s, int len) { char *utfForm = 0; pango_layout_set_font_description(layout, PFont(font_)->pfd); PangoRectangle pos; - bool useGFree = false; if (et == UTF8) { pango_layout_set_text(layout, s, len); } else { @@ -1930,11 +1917,7 @@ XYPOSITION SurfaceImpl::WidthText(Font &font_, const char *s, int len) { PangoLayoutLine *pangoLine = pango_layout_get_line(layout,0); #endif pango_layout_line_get_extents(pangoLine, NULL, &pos); - if (useGFree) { - g_free(utfForm); - } else { - delete []utfForm; - } + delete []utfForm; return pango_units_to_double(pos.width); } #ifndef DISABLE_GDK_FONT diff --git a/gtk/ScintillaGTK.cxx b/gtk/ScintillaGTK.cxx index 2b2a7c689..efb0e0cd5 100644 --- a/gtk/ScintillaGTK.cxx +++ b/gtk/ScintillaGTK.cxx @@ -74,9 +74,7 @@ #define IS_WIDGET_VISIBLE(w) (GTK_WIDGET_VISIBLE(w)) #endif -#if GTK_CHECK_VERSION(2,22,0) #define USE_CAIRO 1 -#endif static GdkWindow *WindowFromWidget(GtkWidget *w) { #if GTK_CHECK_VERSION(3,0,0) diff --git a/include/SciLexer.h b/include/SciLexer.h index 1d5b69ede..e8805f2d6 100644 --- a/include/SciLexer.h +++ b/include/SciLexer.h @@ -344,6 +344,16 @@ #define SCE_PL_SUB_PROTOTYPE 40 #define SCE_PL_FORMAT_IDENT 41 #define SCE_PL_FORMAT 42 +#define SCE_PL_STRING_VAR 43 +#define SCE_PL_XLAT 44 +#define SCE_PL_REGEX_VAR 54 +#define SCE_PL_REGSUBST_VAR 55 +#define SCE_PL_BACKTICKS_VAR 57 +#define SCE_PL_HERE_QQ_VAR 61 +#define SCE_PL_HERE_QX_VAR 62 +#define SCE_PL_STRING_QQ_VAR 64 +#define SCE_PL_STRING_QX_VAR 65 +#define SCE_PL_STRING_QR_VAR 66 #define SCE_RB_DEFAULT 0 #define SCE_RB_ERROR 1 #define SCE_RB_COMMENTLINE 2 @@ -408,6 +418,14 @@ #define SCE_L_TAG 2 #define SCE_L_MATH 3 #define SCE_L_COMMENT 4 +#define SCE_L_TAG2 5 +#define SCE_L_MATH2 6 +#define SCE_L_COMMENT2 7 +#define SCE_L_VERBATIM 8 +#define SCE_L_SHORTCMD 9 +#define SCE_L_SPECIAL 10 +#define SCE_L_CMDOPT 11 +#define SCE_L_ERROR 12 #define SCE_LUA_DEFAULT 0 #define SCE_LUA_COMMENT 1 #define SCE_LUA_COMMENTLINE 2 @@ -428,6 +446,7 @@ #define SCE_LUA_WORD6 17 #define SCE_LUA_WORD7 18 #define SCE_LUA_WORD8 19 +#define SCE_LUA_LABEL 20 #define SCE_ERR_DEFAULT 0 #define SCE_ERR_PYTHON 1 #define SCE_ERR_GCC 2 diff --git a/include/Scintilla.iface b/include/Scintilla.iface index 08a77b605..23da6d5b5 100644 --- a/include/Scintilla.iface +++ b/include/Scintilla.iface @@ -2184,7 +2184,7 @@ set void RGBAImageSetHeight=2625(int height,) # It has the width and height from RGBAImageSetWidth/Height fun void MarkerDefineRGBAImage=2626(int markerNumber, string pixels) -# Register an RGBA image for use in autocompletion lists. +# Register an RGBA image for use in autocompletion lists. # It has the width and height from RGBAImageSetWidth/Height fun void RegisterRGBAImage=2627(int type, string pixels) @@ -2711,6 +2711,16 @@ val SCE_PL_POD_VERB=31 val SCE_PL_SUB_PROTOTYPE=40 val SCE_PL_FORMAT_IDENT=41 val SCE_PL_FORMAT=42 +val SCE_PL_STRING_VAR=43 +val SCE_PL_XLAT=44 +val SCE_PL_REGEX_VAR=54 +val SCE_PL_REGSUBST_VAR=55 +val SCE_PL_BACKTICKS_VAR=57 +val SCE_PL_HERE_QQ_VAR=61 +val SCE_PL_HERE_QX_VAR=62 +val SCE_PL_STRING_QQ_VAR=64 +val SCE_PL_STRING_QX_VAR=65 +val SCE_PL_STRING_QR_VAR=66 # Lexical states for SCLEX_RUBY lex Ruby=SCLEX_RUBY SCE_RB_ val SCE_RB_DEFAULT=0 @@ -2785,6 +2795,14 @@ val SCE_L_COMMAND=1 val SCE_L_TAG=2 val SCE_L_MATH=3 val SCE_L_COMMENT=4 +val SCE_L_TAG2=5 +val SCE_L_MATH2=6 +val SCE_L_COMMENT2=7 +val SCE_L_VERBATIM=8 +val SCE_L_SHORTCMD=9 +val SCE_L_SPECIAL=10 +val SCE_L_CMDOPT=11 +val SCE_L_ERROR=12 # Lexical states for SCLEX_LUA lex Lua=SCLEX_LUA SCE_LUA_ val SCE_LUA_DEFAULT=0 @@ -2807,6 +2825,7 @@ val SCE_LUA_WORD5=16 val SCE_LUA_WORD6=17 val SCE_LUA_WORD7=18 val SCE_LUA_WORD8=19 +val SCE_LUA_LABEL=20 # Lexical states for SCLEX_ERRORLIST lex ErrorList=SCLEX_ERRORLIST SCE_ERR_ val SCE_ERR_DEFAULT=0 diff --git a/lexers/LexAU3.cxx b/lexers/LexAU3.cxx index 72c918f07..e9ab75772 100644 --- a/lexers/LexAU3.cxx +++ b/lexers/LexAU3.cxx @@ -241,7 +241,7 @@ static void ColouriseAU3Doc(unsigned int startPos, if (IsAWordChar(sc.ch) || sc.ch == '}') { strcpy(s_save,s); - int tp = strlen(s_save); + int tp = static_cast<int>(strlen(s_save)); if (tp < 99) { s_save[tp] = static_cast<char>(tolower(sc.ch)); s_save[tp+1] = '\0'; diff --git a/lexers/LexCPP.cxx b/lexers/LexCPP.cxx index 22477c32f..51fd19255 100644 --- a/lexers/LexCPP.cxx +++ b/lexers/LexCPP.cxx @@ -803,15 +803,20 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle, sc.SetState(SCE_C_REGEX|activitySet); // JavaScript's RegEx } else if (sc.ch == '\"') { if (sc.chPrev == 'R') { - sc.SetState(SCE_C_STRINGRAW|activitySet); - rawStringTerminator = ")"; - for (int termPos = sc.currentPos + 1;; termPos++) { - char chTerminator = styler.SafeGetCharAt(termPos, '('); - if (chTerminator == '(') - break; - rawStringTerminator += chTerminator; + styler.Flush(); + if (MaskActive(styler.StyleAt(sc.currentPos - 1)) == SCE_C_STRINGRAW) { + sc.SetState(SCE_C_STRINGRAW|activitySet); + rawStringTerminator = ")"; + for (int termPos = sc.currentPos + 1;; termPos++) { + char chTerminator = styler.SafeGetCharAt(termPos, '('); + if (chTerminator == '(') + break; + rawStringTerminator += chTerminator; + } + rawStringTerminator += '\"'; + } else { + sc.SetState(SCE_C_STRING|activitySet); } - rawStringTerminator += '\"'; } else { sc.SetState(SCE_C_STRING|activitySet); } diff --git a/lexers/LexConf.cxx b/lexers/LexConf.cxx index 5e1bd199e..23ed5a6c8 100644 --- a/lexers/LexConf.cxx +++ b/lexers/LexConf.cxx @@ -2,7 +2,7 @@ /** @file LexConf.cxx ** Lexer for Apache Configuration Files. ** - ** First working version contributed by Ahmad Zawawi <zeus_go64@hotmail.com> on October 28, 2000. + ** First working version contributed by Ahmad Zawawi <ahmad.zawawi@gmail.com> on October 28, 2000. ** i created this lexer because i needed something pretty when dealing ** when Apache Configuration files... **/ diff --git a/lexers/LexHTML.cxx b/lexers/LexHTML.cxx index b54401805..a20796387 100644 --- a/lexers/LexHTML.cxx +++ b/lexers/LexHTML.cxx @@ -57,7 +57,7 @@ inline bool IsOperator(int ch) { } static void GetTextSegment(Accessor &styler, unsigned int start, unsigned int end, char *s, size_t len) { - size_t i = 0; + unsigned int i = 0; for (; (i < end - start + 1) && (i < len-1); i++) { s[i] = static_cast<char>(MakeLowerCase(styler[start + i])); } @@ -66,7 +66,7 @@ static void GetTextSegment(Accessor &styler, unsigned int start, unsigned int en static const char *GetNextWord(Accessor &styler, unsigned int start, char *s, size_t sLen) { - size_t i = 0; + unsigned int i = 0; for (; i < sLen-1; i++) { char ch = static_cast<char>(styler.SafeGetCharAt(start + i)); if ((i == 0) && !IsAWordStart(ch)) @@ -960,8 +960,8 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty styler.ColourTo(i, SCE_H_ASP); if (ch != '%' && ch != '$' && ch != '/') { - i += strlen(makoBlockType); - visibleChars += strlen(makoBlockType); + i += static_cast<int>(strlen(makoBlockType)); + visibleChars += static_cast<int>(strlen(makoBlockType)); if (keywords4.InList(makoBlockType)) styler.ColourTo(i, SCE_HP_WORD); else @@ -1983,7 +1983,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty styler.ColourTo(i, StateToPrint); state = SCE_HPHP_DEFAULT; } else if (isLineEnd(chPrev)) { - const int psdLength = strlen(phpStringDelimiter); + const int psdLength = static_cast<int>(strlen(phpStringDelimiter)); const char chAfterPsd = styler.SafeGetCharAt(i + psdLength); const char chAfterPsd2 = styler.SafeGetCharAt(i + psdLength + 1); if (isLineEnd(chAfterPsd) || @@ -2006,7 +2006,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty state = SCE_HPHP_DEFAULT; } } else if (isLineEnd(chPrev) && styler.Match(i, phpStringDelimiter)) { - const int psdLength = strlen(phpStringDelimiter); + const int psdLength = static_cast<int>(strlen(phpStringDelimiter)); const char chAfterPsd = styler.SafeGetCharAt(i + psdLength); const char chAfterPsd2 = styler.SafeGetCharAt(i + psdLength + 1); if (isLineEnd(chAfterPsd) || diff --git a/lexers/LexLua.cxx b/lexers/LexLua.cxx index 1dc9d4058..9e48efcd9 100644 --- a/lexers/LexLua.cxx +++ b/lexers/LexLua.cxx @@ -59,7 +59,7 @@ static void ColouriseLuaDoc( // Accepts accented characters CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true); - CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true); + CharacterSet setWord(CharacterSet::setAlphaNum, "_", 0x80, true); // Not exactly following number definition (several dots are seen as OK, etc.) // but probably enough in most cases. [pP] is for hex floats. CharacterSet setNumber(CharacterSet::setDigits, ".-+abcdefpABCDEFP"); @@ -71,7 +71,7 @@ static void ColouriseLuaDoc( // Initialize long string [[ ... ]] or block comment --[[ ... ]] nesting level, // if we are inside such a string. Block comment was introduced in Lua 5.0, // blocks with separators [=[ ... ]=] in Lua 5.1. - // Continuation of a string (\* whitespace escaping) is controlled by stringWs. + // Continuation of a string (\z whitespace escaping) is controlled by stringWs. int nestLevel = 0; int sepCount = 0; int stringWs = 0; @@ -130,6 +130,61 @@ static void ColouriseLuaDoc( // Determine if the current state should terminate. if (sc.state == SCE_LUA_OPERATOR) { + if (sc.ch == ':' && sc.chPrev == ':') { // :: <label> :: forward scan + sc.Forward(); + int ln = 0, maxln = startPos + length - sc.currentPos; + int c; + while (ln < maxln) { // determine line extent + c = sc.GetRelative(ln); + if (c == '\r' || c == '\n') + break; + ln++; + } + maxln = ln; ln = 0; + while (ln < maxln) { // skip over spaces/tabs + if (!IsASpaceOrTab(sc.GetRelative(ln))) + break; + ln++; + } + int ws1 = ln; + if (setWordStart.Contains(sc.GetRelative(ln))) { + int i = 0; + char s[100]; + while (ln < maxln) { // get potential label + c = sc.GetRelative(ln); + if (!setWord.Contains(c)) + break; + if (i < 90) + s[i++] = c; + ln++; + } + s[i] = '\0'; int lbl = ln; + if (!keywords.InList(s)) { + while (ln < maxln) { // skip over spaces/tabs + if (!IsASpaceOrTab(sc.GetRelative(ln))) + break; + ln++; + } + int ws2 = ln - lbl; + if (sc.GetRelative(ln) == ':' && sc.GetRelative(ln + 1) == ':') { + // final :: found, complete valid label construct + sc.ChangeState(SCE_LUA_LABEL); + if (ws1) { + sc.SetState(SCE_LUA_DEFAULT); + sc.Forward(ws1); + } + sc.SetState(SCE_LUA_LABEL); + sc.Forward(lbl - ws1); + if (ws2) { + sc.SetState(SCE_LUA_DEFAULT); + sc.Forward(ws2); + } + sc.SetState(SCE_LUA_LABEL); + sc.Forward(2); + } + } + } + } sc.SetState(SCE_LUA_DEFAULT); } else if (sc.state == SCE_LUA_NUMBER) { // We stop the number definition on non-numerical non-dot non-eEpP non-sign non-hexdigit char @@ -140,11 +195,26 @@ static void ColouriseLuaDoc( sc.SetState(SCE_LUA_DEFAULT); } } else if (sc.state == SCE_LUA_IDENTIFIER) { - if (!setWord.Contains(sc.ch) || sc.Match('.', '.')) { + if (!(setWord.Contains(sc.ch) || sc.ch == '.') || sc.Match('.', '.')) { char s[100]; sc.GetCurrent(s, sizeof(s)); if (keywords.InList(s)) { sc.ChangeState(SCE_LUA_WORD); + if (strcmp(s, "goto") == 0) { // goto <label> forward scan + sc.SetState(SCE_LUA_DEFAULT); + while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd) + sc.Forward(); + if (setWordStart.Contains(sc.ch)) { + sc.SetState(SCE_LUA_LABEL); + sc.Forward(); + while (setWord.Contains(sc.ch)) + sc.Forward(); + sc.GetCurrent(s, sizeof(s)); + if (keywords.InList(s)) + sc.ChangeState(SCE_LUA_WORD); + } + sc.SetState(SCE_LUA_DEFAULT); + } } else if (keywords2.InList(s)) { sc.ChangeState(SCE_LUA_WORD2); } else if (keywords3.InList(s)) { @@ -174,7 +244,7 @@ static void ColouriseLuaDoc( if (sc.ch == '\\') { if (setEscapeSkip.Contains(sc.chNext)) { sc.Forward(); - } else if (sc.chNext == '*') { + } else if (sc.chNext == 'z') { sc.Forward(); stringWs = 0x100; } @@ -192,7 +262,7 @@ static void ColouriseLuaDoc( if (sc.ch == '\\') { if (setEscapeSkip.Contains(sc.chNext)) { sc.Forward(); - } else if (sc.chNext == '*') { + } else if (sc.chNext == 'z') { sc.Forward(); stringWs = 0x100; } @@ -269,7 +339,7 @@ static void ColouriseLuaDoc( } } - if (setWord.Contains(sc.chPrev)) { + if (setWord.Contains(sc.chPrev) || sc.chPrev == '.') { char s[100]; sc.GetCurrent(s, sizeof(s)); if (keywords.InList(s)) { diff --git a/lexers/LexMagik.cxx b/lexers/LexMagik.cxx index 45390d45d..992080dd8 100644 --- a/lexers/LexMagik.cxx +++ b/lexers/LexMagik.cxx @@ -233,7 +233,7 @@ static void ColouriseMagikDoc(unsigned int startPos, int length, int initStyle, } if(characters.InList(keyword)) { - sc.Forward(strlen(keyword)); + sc.Forward(static_cast<int>(strlen(keyword))); } else { sc.Forward(); } diff --git a/lexers/LexMarkdown.cxx b/lexers/LexMarkdown.cxx index 393712033..a92697707 100644 --- a/lexers/LexMarkdown.cxx +++ b/lexers/LexMarkdown.cxx @@ -113,6 +113,10 @@ static bool HasPrevLineContent(StyleContext &sc) { return false; } +static bool AtTermStart(StyleContext &sc) { + return sc.currentPos == 0 || isspacechar(sc.chPrev); +} + static bool IsValidHrule(const unsigned int endPos, StyleContext &sc) { int c, count = 1; unsigned int i = 0; @@ -373,35 +377,38 @@ static void ColorizeMarkdownDoc(unsigned int startPos, int length, int initStyle } } // Code - also a special case for alternate inside spacing - if (sc.Match("``") && sc.GetRelative(3) != ' ') { + if (sc.Match("``") && sc.GetRelative(3) != ' ' && AtTermStart(sc)) { sc.SetState(SCE_MARKDOWN_CODE2); sc.Forward(); } - else if (sc.ch == '`' && sc.chNext != ' ') { + else if (sc.ch == '`' && sc.chNext != ' ' && AtTermStart(sc)) { sc.SetState(SCE_MARKDOWN_CODE); } // Strong - else if (sc.Match("**") && sc.GetRelative(2) != ' ') { + else if (sc.Match("**") && sc.GetRelative(2) != ' ' && AtTermStart(sc)) { sc.SetState(SCE_MARKDOWN_STRONG1); sc.Forward(); } - else if (sc.Match("__") && sc.GetRelative(2) != ' ') { + else if (sc.Match("__") && sc.GetRelative(2) != ' ' && AtTermStart(sc)) { sc.SetState(SCE_MARKDOWN_STRONG2); sc.Forward(); } // Emphasis - else if (sc.ch == '*' && sc.chNext != ' ') + else if (sc.ch == '*' && sc.chNext != ' ' && AtTermStart(sc)) { sc.SetState(SCE_MARKDOWN_EM1); - else if (sc.ch == '_' && sc.chNext != ' ') + } + else if (sc.ch == '_' && sc.chNext != ' ' && AtTermStart(sc)) { sc.SetState(SCE_MARKDOWN_EM2); + } // Strikeout - else if (sc.Match("~~") && sc.GetRelative(2) != ' ') { + else if (sc.Match("~~") && sc.GetRelative(2) != ' ' && AtTermStart(sc)) { sc.SetState(SCE_MARKDOWN_STRIKEOUT); sc.Forward(); } // Beginning of line - else if (IsNewline(sc.ch)) + else if (IsNewline(sc.ch)) { sc.SetState(SCE_MARKDOWN_LINE_BEGIN); + } } // Advance if not holding back the cursor for this iteration. if (!freezeCursor) diff --git a/lexers/LexModula.cxx b/lexers/LexModula.cxx index 1d0361165..cc5847fd6 100644 --- a/lexers/LexModula.cxx +++ b/lexers/LexModula.cxx @@ -92,7 +92,7 @@ static inline bool checkStatement( Accessor &styler, int &curPos, const char *stt, bool spaceAfter = true ) { - int len = strlen( stt ); + int len = static_cast<int>(strlen( stt )); int i; for( i = 0; i < len; i++ ) { if( styler.SafeGetCharAt( curPos + i ) != stt[i] ) { @@ -113,7 +113,7 @@ static inline bool checkEndSemicolon( int &curPos, int endPos ) { const char *stt = "END"; - int len = strlen( stt ); + int len = static_cast<int>(strlen( stt )); int i; for( i = 0; i < len; i++ ) { if( styler.SafeGetCharAt( curPos + i ) != stt[i] ) { diff --git a/lexers/LexOthers.cxx b/lexers/LexOthers.cxx index bc2c28773..720d97930 100644 --- a/lexers/LexOthers.cxx +++ b/lexers/LexOthers.cxx @@ -1162,21 +1162,71 @@ static void ColouriseErrorListDoc(unsigned int startPos, int length, int, WordLi } } -static int isSpecial(char s) { - return (s == '\\') || (s == ',') || (s == ';') || (s == '\'') || (s == ' ') || - (s == '\"') || (s == '`') || (s == '^') || (s == '~'); +static bool latexIsSpecial(int ch) { + return (ch == '#') || (ch == '$') || (ch == '%') || (ch == '&') || (ch == '_') || + (ch == '{') || (ch == '}') || (ch == ' '); } -static int isTag(int start, Accessor &styler) { - char s[6]; - unsigned int i = 0, e = 1; - while (i < 5 && e) { - s[i] = styler[start + i]; +static bool latexIsBlank(int ch) { + return (ch == ' ') || (ch == '\t'); +} + +static bool latexIsBlankAndNL(int ch) { + return (ch == ' ') || (ch == '\t') || (ch == '\r') || (ch == '\n'); +} + +static bool latexIsLetter(int ch) { + return isascii(ch) && isalpha(ch); +} + +static bool latexIsTagValid(int &i, int l, Accessor &styler) { + while (i < l) { + if (styler.SafeGetCharAt(i) == '{') { + while (i < l) { + i++; + if (styler.SafeGetCharAt(i) == '}') { + return true; + } else if (!latexIsLetter(styler.SafeGetCharAt(i)) && + styler.SafeGetCharAt(i)!='*') { + return false; + } + } + } else if (!latexIsBlank(styler.SafeGetCharAt(i))) { + return false; + } i++; - e = (strchr("{ \t", styler[start + i]) == NULL); + } + return false; +} + +static bool latexNextNotBlankIs(int i, int l, Accessor &styler, char needle) { + char ch; + while (i < l) { + ch = styler.SafeGetCharAt(i); + if (!latexIsBlankAndNL(ch) && ch != '*') { + if (ch == needle) + return true; + else + return false; + } + i++; + } + return false; +} + +static bool latexLastWordIs(int start, Accessor &styler, const char *needle) { + unsigned int i = 0; + unsigned int l = static_cast<unsigned int>(strlen(needle)); + int ini = start-l+1; + char s[32]; + + while (i < l && i < 32) { + s[i] = styler.SafeGetCharAt(ini + i); + i++; } s[i] = '\0'; - return (strcmp(s, "begin") == 0) || (strcmp(s, "end") == 0); + + return (strcmp(s, needle) == 0); } static void ColouriseLatexDoc(unsigned int startPos, int length, int initStyle, @@ -1185,39 +1235,51 @@ static void ColouriseLatexDoc(unsigned int startPos, int length, int initStyle, styler.StartAt(startPos); int state = initStyle; - char chNext = styler[startPos]; + char chNext = styler.SafeGetCharAt(startPos); styler.StartSegment(startPos); int lengthDoc = startPos + length; + char chVerbatimDelim = '\0'; for (int i = startPos; i < lengthDoc; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); if (styler.IsLeadByte(ch)) { - chNext = styler.SafeGetCharAt(i + 2); i++; + chNext = styler.SafeGetCharAt(i + 1); continue; } + switch (state) { case SCE_L_DEFAULT : switch (ch) { case '\\' : styler.ColourTo(i - 1, state); - if (isSpecial(styler[i + 1])) { - styler.ColourTo(i + 1, SCE_L_COMMAND); - i++; - chNext = styler.SafeGetCharAt(i + 1); + if (latexIsSpecial(chNext)) { + state = SCE_L_SPECIAL; } else { - if (isTag(i + 1, styler)) - state = SCE_L_TAG; - else + if (latexIsLetter(chNext)) { state = SCE_L_COMMAND; + } else { + if (chNext == '(' || chNext == '[') { + styler.ColourTo(i-1, state); + styler.ColourTo(i+1, SCE_L_SHORTCMD); + state = SCE_L_MATH; + if (chNext == '[') + state = SCE_L_MATH2; + i++; + chNext = styler.SafeGetCharAt(i+1); + } else { + state = SCE_L_SHORTCMD; + } + } } break; case '$' : styler.ColourTo(i - 1, state); state = SCE_L_MATH; if (chNext == '$') { + state = SCE_L_MATH2; i++; chNext = styler.SafeGetCharAt(i + 1); } @@ -1228,29 +1290,124 @@ static void ColouriseLatexDoc(unsigned int startPos, int length, int initStyle, break; } break; + case SCE_L_ERROR: + styler.ColourTo(i-1, state); + state = SCE_L_DEFAULT; + break; + case SCE_L_SPECIAL: + case SCE_L_SHORTCMD: + styler.ColourTo(i, state); + state = SCE_L_DEFAULT; + break; case SCE_L_COMMAND : - if (chNext == '[' || chNext == '{' || chNext == '}' || - chNext == ' ' || chNext == '\r' || chNext == '\n') { + if (!latexIsLetter(chNext)) { styler.ColourTo(i, state); state = SCE_L_DEFAULT; - i++; - chNext = styler.SafeGetCharAt(i + 1); + if (latexNextNotBlankIs(i+1, lengthDoc, styler, '[' )) { + state = SCE_L_CMDOPT; + } else if (latexLastWordIs(i, styler, "\\begin")) { + state = SCE_L_TAG; + } else if (latexLastWordIs(i, styler, "\\end")) { + state = SCE_L_TAG2; + } else if (latexLastWordIs(i, styler, "\\verb") && + chNext != '*' && chNext != ' ') { + chVerbatimDelim = chNext; + state = SCE_L_VERBATIM; + } } break; + case SCE_L_CMDOPT : + if (ch == ']') { + styler.ColourTo(i, state); + state = SCE_L_DEFAULT; + } + break; case SCE_L_TAG : - if (ch == '}') { + if (latexIsTagValid(i, lengthDoc, styler)) { + styler.ColourTo(i, state); + state = SCE_L_DEFAULT; + if (latexLastWordIs(i, styler, "{verbatim}")) { + state = SCE_L_VERBATIM; + } else if (latexLastWordIs(i, styler, "{comment}")) { + state = SCE_L_COMMENT2; + } else if (latexLastWordIs(i, styler, "{math}")) { + state = SCE_L_MATH; + } else if (latexLastWordIs(i, styler, "{displaymath}")) { + state = SCE_L_MATH2; + } else if (latexLastWordIs(i, styler, "{equation}")) { + state = SCE_L_MATH2; + } + } else { + state = SCE_L_ERROR; styler.ColourTo(i, state); state = SCE_L_DEFAULT; } + chNext = styler.SafeGetCharAt(i+1); + break; + case SCE_L_TAG2 : + if (latexIsTagValid(i, lengthDoc, styler)) { + styler.ColourTo(i, state); + state = SCE_L_DEFAULT; + } else { + state = SCE_L_ERROR; + } + chNext = styler.SafeGetCharAt(i+1); break; case SCE_L_MATH : if (ch == '$') { - if (chNext == '$') { - i++; - chNext = styler.SafeGetCharAt(i + 1); - } styler.ColourTo(i, state); state = SCE_L_DEFAULT; + } else if (ch == '\\' && chNext == ')') { + styler.ColourTo(i-1, state); + styler.ColourTo(i+1, SCE_L_SHORTCMD); + i++; + chNext = styler.SafeGetCharAt(i+1); + state = SCE_L_DEFAULT; + } else if (ch == '\\') { + int match = i + 3; + if (latexLastWordIs(match, styler, "\\end")) { + match++; + if (latexIsTagValid(match, lengthDoc, styler)) { + if (latexLastWordIs(match, styler, "{math}")) { + styler.ColourTo(i-1, state); + state = SCE_L_COMMAND; + } + } + } + } + + break; + case SCE_L_MATH2 : + if (ch == '$') { + if (chNext == '$') { + i++; + chNext = styler.SafeGetCharAt(i + 1); + styler.ColourTo(i, state); + state = SCE_L_DEFAULT; + } else { + styler.ColourTo(i, SCE_L_ERROR); + state = SCE_L_DEFAULT; + } + } else if (ch == '\\' && chNext == ']') { + styler.ColourTo(i-1, state); + styler.ColourTo(i+1, SCE_L_SHORTCMD); + i++; + chNext = styler.SafeGetCharAt(i+1); + state = SCE_L_DEFAULT; + } else if (ch == '\\') { + int match = i + 3; + if (latexLastWordIs(match, styler, "\\end")) { + match++; + if (latexIsTagValid(match, lengthDoc, styler)) { + if (latexLastWordIs(match, styler, "{displaymath}")) { + styler.ColourTo(i-1, state); + state = SCE_L_COMMAND; + } else if (latexLastWordIs(match, styler, "{equation}")) { + styler.ColourTo(i-1, state); + state = SCE_L_COMMAND; + } + } + } } break; case SCE_L_COMMENT : @@ -1258,6 +1415,43 @@ static void ColouriseLatexDoc(unsigned int startPos, int length, int initStyle, styler.ColourTo(i - 1, state); state = SCE_L_DEFAULT; } + break; + case SCE_L_COMMENT2 : + if (ch == '\\') { + int match = i + 3; + if (latexLastWordIs(match, styler, "\\end")) { + match++; + if (latexIsTagValid(match, lengthDoc, styler)) { + if (latexLastWordIs(match, styler, "{comment}")) { + styler.ColourTo(i-1, state); + state = SCE_L_COMMAND; + } + } + } + } + break; + case SCE_L_VERBATIM : + if (ch == '\\') { + int match = i + 3; + if (latexLastWordIs(match, styler, "\\end")) { + match++; + if (latexIsTagValid(match, lengthDoc, styler)) { + if (latexLastWordIs(match, styler, "{verbatim}")) { + styler.ColourTo(i-1, state); + state = SCE_L_COMMAND; + } + } + } + } else if (chNext == chVerbatimDelim) { + styler.ColourTo(i+1, state); + state = SCE_L_DEFAULT; + chVerbatimDelim = '\0'; + } else if (chVerbatimDelim != '\0' && (ch == '\n' || ch == '\r')) { + styler.ColourTo(i, SCE_L_ERROR); + state = SCE_L_DEFAULT; + chVerbatimDelim = '\0'; + } + break; } } styler.ColourTo(lengthDoc-1, state); diff --git a/lexers/LexPerl.cxx b/lexers/LexPerl.cxx index 7f0cbcf62..8a0f6422e 100644 --- a/lexers/LexPerl.cxx +++ b/lexers/LexPerl.cxx @@ -69,6 +69,10 @@ using namespace Scintilla; #define BACK_OPERATOR 1 // whitespace/comments are insignificant #define BACK_KEYWORD 2 // operators/keywords are needed for disambiguation +// all interpolated styles are different from their parent styles by a constant difference +// we also assume SCE_PL_STRING_VAR is the interpolated style with the smallest value +#define INTERPOLATE_SHIFT (SCE_PL_STRING_VAR - SCE_PL_STRING) + static bool isPerlKeyword(unsigned int start, unsigned int end, WordList &keywords, LexAccessor &styler) { // old-style keyword matcher; needed because GetCurrent() needs // current segment to be committed, but we may abandon early... @@ -246,14 +250,6 @@ static bool styleCheckSubPrototype(LexAccessor &styler, unsigned int bk) { return true; } -static bool isMatch(const char *sref, char *s) { - // match per-line delimiter - must kill trailing CR if CRLF - int i = strlen(s); - if (i != 0 && s[i - 1] == '\r') - s[i - 1] = '\0'; - return (strcmp(sref, s) == 0); -} - static int actualNumStyle(int numberStyle) { if (numberStyle == PERLNUM_VECTOR || numberStyle == PERLNUM_V_VECTOR) { return SCE_PL_STRING; @@ -360,11 +356,19 @@ struct OptionSetPerl : public OptionSet<OptionsPerl> { }; class LexerPerl : public ILexer { + CharacterSet setWordStart; + CharacterSet setWord; + CharacterSet setSpecialVar; + CharacterSet setControlVar; WordList keywords; OptionsPerl options; OptionSetPerl osPerl; public: - LexerPerl() { + LexerPerl() : + setWordStart(CharacterSet::setAlpha, "_", 0x80, true), + setWord(CharacterSet::setAlphaNum, "_", 0x80, true), + setSpecialVar(CharacterSet::setNone, "\"$;<>&`'+,./\\%:=~!?@[]"), + setControlVar(CharacterSet::setNone, "ACDEFHILMNOPRSTVWX") { } ~LexerPerl() { } @@ -398,6 +402,7 @@ public: static ILexer *LexerFactoryPerl() { return new LexerPerl(); } + void InterpolateSegment(StyleContext &sc, int maxSeg, bool isPattern=false); }; int SCI_METHOD LexerPerl::PropertySet(const char *key, const char *val) { @@ -426,6 +431,90 @@ int SCI_METHOD LexerPerl::WordListSet(int n, const char *wl) { return firstModification; } +void LexerPerl::InterpolateSegment(StyleContext &sc, int maxSeg, bool isPattern) { + // interpolate a segment (with no active backslashes or delimiters within) + // switch in or out of an interpolation style or continue current style + // commit variable patterns if found, trim segment, repeat until done + while (maxSeg > 0) { + bool isVar = false; + int sLen = 0; + if ((maxSeg > 1) && (sc.ch == '$' || sc.ch == '@')) { + // $#[$]*word [$@][$]*word (where word or {word} is always present) + bool braces = false; + sLen = 1; + if (sc.ch == '$' && sc.chNext == '#') { // starts with $# + sLen++; + } + while ((maxSeg > sLen) && (sc.GetRelative(sLen) == '$')) // >0 $ dereference within + sLen++; + if ((maxSeg > sLen) && (sc.GetRelative(sLen) == '{')) { // { start for {word} + sLen++; + braces = true; + } + if (maxSeg > sLen) { + int c = sc.GetRelative(sLen); + if (setWordStart.Contains(c)) { // word (various) + sLen++; + isVar = true; + while ((maxSeg > sLen) && setWord.Contains(sc.GetRelative(sLen))) + sLen++; + } else if (braces && IsADigit(c) && (sLen == 2)) { // digit for ${digit} + sLen++; + isVar = true; + } + } + if (braces) { + if ((maxSeg > sLen) && (sc.GetRelative(sLen) == '}')) { // } end for {word} + sLen++; + } else + isVar = false; + } + } + if (!isVar && (maxSeg > 1)) { // $- or @-specific variable patterns + sLen = 1; + int c = sc.chNext; + if (sc.ch == '$') { + if (IsADigit(c)) { // $[0-9] and slurp trailing digits + sLen++; + isVar = true; + while ((maxSeg > sLen) && IsADigit(sc.GetRelative(sLen))) + sLen++; + } else if (setSpecialVar.Contains(c)) { // $ special variables + sLen++; + isVar = true; + } else if (!isPattern && ((c == '(') || (c == ')') || (c == '|'))) { // $ additional + sLen++; + isVar = true; + } else if (c == '^') { // $^A control-char style + sLen++; + if ((maxSeg > sLen) && setControlVar.Contains(sc.GetRelative(sLen))) { + sLen++; + isVar = true; + } + } + } else if (sc.ch == '@') { + if (!isPattern && ((c == '+') || (c == '-'))) { // @ specials non-pattern + sLen++; + isVar = true; + } + } + } + if (isVar) { // commit as interpolated variable or normal character + if (sc.state < SCE_PL_STRING_VAR) + sc.SetState(sc.state + INTERPOLATE_SHIFT); + sc.Forward(sLen); + maxSeg -= sLen; + } else { + if (sc.state >= SCE_PL_STRING_VAR) + sc.SetState(sc.state - INTERPOLATE_SHIFT); + sc.Forward(); + maxSeg--; + } + } + if (sc.state >= SCE_PL_STRING_VAR) + sc.SetState(sc.state - INTERPOLATE_SHIFT); +} + void SCI_METHOD LexerPerl::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) { LexAccessor styler(pAccess); @@ -434,8 +523,6 @@ void SCI_METHOD LexerPerl::Lex(unsigned int startPos, int length, int initStyle, reWords.Set("elsif if split while"); // charset classes - CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true); - CharacterSet setWord(CharacterSet::setAlphaNum, "_", 0x80, true); CharacterSet setSingleCharOp(CharacterSet::setNone, "rwxoRWXOezsfdlpSbctugkTBMAC"); // lexing of "%*</" operators is non-trivial; these are missing in the set below CharacterSet setPerlOperator(CharacterSet::setNone, "^&\\()-+=|{}[]:;>,?!.~"); @@ -450,7 +537,7 @@ void SCI_METHOD LexerPerl::Lex(unsigned int startPos, int length, int initStyle, CharacterSet &setPOD = setModifiers; CharacterSet setNonHereDoc(CharacterSet::setDigits, "=$@"); CharacterSet setHereDocDelim(CharacterSet::setAlphaNum, "_"); - CharacterSet setSubPrototype(CharacterSet::setNone, "\\[$@%&*];"); + CharacterSet setSubPrototype(CharacterSet::setNone, "\\[$@%&*+];"); // for format identifiers CharacterSet setFormatStart(CharacterSet::setAlpha, "_="); CharacterSet &setFormat = setHereDocDelim; @@ -520,10 +607,13 @@ void SCI_METHOD LexerPerl::Lex(unsigned int startPos, int length, int initStyle, // Includes strings (may be multi-line), numbers (additional state), format // bodies, as well as POD sections. if (initStyle == SCE_PL_HERE_Q - || initStyle == SCE_PL_HERE_QQ - || initStyle == SCE_PL_HERE_QX - || initStyle == SCE_PL_FORMAT + || initStyle == SCE_PL_HERE_QQ + || initStyle == SCE_PL_HERE_QX + || initStyle == SCE_PL_FORMAT + || initStyle == SCE_PL_HERE_QQ_VAR + || initStyle == SCE_PL_HERE_QX_VAR ) { + // backtrack through multiple styles to reach the delimiter start int delim = (initStyle == SCE_PL_FORMAT) ? SCE_PL_FORMAT_IDENT:SCE_PL_HERE_DELIM; while ((startPos > 1) && (styler.StyleAt(startPos) != delim)) { startPos--; @@ -531,15 +621,34 @@ void SCI_METHOD LexerPerl::Lex(unsigned int startPos, int length, int initStyle, startPos = styler.LineStart(styler.GetLine(startPos)); initStyle = styler.StyleAt(startPos - 1); } - if (initStyle == SCE_PL_STRING_Q - || initStyle == SCE_PL_STRING_QQ - || initStyle == SCE_PL_STRING_QX - || initStyle == SCE_PL_STRING_QR + if (initStyle == SCE_PL_STRING + || initStyle == SCE_PL_STRING_QQ + || initStyle == SCE_PL_BACKTICKS + || initStyle == SCE_PL_STRING_QX + || initStyle == SCE_PL_REGEX + || initStyle == SCE_PL_STRING_QR + || initStyle == SCE_PL_REGSUBST + || initStyle == SCE_PL_STRING_VAR + || initStyle == SCE_PL_STRING_QQ_VAR + || initStyle == SCE_PL_BACKTICKS_VAR + || initStyle == SCE_PL_STRING_QX_VAR + || initStyle == SCE_PL_REGEX_VAR + || initStyle == SCE_PL_STRING_QR_VAR + || initStyle == SCE_PL_REGSUBST_VAR + ) { + // for interpolation, must backtrack through a mix of two different styles + int otherStyle = (initStyle >= SCE_PL_STRING_VAR) ? + initStyle - INTERPOLATE_SHIFT : initStyle + INTERPOLATE_SHIFT; + while (startPos > 1) { + int st = styler.StyleAt(startPos - 1); + if ((st != initStyle) && (st != otherStyle)) + break; + startPos--; + } + initStyle = SCE_PL_DEFAULT; + } else if (initStyle == SCE_PL_STRING_Q || initStyle == SCE_PL_STRING_QW - || initStyle == SCE_PL_REGEX - || initStyle == SCE_PL_REGSUBST - || initStyle == SCE_PL_STRING - || initStyle == SCE_PL_BACKTICKS + || initStyle == SCE_PL_XLAT || initStyle == SCE_PL_CHARACTER || initStyle == SCE_PL_NUMBER || initStyle == SCE_PL_IDENTIFIER @@ -770,17 +879,48 @@ void SCI_METHOD LexerPerl::Lex(unsigned int startPos, int length, int initStyle, break; case SCE_PL_HERE_Q: case SCE_PL_HERE_QQ: - case SCE_PL_HERE_QX: { - // also implies HereDoc.State == 2 - sc.Complete(); - while (!sc.atLineEnd) - sc.Forward(); - char s[HERE_DELIM_MAX]; - sc.GetCurrent(s, sizeof(s)); - if (isMatch(HereDoc.Delimiter, s)) { + case SCE_PL_HERE_QX: + // also implies HereDoc.State == 2 + sc.Complete(); + if (HereDoc.DelimiterLength == 0 || sc.Match(HereDoc.Delimiter)) { + int c = sc.GetRelative(HereDoc.DelimiterLength); + if (c == '\r' || c == '\n') { // peek first, do not consume match + sc.Forward(HereDoc.DelimiterLength); sc.SetState(SCE_PL_DEFAULT); backFlag = BACK_NONE; HereDoc.State = 0; + if (!sc.atLineEnd) + sc.Forward(); + break; + } + } + if (sc.state == SCE_PL_HERE_Q) { // \EOF and 'EOF' non-interpolated + while (!sc.atLineEnd) + sc.Forward(); + break; + } + while (!sc.atLineEnd) { // "EOF" and `EOF` interpolated + int s = 0, endType = 0; + int maxSeg = endPos - sc.currentPos; + while (s < maxSeg) { // scan to break string into segments + int c = sc.GetRelative(s); + if (c == '\\') { + endType = 1; break; + } else if (c == '\r' || c == '\n') { + endType = 2; break; + } + s++; + } + if (s > 0) // process non-empty segments + InterpolateSegment(sc, s); + if (endType == 1) { + sc.Forward(); + // \ at end-of-line does not appear to have any effect, skip + if (sc.ch != '\r' && sc.ch != '\n') + sc.Forward(); + } else if (endType == 2) { + if (!sc.atLineEnd) + sc.Forward(); } } break; @@ -833,45 +973,89 @@ void SCI_METHOD LexerPerl::Lex(unsigned int startPos, int length, int initStyle, sc.SetState(SCE_PL_DEFAULT); } else if (!Quote.Up && !IsASpace(sc.ch)) { Quote.Open(sc.ch); - } else if (sc.ch == '\\' && Quote.Up != '\\') { - sc.Forward(); - } else if (sc.ch == Quote.Down) { - Quote.Count--; - if (Quote.Count == 0) - Quote.Rep--; - } else if (sc.ch == Quote.Up) { - Quote.Count++; + } else { + int s = 0, endType = 0; + int maxSeg = endPos - sc.currentPos; + while (s < maxSeg) { // scan to break string into segments + int c = sc.GetRelative(s); + if (IsASpace(c)) { + break; + } else if (c == '\\' && Quote.Up != '\\') { + endType = 1; break; + } else if (c == Quote.Down) { + Quote.Count--; + if (Quote.Count == 0) { + Quote.Rep--; + break; + } + } else if (c == Quote.Up) + Quote.Count++; + s++; + } + if (s > 0) { // process non-empty segments + if (Quote.Up != '\'') { + InterpolateSegment(sc, s, true); + } else // non-interpolated path + sc.Forward(s); + } + if (endType == 1) + sc.Forward(); } break; case SCE_PL_REGSUBST: + case SCE_PL_XLAT: if (Quote.Rep <= 0) { if (!setModifiers.Contains(sc.ch)) sc.SetState(SCE_PL_DEFAULT); } else if (!Quote.Up && !IsASpace(sc.ch)) { Quote.Open(sc.ch); - } else if (sc.ch == '\\' && Quote.Up != '\\') { - sc.Forward(); - } else if (Quote.Count == 0 && Quote.Rep == 1) { - // We matched something like s(...) or tr{...}, Perl 5.10 - // appears to allow almost any character for use as the - // next delimiters. Whitespace and comments are accepted in - // between, but we'll limit to whitespace here. - // For '#', if no whitespace in between, it's a delimiter. - if (IsASpace(sc.ch)) { - // Keep going - } else if (sc.ch == '#' && IsASpaceOrTab(sc.chPrev)) { - sc.SetState(SCE_PL_DEFAULT); - } else { - Quote.Open(sc.ch); + } else { + int s = 0, endType = 0; + int maxSeg = endPos - sc.currentPos; + bool isPattern = (Quote.Rep == 2); + while (s < maxSeg) { // scan to break string into segments + int c = sc.GetRelative(s); + if (c == '\\' && Quote.Up != '\\') { + endType = 2; break; + } else if (Quote.Count == 0 && Quote.Rep == 1) { + // We matched something like s(...) or tr{...}, Perl 5.10 + // appears to allow almost any character for use as the + // next delimiters. Whitespace and comments are accepted in + // between, but we'll limit to whitespace here. + // For '#', if no whitespace in between, it's a delimiter. + if (IsASpace(c)) { + // Keep going + } else if (c == '#' && IsASpaceOrTab(sc.GetRelative(s - 1))) { + endType = 3; + } else + Quote.Open(c); + break; + } else if (c == Quote.Down) { + Quote.Count--; + if (Quote.Count == 0) { + Quote.Rep--; + endType = 1; + } + if (Quote.Up == Quote.Down) + Quote.Count++; + if (endType == 1) + break; + } else if (c == Quote.Up) { + Quote.Count++; + } else if (IsASpace(c)) + break; + s++; + } + if (s > 0) { // process non-empty segments + if (sc.state == SCE_PL_REGSUBST && Quote.Up != '\'') { + InterpolateSegment(sc, s, isPattern); + } else // non-interpolated path + sc.Forward(s); } - } else if (sc.ch == Quote.Down) { - Quote.Count--; - if (Quote.Count == 0) - Quote.Rep--; - if (Quote.Up == Quote.Down) - Quote.Count++; - } else if (sc.ch == Quote.Up) { - Quote.Count++; + if (endType == 2) { + sc.Forward(); + } else if (endType == 3) + sc.SetState(SCE_PL_DEFAULT); } break; case SCE_PL_STRING_Q: @@ -883,14 +1067,45 @@ void SCI_METHOD LexerPerl::Lex(unsigned int startPos, int length, int initStyle, case SCE_PL_BACKTICKS: if (!Quote.Down && !IsASpace(sc.ch)) { Quote.Open(sc.ch); - } else if (sc.ch == '\\' && Quote.Up != '\\') { - sc.Forward(); - } else if (sc.ch == Quote.Down) { - Quote.Count--; - if (Quote.Count == 0) + } else { + int s = 0, endType = 0; + int maxSeg = endPos - sc.currentPos; + while (s < maxSeg) { // scan to break string into segments + int c = sc.GetRelative(s); + if (IsASpace(c)) { + break; + } else if (c == '\\' && Quote.Up != '\\') { + endType = 2; break; + } else if (c == Quote.Down) { + Quote.Count--; + if (Quote.Count == 0) { + endType = 3; break; + } + } else if (c == Quote.Up) + Quote.Count++; + s++; + } + if (s > 0) { // process non-empty segments + switch (sc.state) { + case SCE_PL_STRING: + case SCE_PL_STRING_QQ: + case SCE_PL_BACKTICKS: + InterpolateSegment(sc, s); + break; + case SCE_PL_STRING_QX: + if (Quote.Up != '\'') { + InterpolateSegment(sc, s); + break; + } + // (continued for ' delim) + default: // non-interpolated path + sc.Forward(s); + } + } + if (endType == 2) { + sc.Forward(); + } else if (endType == 3) sc.ForwardSetState(SCE_PL_DEFAULT); - } else if (sc.ch == Quote.Up) { - Quote.Count++; } break; case SCE_PL_SUB_PROTOTYPE: { @@ -910,12 +1125,13 @@ void SCI_METHOD LexerPerl::Lex(unsigned int startPos, int length, int initStyle, break; case SCE_PL_FORMAT: { sc.Complete(); + if (sc.Match('.')) { + sc.Forward(); + if (sc.atLineEnd || ((sc.ch == '\r' && sc.chNext == '\n'))) + sc.SetState(SCE_PL_DEFAULT); + } while (!sc.atLineEnd) sc.Forward(); - char s[10]; - sc.GetCurrent(s, sizeof(s)); - if (isMatch(".", s)) - sc.SetState(SCE_PL_DEFAULT); } break; case SCE_PL_ERROR: @@ -1000,9 +1216,9 @@ void SCI_METHOD LexerPerl::Lex(unsigned int startPos, int length, int initStyle, numState = PERLNUM_DECIMAL; dotCount = 0; if (sc.ch == '0') { // hex,bin,octal - if (sc.chNext == 'x') { + if (sc.chNext == 'x' || sc.chNext == 'X') { numState = PERLNUM_HEX; - } else if (sc.chNext == 'b') { + } else if (sc.chNext == 'b' || sc.chNext == 'B') { numState = PERLNUM_BINARY; } else if (IsADigit(sc.chNext)) { numState = PERLNUM_OCTAL; @@ -1032,10 +1248,10 @@ void SCI_METHOD LexerPerl::Lex(unsigned int startPos, int length, int initStyle, sc.ChangeState(SCE_PL_STRING_Q); Quote.New(); } else if (sc.ch == 'y' && !setWord.Contains(sc.chNext)) { - sc.ChangeState(SCE_PL_REGSUBST); + sc.ChangeState(SCE_PL_XLAT); Quote.New(2); } else if (sc.Match('t', 'r') && !setWord.Contains(sc.GetRelative(2))) { - sc.ChangeState(SCE_PL_REGSUBST); + sc.ChangeState(SCE_PL_XLAT); Quote.New(2); sc.Forward(); fw++; @@ -1127,7 +1343,6 @@ void SCI_METHOD LexerPerl::Lex(unsigned int startPos, int length, int initStyle, bool isHereDoc = sc.Match('<', '<'); bool hereDocSpace = false; // for: SCALAR [whitespace] '<<' unsigned int bk = (sc.currentPos > 0) ? sc.currentPos - 1: 0; - unsigned int bkend; sc.Complete(); styler.Flush(); if (styler.StyleAt(bk) == SCE_PL_DEFAULT) @@ -1196,7 +1411,7 @@ void SCI_METHOD LexerPerl::Lex(unsigned int startPos, int length, int initStyle, // keywords always forced as /PATTERN/: split, if, elsif, while // everything else /PATTERN/ unless digit/space immediately after '/' // for '//', defined-or favoured unless special keywords - bkend = bk + 1; + unsigned int bkend = bk + 1; while (bk > 0 && styler.StyleAt(bk - 1) == SCE_PL_WORD) { bk--; } diff --git a/lexers/LexPowerPro.cxx b/lexers/LexPowerPro.cxx index 89bce5800..e8a7a6689 100644 --- a/lexers/LexPowerPro.cxx +++ b/lexers/LexPowerPro.cxx @@ -155,7 +155,7 @@ static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyl if ((sc.ch > 0) && setWord.Contains(sc.ch)) { strcpy(s_save,s); - int tp = strlen(s_save); + int tp = static_cast<int>(strlen(s_save)); if (tp < 99) { s_save[tp] = static_cast<char>(tolower(sc.ch)); s_save[tp+1] = '\0'; diff --git a/lexers/LexTeX.cxx b/lexers/LexTeX.cxx index 7b79670a9..062c7abb9 100644 --- a/lexers/LexTeX.cxx +++ b/lexers/LexTeX.cxx @@ -222,7 +222,7 @@ static void ColouriseTeXDoc( sc.ForwardSetState(SCE_TEX_TEXT) ; } else { sc.GetCurrent(key, sizeof(key)-1) ; - k = strlen(key) ; + k = static_cast<int>(strlen(key)) ; memmove(key,key+1,k) ; // shift left over escape token key[k] = '\0' ; k-- ; diff --git a/lexers/LexVHDL.cxx b/lexers/LexVHDL.cxx index 58bcd1a5a..5580b3c5e 100644 --- a/lexers/LexVHDL.cxx +++ b/lexers/LexVHDL.cxx @@ -235,7 +235,7 @@ static void FoldNoBoxVHDLDoc( } } } - for(j=j+strlen(prevWord); j<endPos; j++) + for(j=j+static_cast<unsigned int>(strlen(prevWord)); j<endPos; j++) { char ch = styler.SafeGetCharAt(j); int style = styler.StyleAt(j); diff --git a/lexlib/SparseState.h b/lexlib/SparseState.h index 655d7429c..08ff104d3 100644 --- a/lexlib/SparseState.h +++ b/lexlib/SparseState.h @@ -92,7 +92,7 @@ public: changed = true; } typename stateVector::const_iterator startOther = other.states.begin(); - if (!states.empty() && states.back().value == startOther->value) + if (!states.empty() && !other.states.empty() && states.back().value == startOther->value) ++startOther; if (startOther != other.states.end()) { states.insert(states.end(), startOther, other.states.end()); diff --git a/src/Decoration.cxx b/src/Decoration.cxx index 90bde57f2..24632d7c1 100644 --- a/src/Decoration.cxx +++ b/src/Decoration.cxx @@ -126,9 +126,13 @@ bool DecorationList::FillRange(int &position, int value, int &fillLength) { } void DecorationList::InsertSpace(int position, int insertLength) { + const bool atEnd = position == lengthDocument; lengthDocument += insertLength; for (Decoration *deco=root; deco; deco = deco->next) { deco->rs.InsertSpace(position, insertLength); + if (atEnd) { + deco->rs.FillRange(position, 0, insertLength); + } } } diff --git a/src/Document.cxx b/src/Document.cxx index 2729d3d7b..5c05aa5e0 100644 --- a/src/Document.cxx +++ b/src/Document.cxx @@ -87,10 +87,10 @@ void LexInterface::Colourise(int start, int end) { Document::Document() { refCount = 0; -#ifdef __unix__ - eolMode = SC_EOL_LF; -#else +#ifdef _WIN32 eolMode = SC_EOL_CRLF; +#else + eolMode = SC_EOL_LF; #endif dbcsCodePage = 0; stylingBits = 5; diff --git a/src/Editor.cxx b/src/Editor.cxx index 74698a13d..1257ac4b0 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -6051,20 +6051,20 @@ bool Editor::PositionInSelection(int pos) { bool Editor::PointInSelection(Point pt) { SelectionPosition pos = SPositionFromLocation(pt, false, true); - int xPos = XFromPosition(pos); + Point ptPos = LocationFromPosition(pos); for (size_t r=0; r<sel.Count(); r++) { SelectionRange range = sel.Range(r); if (range.Contains(pos)) { bool hit = true; if (pos == range.Start()) { // see if just before selection - if (pt.x < xPos) { + if (pt.x < ptPos.x) { hit = false; } } if (pos == range.End()) { // see if just after selection - if (pt.x > xPos) { + if (pt.x > ptPos.x) { hit = false; } } @@ -8423,7 +8423,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { return vs.caretStyle; case SCI_SETCARETWIDTH: - if (wParam <= 0) + if (static_cast<int>(wParam) <= 0) vs.caretWidth = 0; else if (wParam >= 3) vs.caretWidth = 3; diff --git a/version.txt b/version.txt index 9be0dc9a9..bf18240ed 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -228 +229 diff --git a/win32/PlatWin.cxx b/win32/PlatWin.cxx index f3c063c1b..00e0bf576 100644 --- a/win32/PlatWin.cxx +++ b/win32/PlatWin.cxx @@ -2192,6 +2192,7 @@ class ListBoxX : public ListBox { PRectangle rcPreSize; Point dragOffset; Point location; // Caret location at which the list is opened + int wheelDelta; // mouse wheel residue HWND GetHWND() const; void AppendListItem(const char *startword, const char *numword); @@ -2219,7 +2220,7 @@ public: ListBoxX() : lineHeight(10), fontCopy(0), technology(0), lb(0), unicodeMode(false), desiredVisibleRows(5), maxItemCharacters(0), aveCharWidth(8), parent(NULL), ctrlID(0), doubleClickAction(NULL), doubleClickActionData(NULL), - widestItem(NULL), maxCharWidth(1), resizeHit(0) { + widestItem(NULL), maxCharWidth(1), resizeHit(0), wheelDelta(0) { } virtual ~ListBoxX() { if (fontCopy) { @@ -2832,6 +2833,10 @@ LRESULT PASCAL ListBoxX::ControlWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPA } } return 0; + + case WM_MBUTTONDOWN: + // disable the scroll wheel button click action + return 0; } WNDPROC prevWndProc = reinterpret_cast<WNDPROC>(GetWindowLongPtr(hWnd, GWLP_USERDATA)); @@ -2943,6 +2948,31 @@ LRESULT ListBoxX::WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam } return ::DefWindowProc(hWnd, iMessage, wParam, lParam); + case WM_MOUSEWHEEL: + wheelDelta -= GET_WHEEL_DELTA_WPARAM(wParam); + if (abs(wheelDelta) >= WHEEL_DELTA) { + int nRows = GetVisibleRows(); + int linesToScroll = 1; + if (nRows > 1) { + linesToScroll = nRows - 1; + } + if (linesToScroll > 3) { + linesToScroll = 3; + } + linesToScroll *= (wheelDelta / WHEEL_DELTA); + int top = ::SendMessage(lb, LB_GETTOPINDEX, 0, 0) + linesToScroll; + if (top < 0) { + top = 0; + } + ::SendMessage(lb, LB_SETTOPINDEX, top, 0); + // update wheel delta residue + if (wheelDelta >= 0) + wheelDelta = wheelDelta % WHEEL_DELTA; + else + wheelDelta = - (-wheelDelta % WHEEL_DELTA); + } + break; + default: return ::DefWindowProc(hWnd, iMessage, wParam, lParam); } diff --git a/win32/ScintRes.rc b/win32/ScintRes.rc index 41443340a..2b50d1730 100644 --- a/win32/ScintRes.rc +++ b/win32/ScintRes.rc @@ -5,8 +5,8 @@ #include <windows.h> VS_VERSION_INFO VERSIONINFO -FILEVERSION 2, 2, 8, 0 -PRODUCTVERSION 2, 2, 8, 0 +FILEVERSION 2, 2, 9, 0 +PRODUCTVERSION 2, 2, 9, 0 FILEFLAGSMASK 0x3fL FILEFLAGS 0 FILEOS VOS_NT_WINDOWS32 @@ -23,12 +23,12 @@ BEGIN BEGIN VALUE "CompanyName", "Neil Hodgson neilh@scintilla.org\0" VALUE "FileDescription", "Scintilla.DLL - a Source Editing Component\0" - VALUE "FileVersion", "2.28\0" + VALUE "FileVersion", "2.29\0" VALUE "InternalName", "Scintilla\0" VALUE "LegalCopyright", "Copyright 1998-2011 by Neil Hodgson\0" VALUE "OriginalFilename", "Scintilla.DLL\0" VALUE "ProductName", "Scintilla\0" - VALUE "ProductVersion", "2.28\0" + VALUE "ProductVersion", "2.29\0" END END END diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx index c16da8fdb..a3c141aff 100644 --- a/win32/ScintillaWin.cxx +++ b/win32/ScintillaWin.cxx @@ -737,6 +737,13 @@ sptr_t ScintillaWin::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam break; case WM_MOUSEWHEEL: + // if autocomplete list active then send mousewheel message to it + if (ac.Active()) { + HWND hWnd = reinterpret_cast<HWND>(ac.lb->GetID()); + ::SendMessage(hWnd, iMessage, wParam, lParam); + break; + } + // Don't handle datazoom. // (A good idea for datazoom would be to "fold" or "unfold" details. // i.e. if datazoomed out only class structures are visible, when datazooming in the control |