aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--cocoa/PlatCocoa.mm16
-rw-r--r--cocoa/ScintillaTest/AppController.mm43
-rw-r--r--doc/ScintillaDownload.html10
-rw-r--r--doc/ScintillaHistory.html12
-rw-r--r--doc/ScintillaRelated.html8
-rw-r--r--doc/index.html7
-rw-r--r--gtk/PlatGTK.cxx23
-rw-r--r--gtk/ScintillaGTK.cxx2
-rw-r--r--include/SciLexer.h19
-rw-r--r--include/Scintilla.iface21
-rw-r--r--lexers/LexAU3.cxx2
-rw-r--r--lexers/LexCPP.cxx21
-rw-r--r--lexers/LexConf.cxx2
-rw-r--r--lexers/LexHTML.cxx12
-rw-r--r--lexers/LexLua.cxx82
-rw-r--r--lexers/LexMagik.cxx2
-rw-r--r--lexers/LexMarkdown.cxx23
-rw-r--r--lexers/LexModula.cxx4
-rw-r--r--lexers/LexOthers.cxx250
-rw-r--r--lexers/LexPerl.cxx371
-rw-r--r--lexers/LexPowerPro.cxx2
-rw-r--r--lexers/LexTeX.cxx2
-rw-r--r--lexers/LexVHDL.cxx2
-rw-r--r--lexlib/SparseState.h2
-rw-r--r--src/Decoration.cxx4
-rw-r--r--src/Document.cxx6
-rw-r--r--src/Editor.cxx8
-rw-r--r--version.txt2
-rw-r--r--win32/PlatWin.cxx32
-rw-r--r--win32/ScintRes.rc8
-rw-r--r--win32/ScintillaWin.cxx7
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>&nbsp;&nbsp;
- <a href="http://prdownloads.sourceforge.net/scintilla/scintilla228.tgz?download">
+ <a href="http://prdownloads.sourceforge.net/scintilla/scintilla229.tgz?download">
GTK+/Linux</a>&nbsp;&nbsp;
</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%">
&nbsp;
@@ -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