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 | 
