• R/O
  • SSH
  • HTTPS

tortoisesvn: Commit


Commit MetaInfo

Revision4273 (tree)
Zeit2005-08-30 23:38:49
Autorstefankueng

Log Message

Update Scintilla to version 1.66.

Ändern Zusammenfassung

Diff

--- trunk/src/Utils/scintilla/doc/Icons.html (nonexistent)
+++ trunk/src/Utils/scintilla/doc/Icons.html (revision 4273)
@@ -0,0 +1,56 @@
1+<?xml version="1.0"?>
2+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
3+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
4+<html xmlns="http://www.w3.org/1999/xhtml">
5+ <head>
6+ <meta name="generator" content="HTML Tidy, see www.w3.org" />
7+ <meta name="generator" content="SciTE" />
8+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
9+ <title>
10+ Scintilla icons
11+ </title>
12+ </head>
13+ <body bgcolor="#FFFFFF" text="#000000">
14+ <table bgcolor="#000000" width="100%" cellspacing="0" cellpadding="0" border="0">
15+ <tr>
16+ <td>
17+ <img src="SciTEIco.png" border="3" height="64" width="64" alt="Scintilla icon" />
18+ </td>
19+ <td>
20+ <a href="index.html" style="color:white;text-decoration:none"><font size="5">Scintilla
21+ and SciTE</font></a>
22+ </td>
23+ </tr>
24+ </table>
25+ <h2>
26+ Icons
27+ </h2>
28+ <p>
29+ These images may be used under the same license as Scintilla.
30+ </p>
31+ <p>
32+ Drawn by Iago Rubio, Philippe Lhoste, and Neil Hodgson.
33+ </p>
34+ <p>
35+ <a href="http://prdownloads.sourceforge.net/scintilla/icons1.zip?download">zip format</a> (70K)
36+ </p>
37+ <table>
38+ <tr>
39+ <td>For autocompletion lists</td>
40+ <td colspan="3">For margin markers</td>
41+ </tr>
42+ <tr>
43+ <td>12x12</td>
44+ <td>16x16</td>
45+ <td>24x24</td>
46+ <td>32x32</td>
47+ </tr>
48+ <tr>
49+ <td valign="top"><img src="12.png" /></td>
50+ <td valign="top"><img src="16.png" /></td>
51+ <td valign="top"><img src="24.png" /></td>
52+ <td valign="top"><img src="32.png" /></td>
53+ </tr>
54+ </table>
55+ </body>
56+</html>
--- trunk/src/Utils/scintilla/doc/ScintillaDoc.html (revision 4272)
+++ trunk/src/Utils/scintilla/doc/ScintillaDoc.html (revision 4273)
@@ -38,7 +38,7 @@
3838
3939 <h1>Scintilla Documentation</h1>
4040
41- <p>Last edited 3/June/2005 RBR</p>
41+ <p>Last edited 31/July/2005 RBR</p>
4242
4343 <p>There is <a class="jump" href="Design.html">an overview of the internal design of
4444 Scintilla</a>.<br />
@@ -1080,12 +1080,10 @@
10801080 last line), the return value is the end of the document.</p>
10811081
10821082 <p><b id="SCI_GETLINEENDPOSITION">SCI_GETLINEENDPOSITION(int line)</b><br />
1083- This returns the position at the end of the line, before any line end characters. If
1084- <code>line</code> is negative, the result is 0. If <code>line</code> is the last line in the
1085- document, (which does not have any end of line characters), the result is the size of the
1086- document. If <code>line</code> is negative, the result is -1. If <code>line</code> is &gt;=
1087- <code>SCI_GETLINECOUNT()</code>, the result is currently <code>SCI_GETLENGTH()-1</code>...
1088- (undefined?).</p>
1083+ This returns the position at the end of the line, before any line end characters. If <code>line</code>
1084+ is the last line in the document (which does not have any end of line characters), the result is the size of the
1085+ document. If <code>line</code> is negative or <code>line</code> &gt;= <a class="message"
1086+ href="#SCI_GETLINECOUNT"><code>SCI_GETLINECOUNT()</code></a>, the result is undefined.</p>
10891087
10901088 <p><b id="SCI_LINELENGTH">SCI_LINELENGTH(int line)</b><br />
10911089 This returns the length of the line, including any line end characters. If <code>line</code>
@@ -1125,9 +1123,9 @@
11251123 <p><b id="SCI_SETSELECTIONMODE">SCI_SETSELECTIONMODE(int mode)</b><br />
11261124 <b id="SCI_GETSELECTIONMODE">SCI_GETSELECTIONMODE</b><br />
11271125 The two functions set and get the selection mode, which can be
1128- stream (<code>SC_SEL_STREAM</code>=1) or
1129- rectangular (<code>SC_SEL_RECTANGLE</code>=2)
1130- or by lines (<code>SC_SEL_LINES</code>=3).
1126+ stream (<code>SC_SEL_STREAM</code>=0) or
1127+ rectangular (<code>SC_SEL_RECTANGLE</code>=1)
1128+ or by lines (<code>SC_SEL_LINES</code>=2).
11311129 When set in these modes, regular caret moves will extend or reduce the selection,
11321130 until the mode is cancelled by a call with same value or with <code>SCI_CANCEL</code>.
11331131 The get function returns the current mode even if the selection was made by mouse
@@ -2013,7 +2011,7 @@
20132011 <code>SCI_STYLESETCHARACTERSET(SCE_C_STRING, SC_CHARSET_RUSSIAN)</code> would ensure that
20142012 strings in Russian would display correctly in C and C++ (<code>SCE_C_STRING</code> is the style
20152013 number used by the C and C++ lexer to display literal strings; it has the value 6). This
2016- feature currently only works fully on Windows.</p>
2014+ feature works differently on Windows and GTK+.</p>
20172015
20182016 <p>The character sets supported on Windows are:<br />
20192017 <code>SC_CHARSET_ANSI</code>, <code>SC_CHARSET_ARABIC</code>, <code>SC_CHARSET_BALTIC</code>,
@@ -2021,13 +2019,16 @@
20212019 <code>SC_CHARSET_EASTEUROPE</code>, <code>SC_CHARSET_GB2312</code>,
20222020 <code>SC_CHARSET_GREEK</code>, <code>SC_CHARSET_HANGUL</code>, <code>SC_CHARSET_HEBREW</code>,
20232021 <code>SC_CHARSET_JOHAB</code>, <code>SC_CHARSET_MAC</code>, <code>SC_CHARSET_OEM</code>,
2022+ <code>SC_CHARSET_RUSSIAN</code> (code page 1251),
20242023 <code>SC_CHARSET_SHIFTJIS</code>, <code>SC_CHARSET_SYMBOL</code>, <code>SC_CHARSET_THAI</code>,
20252024 <code>SC_CHARSET_TURKISH</code>, and <code>SC_CHARSET_VIETNAMESE</code>.</p>
20262025
20272026 <p>The character sets supported on GTK+ are:<br />
2028- <code>SC_CHARSET_ANSI</code>, <code>SC_CHARSET_EASTEUROPE</code>,
2029- <code>SC_CHARSET_GB2312</code>, <code>SC_CHARSET_HANGUL</code>, and
2030- <code>SC_CHARSET_SHIFTJIS</code>.</p>
2027+ <code>SC_CHARSET_ANSI</code>, <code>SC_CHARSET_CYRILLIC</code> (code page 1251),
2028+ <code>SC_CHARSET_EASTEUROPE</code>,
2029+ <code>SC_CHARSET_GB2312</code>, <code>SC_CHARSET_HANGUL</code>,
2030+ <code>SC_CHARSET_RUSSIAN</code> (KOI8-R), <code>SC_CHARSET_SHIFTJIS</code>, and
2031+ <code>SC_CHARSET_8859_15</code>.</p>
20312032
20322033 <p><b id="SCI_STYLESETCASE">SCI_STYLESETCASE(int styleNumber, int caseMode)</b><br />
20332034 The value of caseMode determines how text is displayed. You can set upper case
@@ -4289,7 +4290,7 @@
42894290 <a class="message" href="#SCI_SETPROPERTY">SCI_SETPROPERTY(const char *key, const char *value)</a><br />
42904291 <a class="message" href="#SCI_GETPROPERTY">SCI_GETPROPERTY(const char *key, char *value)</a><br />
42914292 <a class="message" href="#SCI_GETPROPERTYEXPANDED">SCI_GETPROPERTYEXPANDED(const char *key, char *value)</a><br />
4292- <a class="message" href="#SCI_GETPROPERTYINT">SCI_GETPROPERTYINT(const char *key)</a><br />
4293+ <a class="message" href="#SCI_GETPROPERTYINT">SCI_GETPROPERTYINT(const char *key, int default)</a><br />
42934294 <a class="message" href="#SCI_SETKEYWORDS">SCI_SETKEYWORDS(int keyWordSet, const char
42944295 *keyWordList)</a><br />
42954296 </code>
@@ -4371,9 +4372,10 @@
43714372 <p>If the value argument is 0 then the length that should be allocated to store the value (including any indicated keyword replacement)
43724373 is returned; again, the terminating 0 is not included.</p>
43734374
4374- <p><b id="SCI_GETPROPERTYINT">SCI_GETPROPERTYINT(const char *key)</b><br />
4375+ <p><b id="SCI_GETPROPERTYINT">SCI_GETPROPERTYINT(const char *key, int default)</b><br />
43754376 Lookup a keyword:value pair using the specified key; if found, interpret the value as an integer and return it.
4376- If not found (or the value is not a number) then return 0.</p>
4377+ If not found (or the value is an empty string) then return the supplied default. If the keyword:value pair is found but is not
4378+ a number, then return 0.</p>
43774379
43784380 <p>Note that "keyword replacement" as described in <a class="message" href="#SCI_SETPROPERTY">
43794381 <code>SCI_SETPROPERTY</code></a> will be performed before any numeric interpretation.</p>
--- trunk/src/Utils/scintilla/doc/ScintillaDownload.html (revision 4272)
+++ trunk/src/Utils/scintilla/doc/ScintillaDownload.html (revision 4273)
@@ -25,9 +25,9 @@
2525 <table bgcolor="#CCCCCC" width="100%" cellspacing="0" cellpadding="8" border="0">
2626 <tr>
2727 <td>
28- <font size="4"> <a href="http://prdownloads.sourceforge.net/scintilla/scintilla164.zip?download">
28+ <font size="4"> <a href="http://prdownloads.sourceforge.net/scintilla/scintilla166.zip?download">
2929 Windows</a>&nbsp;&nbsp;
30- <a href="http://prdownloads.sourceforge.net/scintilla/scintilla164.tgz?download">
30+ <a href="http://prdownloads.sourceforge.net/scintilla/scintilla166.tgz?download">
3131 GTK+/Linux</a>&nbsp;&nbsp;
3232 </font>
3333 </td>
@@ -41,7 +41,7 @@
4141 containing very few restrictions.
4242 </p>
4343 <h3>
44- Release 1.64
44+ Release 1.66
4545 </h3>
4646 <h4>
4747 Source Code
@@ -49,8 +49,8 @@
4949 The source code package contains all of the source code for Scintilla but no binary
5050 executable code and is available in
5151 <ul>
52- <li><a href="http://prdownloads.sourceforge.net/scintilla/scintilla164.zip?download">zip format</a> (655K) commonly used on Windows</li>
53- <li><a href="http://prdownloads.sourceforge.net/scintilla/scintilla164.tgz?download">tgz format</a> (560K) commonly used on Linux and compatible operating systems</li>
52+ <li><a href="http://prdownloads.sourceforge.net/scintilla/scintilla166.zip?download">zip format</a> (680K) commonly used on Windows</li>
53+ <li><a href="http://prdownloads.sourceforge.net/scintilla/scintilla166.tgz?download">tgz format</a> (570K) commonly used on Linux and compatible operating systems</li>
5454 </ul>
5555 Instructions for building on both Windows and Linux are included in the readme file.
5656 <h4>
--- trunk/src/Utils/scintilla/doc/ScintillaHistory.html (revision 4272)
+++ trunk/src/Utils/scintilla/doc/ScintillaHistory.html (revision 4273)
@@ -202,6 +202,13 @@
202202 <li>Andre</li>
203203 <li>Randy Butler</li>
204204 <li>Georg Ritter</li>
205+ <li>Michael Goffioul</li>
206+ <li>Ben Harper</li>
207+ <li>Adam Strzelecki</li>
208+ <li>Kamen Stanev</li>
209+ <li>Steve Menard</li>
210+ <li>Oliver Yeoh</li>
211+ <li>Eric Promislow</li>
205212 </ul>
206213 <p>
207214 Images used in GTK+ version
@@ -213,10 +220,176 @@
213220 </li>
214221 </ul>
215222 <h3>
216- <a href="http://prdownloads.sourceforge.net/scintilla/scite163.zip?download">Release 1.64</a>
223+ <a href="http://prdownloads.sourceforge.net/scintilla/scite166.zip?download">Release 1.66</a>
217224 </h3>
218225 <ul>
219226 <li>
227+ Released on 26 August 2005.
228+ </li>
229+ <li>
230+ New, more ambitious Ruby lexer.
231+ </li>
232+ <li>
233+ SciTE Find in Files dialog has options for matching case and whole words which are
234+ enabled when the internal find command is used.
235+ </li>
236+ <li>
237+ SciTE output pane can display automatic completion after "$(" typed.
238+ An initial ">" on a line is ignored when Enter pressed.
239+ </li>
240+ <li>
241+ C++ lexer recognises keywords within line doc comments. It continues styles over line
242+ end characters more consistently so that eolfilled style can be used for preprocessor lines
243+ and line comments.
244+ </li>
245+ <li>
246+ VB lexer improves handling of file numbers and date literals.
247+ </li>
248+ <li>
249+ Lua folder handles repeat until, nested comments and nested strings.
250+ </li>
251+ <li>
252+ POV lexer improves handling of comment lines.
253+ </li>
254+ <li>
255+ AU3 lexer and folder updated. COMOBJ style added.
256+ </li>
257+ <li>
258+ Bug fixed with text display on GTK+ with Pango 1.8.
259+ </li>
260+ <li>
261+ Caret painting avoided when not focused.
262+ </li>
263+ <li>
264+ SciTE on GTK+ handles file names used to reference properties as case-sensitive.
265+ </li>
266+ <li>
267+ SciTE on GTK+ Save As and Export commands set the file name field.
268+ On GTK+ the Export commands modify the file name in the same way as on Windows.
269+ </li>
270+ <li>
271+ Fixed SciTE problem where confirmation was not displaying when closing a file where all
272+ contents had been deleted.
273+ </li>
274+ <li>
275+ Middle click on SciTE tab now closes correct buffer on Windows when tool bar is visible.
276+ </li>
277+ <li>
278+ SciTE bugs fixed where files contained in directory that includes '.' character.
279+ </li>
280+ <li>
281+ SciTE bug fixed where import in user options was reading file from directory of
282+ global options.
283+ </li>
284+ <li>
285+ SciTE calltip bug fixed where single line calltips had arrow displayed incorrectly.
286+ </li>
287+ <li>
288+ SciTE folding bug fixed where empty lines were shown for no reason.
289+ </li>
290+ <li>
291+ Bug fixed where 2 byte per pixel XPM images caused crash although they are still not
292+ displayed.
293+ </li>
294+ <li>
295+ Autocompletion list size tweaked.
296+ </li>
297+ </ul>
298+ <h3>
299+ <a href="http://prdownloads.sourceforge.net/scintilla/scite165.zip?download">Release 1.65</a>
300+ </h3>
301+ <ul>
302+ <li>
303+ Released on 1 August 2005.
304+ </li>
305+ <li>
306+ FreeBasic support.
307+ </li>
308+ <li>
309+ SciTE on Windows handles command line arguments
310+ "-" (read standard input into buffer),
311+ "--" (read standard input into output pane) and
312+ "-@" (read file names from standard input and open each).
313+ </li>
314+ <li>
315+ SciTE includes a simple implementation of Find in Files which is used if no find.command is set.
316+ </li>
317+ <li>
318+ SciTE can close tabs with a mouse middle click.
319+ </li>
320+ <li>
321+ SciTE includes a save.all.for.build setting.
322+ </li>
323+ <li>
324+ Folder for MSSQL.
325+ </li>
326+ <li>
327+ Batch file lexer understands more of the syntax and the behaviour of built in commands.
328+ </li>
329+ <li>
330+ Perl lexer handles here docs better; disambiguates barewords, quote-like delimiters, and repetition operators;
331+ handles Pods after __END__; recognises numbers better; and handles some typeglob special variables.
332+ </li>
333+ <li>
334+ Lisp adds more lexical states.
335+ </li>
336+ <li>
337+ PHP allows spaces after &lt;&lt;&lt;.
338+ </li>
339+ <li>
340+ TADS3 has a simpler set of states and recognizes identifiers.
341+ </li>
342+ <li>
343+ Avenue elseif folds better.
344+ </li>
345+ <li>
346+ Errorlist lexer treats lines starting with '+++' and '---' as separate
347+ styles from '+' and '-' as they indicate file names in diffs.
348+ </li>
349+ <li>
350+ SciTE error recogniser handles file paths in extra explanatory lines from MSVC
351+ and in '+++' and '---' lines from diff.
352+ </li>
353+ <li>
354+ Bugs fixed in SciTE and Scintilla folding behaviour when text pasted before
355+ folded text caused unnecessary
356+ unfolding and cutting text could lead to text being irretrievably hidden.
357+ </li>
358+ <li>
359+ SciTE on Windows uses correct font for dialogs and better font for tab bar
360+ allowing better localisation
361+ </li>
362+ <li>
363+ When Windows is used with a secondary monitor before the primary
364+ monitor, autocompletion lists are not forced onto the primary monitor.
365+ </li>
366+ <li>
367+ Scintilla calltip bug fixed where down arrow setting wrong value in notification
368+ if not in first line. SciTE bug fixed where second arrow only shown on multiple line
369+ calltip and was therefore misinterpreting the notification value.
370+ </li>
371+ <li>
372+ Lexers will no longer be re-entered recursively during, for example, fold level setting.
373+ </li>
374+ <li>
375+ Undo of typing in overwrite mode undoes one character at a time rather than requiring a removal
376+ and addition step for each character.
377+ </li>
378+ <li>
379+ EM_EXSETSEL(0,-1) fixed.
380+ </li>
381+ <li>
382+ Bug fixed where part of a rectangular selection was not shown as selected.
383+ </li>
384+ <li>
385+ Autocomplete window size fixed.
386+ </li>
387+ </ul>
388+ <h3>
389+ <a href="http://prdownloads.sourceforge.net/scintilla/scite164.zip?download">Release 1.64</a>
390+ </h3>
391+ <ul>
392+ <li>
220393 Released on 6 June 2005.
221394 </li>
222395 <li>
@@ -278,7 +451,7 @@
278451 Undo and redo can cause SCN_MODIFYATTEMPTRO notifications.
279452 </li>
280453 <li>
281- Indicators display correctly when they atrt at the second character on a line.
454+ Indicators display correctly when they start at the second character on a line.
282455 </li>
283456 <li>
284457 SciTE Export As HTML uses standards compliant CSS.
@@ -293,6 +466,9 @@
293466 Fixed problem with character set conversion when pasting on GTK+.
294467 </li>
295468 <li>
469+ SciTE default character set changed from ANSI_CHARSET to DEFAULT_CHARSET.
470+ </li>
471+ <li>
296472 Fixed crash when creating empty autocompletion list.
297473 </li>
298474 <li>
@@ -357,7 +533,7 @@
357533 SQL lexer gains second set of keywords.
358534 </li>
359535 <li>
360- ErrorList lexer recognises Borland Delphi error messages.
536+ Errorlist lexer recognises Borland Delphi error messages.
361537 </li>
362538 <li>
363539 Method added for determining number of visual lines occupied by a document
--- trunk/src/Utils/scintilla/doc/index.html (revision 4272)
+++ trunk/src/Utils/scintilla/doc/index.html (revision 4273)
@@ -9,7 +9,7 @@
99 <meta name="keywords" content="Scintilla, SciTE, Editing Component, Text Editor" />
1010 <meta name="Description"
1111 content="www.scintilla.org is the home of the Scintilla editing component and SciTE text editor application." />
12- <meta name="Date.Modified" content="20050606" />
12+ <meta name="Date.Modified" content="20050826" />
1313 <style type="text/css">
1414 .versionlist {
1515 color: #FFCC99;
@@ -36,8 +36,8 @@
3636 GTK+</font>
3737 </td>
3838 <td width="40%" align="right">
39- <font color="#FFCC99" size="3"> Release version 1.64<br />
40- Site last modified June 6 2005</font>
39+ <font color="#FFCC99" size="3"> Release version 1.66<br />
40+ Site last modified August 26 2005</font>
4141 </td>
4242 <td width="20%">
4343 &nbsp;
@@ -54,6 +54,17 @@
5454 <table bgcolor="#000000" width="100%" cellspacing="0" cellpadding="6" border="0">
5555 <tr>
5656 <td width="100%">
57+ <span class="versionlist">Version 1.66 has a new Ruby lexer and fixes bugs on GTK+
58+ with Pango 1.8.</span>
59+ </td>
60+ </tr>
61+ <tr>
62+ <td width="100%">
63+ <span class="versionlist">Version 1.65 contains minor enhancements and bug fixes. </span>
64+ </td>
65+ </tr>
66+ <tr>
67+ <td width="100%">
5768 <span class="versionlist">Version 1.64 supports
5869 TADS3, Smalltalk, Rebol, Flagship (Clipper / XBase), and CSound. </span>
5970 </td>
@@ -81,30 +92,6 @@
8192 <span class="versionlist"> Version 1.60 includes continuation markers on wrapped lines. </span>
8293 </td>
8394 </tr>
84- <tr>
85- <td width="100%">
86- <span class="versionlist"> Version 1.59 contains minor
87- improvements and fixes including a partial retreat from GTK+ input
88- method use for European languages. </span>
89- </td>
90- </tr>
91- <tr>
92- <td width="100%">
93- <span class="versionlist"> Version 1.58 contains minor fixes.</span>
94- </td>
95- </tr>
96- <tr>
97- <td width="100%">
98- <span class="versionlist"> Version 1.57 contains minor new features and
99- bug fixes.</span>
100- </td>
101- </tr>
102- <tr>
103- <td width="100%">
104- <span class="versionlist"> Version 1.56 adds rectangular selection from keyboard
105- and fixes some problems with line wrapping.</span>
106- </td>
107- </tr>
10895 </table>
10996 <table bgcolor="#CCCCCC" width="100%" cellspacing="0" cellpadding="8" border="0">
11097 <tr>
@@ -184,6 +171,9 @@
184171 <a href="http://scintilla.sourceforge.net/ScintillaHistory.html">History and contribution credits.</a>
185172 </p>
186173 <p>
174+ <a href="http://scintilla.sourceforge.net/Icons.html">Icons that can be used with Scintilla.</a>
175+ </p>
176+ <p>
187177 Questions and comments about Scintilla should be directed to the
188178 <a href="http://mailman.lyra.org/mailman/listinfo/scintilla-interest">scintilla-interest</a>
189179 mailing list,
--- trunk/src/Utils/scintilla/gtk/PlatGTK.cxx (revision 4272)
+++ trunk/src/Utils/scintilla/gtk/PlatGTK.cxx (revision 4273)
@@ -286,6 +286,8 @@
286286 return "*-*";
287287 case SC_CHARSET_RUSSIAN:
288288 return "*-r";
289+ case SC_CHARSET_CYRILLIC:
290+ return "*-cp1251";
289291 case SC_CHARSET_SHIFTJIS:
290292 return "jisx0208.1983-*";
291293 case SC_CHARSET_SYMBOL:
@@ -744,6 +746,8 @@
744746 return "ASCII";
745747 case SC_CHARSET_RUSSIAN:
746748 return "KOI8-R";
749+ case SC_CHARSET_CYRILLIC:
750+ return "CP1251";
747751 case SC_CHARSET_SHIFTJIS:
748752 return "SHIFT-JIS";
749753 case SC_CHARSET_SYMBOL:
@@ -1254,6 +1258,7 @@
12541258 if (font_.GetID()) {
12551259 int totalWidth = 0;
12561260 #ifdef USE_PANGO
1261+ const int lenPositions = len;
12571262 if (PFont(font_)->pfd) {
12581263 if (len == 1) {
12591264 int width = PFont(font_)->CharWidth(*s, et);
@@ -1267,17 +1272,21 @@
12671272 if (et == UTF8) {
12681273 // Simple and direct as UTF-8 is native Pango encoding
12691274 pango_layout_set_text(layout, s, len);
1270- PangoLayoutIter *iter = pango_layout_get_iter (layout);
1275+ PangoLayoutIter *iter = pango_layout_get_iter(layout);
1276+ pango_layout_iter_get_cluster_extents(iter, NULL, &pos);
12711277 int i = 0;
1272- while (pango_layout_iter_next_cluster (iter)) {
1278+ while (pango_layout_iter_next_cluster(iter)) {
12731279 pango_layout_iter_get_cluster_extents(iter, NULL, &pos);
12741280 int position = PANGO_PIXELS(pos.x);
1275- int curIndex = pango_layout_iter_get_index (iter);
1281+ int curIndex = pango_layout_iter_get_index(iter);
12761282 while (i < curIndex) {
12771283 positions[i++] = position;
12781284 }
12791285 }
1280- pango_layout_iter_free (iter);
1286+ while (i < lenPositions)
1287+ positions[i++] = PANGO_PIXELS(pos.x + pos.width);
1288+ pango_layout_iter_free(iter);
1289+ PLATFORM_ASSERT(i == lenPositions);
12811290 } else {
12821291 int positionsCalculated = 0;
12831292 if (et == dbcs) {
@@ -1291,11 +1300,12 @@
12911300 pango_layout_set_text(layout, utfForm, strlen(utfForm));
12921301 int i = 0;
12931302 int utfIndex = 0;
1294- PangoLayoutIter *iter = pango_layout_get_iter (layout);
1295- while (pango_layout_iter_next_cluster (iter)) {
1303+ PangoLayoutIter *iter = pango_layout_get_iter(layout);
1304+ pango_layout_iter_get_cluster_extents(iter, NULL, &pos);
1305+ while (pango_layout_iter_next_cluster(iter)) {
12961306 pango_layout_iter_get_cluster_extents (iter, NULL, &pos);
12971307 int position = PANGO_PIXELS(pos.x);
1298- int utfIndexNext = pango_layout_iter_get_index (iter);
1308+ int utfIndexNext = pango_layout_iter_get_index(iter);
12991309 while (utfIndex < utfIndexNext) {
13001310 size_t lenChar = MultiByteLenFromIconv(convMeasure, s+i, len-i);
13011311 //size_t lenChar = mblen(s+i, MB_CUR_MAX);
@@ -1306,8 +1316,11 @@
13061316 utfIndex += UTF8CharLength(utfForm+utfIndex);
13071317 }
13081318 }
1309- pango_layout_iter_free (iter);
1319+ while (i < lenPositions)
1320+ positions[i++] = PANGO_PIXELS(pos.x + pos.width);
1321+ pango_layout_iter_free(iter);
13101322 delete []utfForm;
1323+ PLATFORM_ASSERT(i == lenPositions);
13111324 }
13121325 }
13131326 if (positionsCalculated < 1 ) {
@@ -1320,11 +1333,14 @@
13201333 }
13211334 pango_layout_set_text(layout, utfForm, len);
13221335 int i = 0;
1323- PangoLayoutIter *iter = pango_layout_get_iter (layout);
1324- while (pango_layout_iter_next_cluster (iter)) {
1336+ PangoLayoutIter *iter = pango_layout_get_iter(layout);
1337+ pango_layout_iter_get_cluster_extents(iter, NULL, &pos);
1338+ while (pango_layout_iter_next_cluster(iter)) {
13251339 pango_layout_iter_get_cluster_extents(iter, NULL, &pos);
13261340 positions[i++] = PANGO_PIXELS(pos.x);
13271341 }
1342+ while (i < lenPositions)
1343+ positions[i++] = PANGO_PIXELS(pos.x + pos.width);
13281344 pango_layout_iter_free(iter);
13291345 if (useGFree) {
13301346 g_free(utfForm);
@@ -1331,6 +1347,7 @@
13311347 } else {
13321348 delete []utfForm;
13331349 }
1350+ PLATFORM_ASSERT(i == lenPositions);
13341351 }
13351352 }
13361353 if (len == 1) {
@@ -1467,10 +1484,12 @@
14671484 // rarely used in code.
14681485
14691486 // This string contains a good range of characters to test for size.
1470-const char largeSizeString[] = "ÂÃÅÄ `~!@#$%^&*()-_=+\\|[]{};:\"\'<,>.?/1234567890"
1471- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
1487+//const char largeSizeString[] = "ÂÃÅÄ `~!@#$%^&*()-_=+\\|[]{};:\"\'<,>.?/1234567890"
1488+// "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
1489+#ifndef FAST_WAY
14721490 const char sizeString[] = "`~!@#$%^&*()-_=+\\|[]{};:\"\'<,>.?/1234567890"
14731491 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
1492+#endif
14741493
14751494 int SurfaceImpl::Ascent(Font &font_) {
14761495 if (!(font_.GetID()))
--- trunk/src/Utils/scintilla/include/KeyWords.h (revision 4272)
+++ trunk/src/Utils/scintilla/include/KeyWords.h (revision 4273)
@@ -29,6 +29,8 @@
2929 LexerModule(int language_, LexerFunction fnLexer_,
3030 const char *languageName_=0, LexerFunction fnFolder_=0,
3131 const char * const wordListDescriptions_[] = NULL);
32+ virtual ~LexerModule() {
33+ }
3234 int GetLanguage() const { return language; }
3335
3436 // -1 is returned if no WordList information is available
--- trunk/src/Utils/scintilla/include/PropSet.h (revision 4272)
+++ trunk/src/Utils/scintilla/include/PropSet.h (revision 4273)
@@ -29,6 +29,7 @@
2929 Property *props[hashRoots];
3030 Property *enumnext;
3131 int enumhash;
32+ static bool caseSensitiveFilenames;
3233 static unsigned int HashString(const char *s, size_t len) {
3334 unsigned int ret = 0;
3435 while (len--) {
@@ -58,6 +59,9 @@
5859 char *ToString(); // Caller must delete[] the return value
5960 bool GetFirst(char **key, char **val);
6061 bool GetNext(char **key, char **val);
62+ static void SetCaseSensitiveFilenames(bool caseSensitiveFilenames_) {
63+ caseSensitiveFilenames = caseSensitiveFilenames_;
64+ }
6165
6266 private:
6367 // copy-value semantics not implemented
--- trunk/src/Utils/scintilla/include/SciLexer.h (revision 4272)
+++ trunk/src/Utils/scintilla/include/SciLexer.h (revision 4273)
@@ -87,6 +87,7 @@
8787 #define SCLEX_SMALLTALK 72
8888 #define SCLEX_FLAGSHIP 73
8989 #define SCLEX_CSOUND 74
90+#define SCLEX_FREEBASIC 75
9091 #define SCLEX_AUTOMATIC 1000
9192 #define SCE_P_DEFAULT 0
9293 #define SCE_P_COMMENTLINE 1
@@ -249,6 +250,7 @@
249250 #define SCE_PL_ARRAY 13
250251 #define SCE_PL_HASH 14
251252 #define SCE_PL_SYMBOLTABLE 15
253+#define SCE_PL_VARIABLE_INDEXER 16
252254 #define SCE_PL_REGEX 17
253255 #define SCE_PL_REGSUBST 18
254256 #define SCE_PL_LONGQUOTE 19
@@ -264,6 +266,40 @@
264266 #define SCE_PL_STRING_QR 29
265267 #define SCE_PL_STRING_QW 30
266268 #define SCE_PL_POD_VERB 31
269+#define SCE_RB_DEFAULT 0
270+#define SCE_RB_ERROR 1
271+#define SCE_RB_COMMENTLINE 2
272+#define SCE_RB_POD 3
273+#define SCE_RB_NUMBER 4
274+#define SCE_RB_WORD 5
275+#define SCE_RB_STRING 6
276+#define SCE_RB_CHARACTER 7
277+#define SCE_RB_CLASSNAME 8
278+#define SCE_RB_DEFNAME 9
279+#define SCE_RB_OPERATOR 10
280+#define SCE_RB_IDENTIFIER 11
281+#define SCE_RB_REGEX 12
282+#define SCE_RB_GLOBAL 13
283+#define SCE_RB_SYMBOL 14
284+#define SCE_RB_MODULE_NAME 15
285+#define SCE_RB_INSTANCE_VAR 16
286+#define SCE_RB_CLASS_VAR 17
287+#define SCE_RB_BACKTICKS 18
288+#define SCE_RB_DATASECTION 19
289+#define SCE_RB_HERE_DELIM 20
290+#define SCE_RB_HERE_Q 21
291+#define SCE_RB_HERE_QQ 22
292+#define SCE_RB_HERE_QX 23
293+#define SCE_RB_STRING_Q 24
294+#define SCE_RB_STRING_QQ 25
295+#define SCE_RB_STRING_QX 26
296+#define SCE_RB_STRING_QR 27
297+#define SCE_RB_STRING_QW 28
298+#define SCE_RB_WORD_DEMOTED 29
299+#define SCE_RB_STDIN 30
300+#define SCE_RB_STDOUT 31
301+#define SCE_RB_STDERR 40
302+#define SCE_RB_UPPER_BOUND 41
267303 #define SCE_B_DEFAULT 0
268304 #define SCE_B_COMMENT 1
269305 #define SCE_B_NUMBER 2
@@ -408,10 +444,14 @@
408444 #define SCE_LISP_COMMENT 1
409445 #define SCE_LISP_NUMBER 2
410446 #define SCE_LISP_KEYWORD 3
447+#define SCE_LISP_KEYWORD_KW 4
448+#define SCE_LISP_SYMBOL 5
411449 #define SCE_LISP_STRING 6
412450 #define SCE_LISP_STRINGEOL 8
413451 #define SCE_LISP_IDENTIFIER 9
414452 #define SCE_LISP_OPERATOR 10
453+#define SCE_LISP_SPECIAL 11
454+#define SCE_LISP_MULTI_COMMENT 12
415455 #define SCE_EIFFEL_DEFAULT 0
416456 #define SCE_EIFFEL_COMMENTLINE 1
417457 #define SCE_EIFFEL_NUMBER 2
@@ -752,6 +792,7 @@
752792 #define SCE_AU3_PREPROCESSOR 11
753793 #define SCE_AU3_SPECIAL 12
754794 #define SCE_AU3_EXPAND 13
795+#define SCE_AU3_COMOBJ 14
755796 #define SCE_APDL_DEFAULT 0
756797 #define SCE_APDL_COMMENT 1
757798 #define SCE_APDL_COMMENTBLOCK 2
@@ -837,37 +878,25 @@
837878 #define SCE_HA_COMMENTBLOCK2 15
838879 #define SCE_HA_COMMENTBLOCK3 16
839880 #define SCE_T3_DEFAULT 0
840-#define SCE_T3_PREPROCESSOR 1
841-#define SCE_T3_BLOCK_COMMENT 2
842-#define SCE_T3_LINE_COMMENT 3
843-#define SCE_T3_OPERATOR 4
844-#define SCE_T3_KEYWORD 5
845-#define SCE_T3_NUMBER 6
846-#define SCE_T3_BRACKET 7
847-#define SCE_T3_HTML_TAG 8
848-#define SCE_T3_HTML_STRING 9
849-#define SCE_T3_S_STRING 10
850-#define SCE_T3_S_LIB_DIRECTIVE 11
851-#define SCE_T3_S_MSG_PARAM 12
852-#define SCE_T3_S_H_DEFAULT 13
853-#define SCE_T3_D_STRING 14
854-#define SCE_T3_D_LIB_DIRECTIVE 15
855-#define SCE_T3_D_MSG_PARAM 16
856-#define SCE_T3_D_H_DEFAULT 17
857-#define SCE_T3_X_DEFAULT 18
858-#define SCE_T3_X_PREPROCESSOR 19
859-#define SCE_T3_X_BLOCK_COMMENT 20
860-#define SCE_T3_X_LINE_COMMENT 21
861-#define SCE_T3_X_S_STRING 22
862-#define SCE_T3_X_S_LIB_DIRECTIVE 23
863-#define SCE_T3_X_S_MSG_PARAM 24
864-#define SCE_T3_X_S_H_DEFAULT 25
865-#define SCE_T3_X_D_STRING 26
866-#define SCE_T3_X_D_LIB_DIRECTIVE 27
867-#define SCE_T3_X_D_MSG_PARAM 28
868-#define SCE_T3_X_D_H_DEFAULT 29
869-#define SCE_T3_USER1 30
870-#define SCE_T3_USER2 31
881+#define SCE_T3_X_DEFAULT 1
882+#define SCE_T3_PREPROCESSOR 2
883+#define SCE_T3_BLOCK_COMMENT 3
884+#define SCE_T3_LINE_COMMENT 4
885+#define SCE_T3_OPERATOR 5
886+#define SCE_T3_KEYWORD 6
887+#define SCE_T3_NUMBER 7
888+#define SCE_T3_IDENTIFIER 8
889+#define SCE_T3_S_STRING 9
890+#define SCE_T3_D_STRING 10
891+#define SCE_T3_X_STRING 11
892+#define SCE_T3_LIB_DIRECTIVE 12
893+#define SCE_T3_MSG_PARAM 13
894+#define SCE_T3_HTML_TAG 14
895+#define SCE_T3_HTML_DEFAULT 15
896+#define SCE_T3_HTML_STRING 16
897+#define SCE_T3_USER1 17
898+#define SCE_T3_USER2 18
899+#define SCE_T3_USER3 19
871900 #define SCE_REBOL_DEFAULT 0
872901 #define SCE_REBOL_COMMENTLINE 1
873902 #define SCE_REBOL_COMMENTBLOCK 2
--- trunk/src/Utils/scintilla/include/Scintilla.h (revision 4272)
+++ trunk/src/Utils/scintilla/include/Scintilla.h (revision 4273)
@@ -166,6 +166,7 @@
166166 #define SC_CHARSET_MAC 77
167167 #define SC_CHARSET_OEM 255
168168 #define SC_CHARSET_RUSSIAN 204
169+#define SC_CHARSET_CYRILLIC 1251
169170 #define SC_CHARSET_SHIFTJIS 128
170171 #define SC_CHARSET_SYMBOL 2
171172 #define SC_CHARSET_TURKISH 162
--- trunk/src/Utils/scintilla/src/CallTip.cxx (revision 4272)
+++ trunk/src/Utils/scintilla/src/CallTip.cxx (revision 4273)
@@ -18,8 +18,8 @@
1818 inCallTipMode = false;
1919 posStartCallTip = 0;
2020 val = 0;
21- xUp = -100;
22- xDown = -100;
21+ rectUp = PRectangle(0,0,0,0);
22+ rectDown = PRectangle(0,0,0,0);
2323 lineHeight = 1;
2424 startHighlight = 0;
2525 endHighlight = 0;
@@ -75,12 +75,12 @@
7575 if (IsArrowCharacter(s[startSeg])) {
7676 xEnd = x + widthArrow;
7777 offsetMain = xEnd;
78+ rcClient.left = x;
79+ rcClient.right = xEnd;
7880 if (draw) {
7981 const int halfWidth = widthArrow / 2 - 3;
8082 const int centreX = x + widthArrow / 2 - 1;
8183 const int centreY = (rcClient.top + rcClient.bottom) / 2;
82- rcClient.left = x;
83- rcClient.right = xEnd;
8484 surface->FillRectangle(rcClient, colourBG.allocated);
8585 PRectangle rcClientInner(rcClient.left+1, rcClient.top+1, rcClient.right-2, rcClient.bottom-1);
8686 surface->FillRectangle(rcClientInner, colourUnSel.allocated);
@@ -104,13 +104,12 @@
104104 surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
105105 colourBG.allocated, colourBG.allocated);
106106 }
107- } else {
108- if (s[startSeg] == '\001') {
109- xUp = x+1;
110- } else {
111- xDown = x+1;
112- }
113107 }
108+ if (s[startSeg] == '\001') {
109+ rectUp = rcClient;
110+ } else if (s[startSeg] == '\002') {
111+ rectDown = rcClient;
112+ }
114113 } else {
115114 xEnd = x + surface->WidthText(font, s+startSeg, endSeg - startSeg);
116115 if (draw) {
@@ -203,13 +202,10 @@
203202
204203 void CallTip::MouseClick(Point pt) {
205204 clickPlace = 0;
206- if (pt.y < lineHeight) {
207- if ((pt.x > xUp) && (pt.x < xUp + widthArrow - 2)) {
208- clickPlace = 1;
209- } else if ((pt.x > xDown) && (pt.x < xDown + widthArrow - 2)) {
210- clickPlace = 2;
211- }
212- }
205+ if (rectUp.Contains(pt))
206+ clickPlace = 1;
207+ if (rectDown.Contains(pt))
208+ clickPlace = 2;
213209 }
214210
215211 PRectangle CallTip::CallTipStart(int pos, Point pt, const char *defn,
@@ -240,8 +236,8 @@
240236 int numLines = 1;
241237 const char *newline;
242238 const char *look = val;
243- xUp = -100;
244- xDown = -100;
239+ rectUp = PRectangle(0,0,0,0);
240+ rectDown = PRectangle(0,0,0,0);
245241 offsetMain = 5;
246242 int width = PaintContents(surfaceMeasure, false) + 5;
247243 while ((newline = strchr(look, '\n')) != NULL) {
--- trunk/src/Utils/scintilla/src/CallTip.h (revision 4272)
+++ trunk/src/Utils/scintilla/src/CallTip.h (revision 4273)
@@ -15,8 +15,8 @@
1515 int endHighlight;
1616 char *val;
1717 Font font;
18- int xUp;
19- int xDown;
18+ PRectangle rectUp;
19+ PRectangle rectDown;
2020 int lineHeight;
2121 int offsetMain;
2222 // Private so CallTip objects can not be copied
--- trunk/src/Utils/scintilla/src/CellBuffer.cxx (revision 4272)
+++ trunk/src/Utils/scintilla/src/CellBuffer.cxx (revision 4273)
@@ -254,9 +254,14 @@
254254 linesData[i] = linesData[i + 1];
255255 }
256256 if (levels) {
257+ // Move up following lines but merge header flag from this line
258+ // to line before to avoid a temporary disappearence causing expansion.
259+ int firstHeader = levels[pos] & SC_FOLDLEVELHEADERFLAG;
257260 for (int j = pos; j < lines; j++) {
258261 levels[j] = levels[j + 1];
259262 }
263+ if (pos > 0)
264+ levels[pos-1] |= firstHeader;
260265 }
261266 lines--;
262267 }
--- trunk/src/Utils/scintilla/src/Document.cxx (revision 4272)
+++ trunk/src/Utils/scintilla/src/Document.cxx (revision 4273)
@@ -966,6 +966,9 @@
966966 pdoc(pdoc_), end(end_) {
967967 }
968968
969+ virtual ~DocumentIndexer() {
970+ }
971+
969972 virtual char CharAt(int index) {
970973 if (index < 0 || index >= end)
971974 return 0;
--- trunk/src/Utils/scintilla/src/Editor.cxx (revision 4272)
+++ trunk/src/Utils/scintilla/src/Editor.cxx (revision 4273)
@@ -452,6 +452,7 @@
452452 pixmapSelMargin->Release();
453453 pixmapSelPattern->Release();
454454 pixmapIndentGuide->Release();
455+ pixmapIndentGuideHighlight->Release();
455456 }
456457
457458 void Editor::InvalidateStyleData() {
@@ -3243,9 +3244,12 @@
32433244 void Editor::AddCharUTF(char *s, unsigned int len, bool treatAsDBCS) {
32443245 bool wasSelection = currentPos != anchor;
32453246 ClearSelection();
3247+ bool charReplaceAction = false;
32463248 if (inOverstrike && !wasSelection && !RangeContainsProtected(currentPos, currentPos + 1)) {
32473249 if (currentPos < (pdoc->Length())) {
32483250 if (!IsEOLChar(pdoc->CharAt(currentPos))) {
3251+ charReplaceAction = true;
3252+ pdoc->BeginUndoAction();
32493253 pdoc->DelChar(currentPos);
32503254 }
32513255 }
@@ -3253,6 +3257,9 @@
32533257 if (pdoc->InsertString(currentPos, s, len)) {
32543258 SetEmptySelection(currentPos + len);
32553259 }
3260+ if (charReplaceAction) {
3261+ pdoc->EndUndoAction();
3262+ }
32563263 EnsureCaretVisible();
32573264 // Avoid blinking during rapid typing:
32583265 ShowCaretAtCurrentPosition();
@@ -3688,7 +3695,7 @@
36883695 // Some lines are hidden so may need shown.
36893696 // TODO: check if the modified area is hidden.
36903697 if (mh.modificationType & SC_MOD_BEFOREINSERT) {
3691- NotifyNeedShown(mh.position, mh.length);
3698+ NotifyNeedShown(mh.position, 0);
36923699 } else if (mh.modificationType & SC_MOD_BEFOREDELETE) {
36933700 NotifyNeedShown(mh.position, mh.length);
36943701 }
@@ -5291,7 +5298,9 @@
52915298 if (timer.ticksToWait <= 0) {
52925299 caret.on = !caret.on;
52935300 timer.ticksToWait = caret.period;
5294- InvalidateCaret();
5301+ if (caret.active) {
5302+ InvalidateCaret();
5303+ }
52955304 }
52965305 }
52975306 if ((dwellDelay < SC_TIME_FOREVER) &&
--- trunk/src/Utils/scintilla/src/KeyWords.cxx (revision 4272)
+++ trunk/src/Utils/scintilla/src/KeyWords.cxx (revision 4273)
@@ -139,6 +139,7 @@
139139 LINK_LEXER(lmBash);
140140 LINK_LEXER(lmBlitzBasic);
141141 LINK_LEXER(lmPureBasic);
142+ LINK_LEXER(lmFreeBasic);
142143 LINK_LEXER(lmBullant);
143144 LINK_LEXER(lmCaml);
144145 LINK_LEXER(lmClw);
--- trunk/src/Utils/scintilla/src/LexAU3.cxx (revision 4272)
+++ trunk/src/Utils/scintilla/src/LexAU3.cxx (revision 4273)
@@ -30,7 +30,16 @@
3030 // Oct 10, 2004 - Added logic to show Comments in "Special" directives.
3131 // Nov 1, 2004 - Added better testing for Numbers supporting x and e notation.
3232 // Nov 28, 2004 - Added logic to handle continuation lines for syntax highlighting.
33-//
33+// Jan 10, 2005 - Added Abbreviations Keyword used for expansion
34+// Mar 24, 2005 - Updated Abbreviations Keywords to fix when followed by Operator.
35+// Apr 18, 2005 - Updated #CE/#Comment-End logic to take a linecomment ";" into account
36+// - Added folding support for With...EndWith
37+// - Added support for a DOT in variable names
38+// - Fixed Underscore in CommentBlock
39+// May 23, 2005 - Fixed the SentKey lexing in case of a missing }
40+// Aug 11, 2005 - Fixed possible bug with s_save length > 100.
41+// Aug 23, 2005 - Added Switch/endswitch support to the folding logic.
42+//
3443 // Copyright for Scintilla: 1998-2001 by Neil Hodgson <neilh@scintilla.org>
3544 // The License.txt file describes the conditions under which this software may be distributed.
3645 // Scintilla source code edit control
@@ -61,7 +70,7 @@
6170
6271 static inline bool IsAWordStart(const int ch)
6372 {
64- return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '@' || ch == '#' || ch == '$');
73+ return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '@' || ch == '#' || ch == '$' || ch == '.');
6574 }
6675
6776 static inline bool IsAOperator(char ch) {
@@ -93,8 +102,12 @@
93102 // split the portion of the sendkey in the part before and after the spaces
94103 while ( ( (cTemp = szLine[nPos]) != '\0'))
95104 {
96- if ((cTemp == ' ') && (nFlag == 0) ) // get the stuff till first space
105+ // skip leading Ctrl/Shift/ALt state
106+ if ((cTemp == '#' || cTemp == '!' || cTemp == '^') && (szLine[nPos+1] == '{') )
97107 {
108+ }
109+ else if ((cTemp == ' ') && (nFlag == 0) ) // get the stuff till first space
110+ {
98111 nFlag = 1;
99112 // Add } to the end of the first bit for table lookup later.
100113 szKey[nKeyPos++] = '}';
@@ -180,11 +193,14 @@
180193 // find the first previous line without continuation character at the end
181194 int lineCurrent = styler.GetLine(startPos);
182195 int s_startPos = startPos;
183- while ((lineCurrent > 0 && IsContinuationLine(lineCurrent,styler)) ||
184- (lineCurrent > 1 && IsContinuationLine(lineCurrent-1,styler))) {
185- lineCurrent--;
186- startPos = styler.LineStart(lineCurrent); // get start position
187- initStyle = 0; // reset the start style to 0
196+ // When not inside a Block comment: find First line without _
197+ if (!(initStyle==SCE_AU3_COMMENTBLOCK)) {
198+ while ((lineCurrent > 0 && IsContinuationLine(lineCurrent,styler)) ||
199+ (lineCurrent > 1 && IsContinuationLine(lineCurrent-1,styler))) {
200+ lineCurrent--;
201+ startPos = styler.LineStart(lineCurrent); // get start position
202+ initStyle = 0; // reset the start style to 0
203+ }
188204 }
189205 // Set the new length to include it from the start and set the start position
190206 length = length + s_startPos - startPos; // correct the total length to process
@@ -193,22 +209,25 @@
193209 StyleContext sc(startPos, length, initStyle, styler);
194210 char si; // string indicator "=1 '=2
195211 char ni; // Numeric indicator error=9 normal=0 normal+dec=1 hex=2 Enot=3
212+ char ci; // comment indicator 0=not linecomment(;)
196213 char s_save[100];
197214 si=0;
198215 ni=0;
216+ ci=0;
199217 //$$$
200218 for (; sc.More(); sc.Forward()) {
201219 char s[100];
202220 sc.GetCurrentLowered(s, sizeof(s));
203221 // **********************************************
204- // save the total current word for eof processing
205- if (IsAWordChar(sc.ch))
222+ // save the total current word for eof processing
223+ if (IsAWordChar(sc.ch) || sc.ch == '}')
206224 {
207225 strcpy(s_save,s);
208- char test = static_cast<char>(sc.ch);
209226 int tp = strlen(s_save);
210- s_save[tp] = static_cast<char>(tolower(test));
211- s_save[tp+1] = '\0';
227+ if (tp < 99) {
228+ s_save[tp] = static_cast<char>(tolower(sc.ch));
229+ s_save[tp+1] = '\0';
230+ }
212231 }
213232 // **********************************************
214233 //
@@ -216,12 +235,32 @@
216235 {
217236 case SCE_AU3_COMMENTBLOCK:
218237 {
219- if (!(IsAWordChar(sc.ch) || (sc.ch == '-' && strcmp(s, "#comments") == 0)))
220- {
238+ //Reset at line end
239+ if (sc.atLineEnd) {
240+ ci=0;
241+ sc.SetState(SCE_AU3_COMMENTBLOCK);
242+ }
243+ //skip rest of line when a ; is encountered
244+ if (sc.chPrev == ';') {
245+ ci=2;
246+ sc.SetState(SCE_AU3_COMMENTBLOCK);
247+ }
248+ // skip rest of the line
249+ if (ci==2)
250+ break;
251+ // check when first character is detected on the line
252+ if (ci==0) {
253+ if (IsAWordStart(static_cast<char>(sc.ch)) || IsAOperator(static_cast<char>(sc.ch))) {
254+ ci=1;
255+ sc.SetState(SCE_AU3_COMMENTBLOCK);
256+ }
257+ break;
258+ }
259+ if (!(IsAWordChar(sc.ch) || (sc.ch == '-' && strcmp(s, "#comments") == 0))) {
221260 if ((strcmp(s, "#ce")== 0 || strcmp(s, "#comments-end")== 0))
222- {sc.SetState(SCE_AU3_COMMENT);} // set to comment line for the rest of the line
261+ sc.SetState(SCE_AU3_COMMENT); // set to comment line for the rest of the line
223262 else
224- {sc.SetState(SCE_AU3_COMMENTBLOCK);}
263+ ci=2; // line doesn't begin with #CE so skip the rest of the line
225264 }
226265 break;
227266 }
@@ -232,7 +271,13 @@
232271 }
233272 case SCE_AU3_OPERATOR:
234273 {
235- sc.SetState(SCE_AU3_DEFAULT);
274+ // check if its a COMobject
275+ if (sc.chPrev == '.' && IsAWordChar(sc.ch)) {
276+ sc.SetState(SCE_AU3_COMOBJ);
277+ }
278+ else {
279+ sc.SetState(SCE_AU3_DEFAULT);
280+ }
236281 break;
237282 }
238283 case SCE_AU3_SPECIAL:
@@ -276,7 +321,7 @@
276321 sc.ChangeState(SCE_AU3_SPECIAL);
277322 sc.SetState(SCE_AU3_SPECIAL);
278323 }
279- else if (keywords7.InList(s)) {
324+ else if ((keywords7.InList(s)) && (!IsAOperator(static_cast<char>(sc.ch)))) {
280325 sc.ChangeState(SCE_AU3_EXPAND);
281326 sc.SetState(SCE_AU3_DEFAULT);
282327 }
@@ -290,7 +335,8 @@
290335 }
291336 }
292337 }
293- if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
338+ if (sc.atLineEnd) {
339+ sc.SetState(SCE_AU3_DEFAULT);}
294340 break;
295341 }
296342 case SCE_AU3_NUMBER:
@@ -338,12 +384,26 @@
338384 }
339385 sc.SetState(SCE_AU3_DEFAULT);
340386 }
387+ break;
341388 }
342389 case SCE_AU3_VARIABLE:
343390 {
344- if (!IsAWordChar(sc.ch)) {sc.SetState(SCE_AU3_DEFAULT);}
391+ // Check if its a COMObject
392+ if (sc.ch == '.' && !IsADigit(sc.chNext)) {
393+ sc.SetState(SCE_AU3_OPERATOR);
394+ }
395+ else if (!IsAWordChar(sc.ch)) {
396+ sc.SetState(SCE_AU3_DEFAULT);
397+ }
345398 break;
346399 }
400+ case SCE_AU3_COMOBJ:
401+ {
402+ if (!(IsAWordChar(sc.ch))) {
403+ sc.SetState(SCE_AU3_DEFAULT);
404+ }
405+ break;
406+ }
347407 case SCE_AU3_STRING:
348408 {
349409 // check for " to end a double qouted string or
@@ -402,10 +462,11 @@
402462 // check if next portion is again a sendkey
403463 if (sc.atLineEnd)
404464 {
465+ sc.ChangeState(SCE_AU3_STRING);
405466 sc.SetState(SCE_AU3_DEFAULT);
406467 si = 0; // reset string indicator
407468 }
408- if (sc.ch == '{' && sc.chPrev != '{') {sc.SetState(SCE_AU3_SENT);}
469+ //if (sc.ch == '{' && sc.chPrev != '{') {sc.SetState(SCE_AU3_SENT);}
409470 if (sc.ch == '+' && sc.chNext == '{') {sc.SetState(SCE_AU3_SENT);}
410471 if (sc.ch == '!' && sc.chNext == '{') {sc.SetState(SCE_AU3_SENT);}
411472 if (sc.ch == '^' && sc.chNext == '{') {sc.SetState(SCE_AU3_SENT);}
@@ -428,6 +489,7 @@
428489 if (sc.ch == ';') {sc.SetState(SCE_AU3_COMMENT);}
429490 else if (sc.ch == '#') {sc.SetState(SCE_AU3_KEYWORD);}
430491 else if (sc.ch == '$') {sc.SetState(SCE_AU3_VARIABLE);}
492+ else if (sc.ch == '.' && !IsADigit(sc.chNext)) {sc.SetState(SCE_AU3_OPERATOR);}
431493 else if (sc.ch == '@') {sc.SetState(SCE_AU3_KEYWORD);}
432494 else if (sc.ch == '<' && si==3) {sc.SetState(SCE_AU3_STRING);} // string after #include
433495 else if (sc.ch == '\"') {
@@ -477,7 +539,7 @@
477539 sc.ChangeState(SCE_AU3_SPECIAL);
478540 sc.SetState(SCE_AU3_SPECIAL);
479541 }
480- else if (keywords7.InList(s_save)) {
542+ else if (keywords7.InList(s_save) && sc.atLineEnd) {
481543 sc.ChangeState(SCE_AU3_EXPAND);
482544 sc.SetState(SCE_AU3_EXPAND);
483545 }
@@ -486,6 +548,42 @@
486548 sc.SetState(SCE_AU3_DEFAULT);
487549 }
488550 }
551+ if (sc.state == SCE_AU3_SENT)
552+ {
553+ // Send key string ended
554+ if (sc.chPrev == '}' && sc.ch != '}')
555+ {
556+ // set color to SENDKEY when valid sendkey .. else set back to regular string
557+ char sk[100];
558+ // split {111 222} and return {111} and check if 222 is valid.
559+ // if return code = 1 then invalid 222 so must be string
560+ if (GetSendKey(s_save,sk))
561+ {
562+ sc.ChangeState(SCE_AU3_STRING);
563+ }
564+ // if single char between {?} then its ok as sendkey for a single character
565+ else if (strlen(sk) == 3)
566+ {
567+ sc.ChangeState(SCE_AU3_SENT);
568+ }
569+ // if sendkey {111} is in table then ok as sendkey
570+ else if (keywords4.InList(sk))
571+ {
572+ sc.ChangeState(SCE_AU3_SENT);
573+ }
574+ else
575+ {
576+ sc.ChangeState(SCE_AU3_STRING);
577+ }
578+ sc.SetState(SCE_AU3_STRING);
579+ }
580+ // check if next portion is again a sendkey
581+ if (sc.atLineEnd)
582+ {
583+ sc.ChangeState(SCE_AU3_STRING);
584+ sc.SetState(SCE_AU3_DEFAULT);
585+ }
586+ }
489587 //*************************************
490588 sc.Complete();
491589 }
@@ -629,11 +727,11 @@
629727 // create new fold for these words
630728 if (strcmp(szKeyword,"do") == 0 || strcmp(szKeyword,"for") == 0 ||
631729 strcmp(szKeyword,"func") == 0 || strcmp(szKeyword,"while") == 0||
632- strcmp(szKeyword,"#region") == 0 ) {
730+ strcmp(szKeyword,"with") == 0 || strcmp(szKeyword,"#region") == 0 ) {
633731 levelNext++;
634732 }
635- // create double Fold for select because Case will subtract one of the current level
636- if (strcmp(szKeyword,"select") == 0) {
733+ // create double Fold for select&switch because Case will subtract one of the current level
734+ if (strcmp(szKeyword,"select") == 0 || strcmp(szKeyword,"switch") == 0) {
637735 levelNext++;
638736 levelNext++;
639737 }
@@ -640,7 +738,7 @@
640738 // end the fold for these words before the current line
641739 if (strcmp(szKeyword,"endfunc") == 0 || strcmp(szKeyword,"endif") == 0 ||
642740 strcmp(szKeyword,"next") == 0 || strcmp(szKeyword,"until") == 0 ||
643- strcmp(szKeyword,"wend") == 0){
741+ strcmp(szKeyword,"endwith") == 0 ||strcmp(szKeyword,"wend") == 0){
644742 levelNext--;
645743 levelCurrent--;
646744 }
@@ -650,7 +748,7 @@
650748 levelCurrent--;
651749 }
652750 // end the double fold for this word before the current line
653- if (strcmp(szKeyword,"endselect") == 0 ) {
751+ if (strcmp(szKeyword,"endselect") == 0 || strcmp(szKeyword,"endswitch") == 0 ) {
654752 levelNext--;
655753 levelNext--;
656754 levelCurrent--;
--- trunk/src/Utils/scintilla/src/LexAVE.cxx (revision 4272)
+++ trunk/src/Utils/scintilla/src/LexAVE.cxx (revision 4273)
@@ -182,7 +182,9 @@
182182 if ((strcmp(s, "then") == 0) || (strcmp(s, "for") == 0) || (strcmp(s, "while") == 0)) {
183183 levelCurrent++;
184184 }
185- if ((strcmp(s, "end") == 0)) {
185+ if ((strcmp(s, "end") == 0) || (strcmp(s, "elseif") == 0)) {
186+ // Normally "elseif" and "then" will be on the same line and will cancel
187+ // each other out. // As implemented, this does not support fold.at.else.
186188 levelCurrent--;
187189 }
188190 }
--- trunk/src/Utils/scintilla/src/LexBash.cxx (revision 4272)
+++ trunk/src/Utils/scintilla/src/LexBash.cxx (revision 4273)
@@ -2,7 +2,7 @@
22 /** @file LexBash.cxx
33 ** Lexer for Bash.
44 **/
5-// Copyright 2004 by Neil Hodgson <neilh@scintilla.org>
5+// Copyright 2004-2005 by Neil Hodgson <neilh@scintilla.org>
66 // Adapted from LexPerl by Kein-Hong Man <mkh@pl.jaring.my> 2004
77 // The License.txt file describes the conditions under which this software may be distributed.
88
@@ -144,6 +144,9 @@
144144 char *Delimiter; // the Delimiter, 256: sizeof PL_tokenbuf
145145 HereDocCls() {
146146 State = 0;
147+ Quote = 0;
148+ Quoted = false;
149+ Indent = 0;
147150 DelimiterLength = 0;
148151 Delimiter = new char[HERE_DELIM_MAX];
149152 Delimiter[0] = '\0';
@@ -582,6 +585,19 @@
582585 styler.ColourTo(lengthDoc - 1, state);
583586 }
584587
588+static bool IsCommentLine(int line, Accessor &styler) {
589+ int pos = styler.LineStart(line);
590+ int eol_pos = styler.LineStart(line + 1) - 1;
591+ for (int i = pos; i < eol_pos; i++) {
592+ char ch = styler[i];
593+ if (ch == '#')
594+ return true;
595+ else if (ch != ' ' && ch != '\t')
596+ return false;
597+ }
598+ return false;
599+}
600+
585601 static void FoldBashDoc(unsigned int startPos, int length, int, WordList *[],
586602 Accessor &styler) {
587603 bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
@@ -599,16 +615,16 @@
599615 int style = styleNext;
600616 styleNext = styler.StyleAt(i + 1);
601617 bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
602- if (foldComment && (style == SCE_SH_COMMENTLINE)) {
603- if ((ch == '/') && (chNext == '/')) {
604- char chNext2 = styler.SafeGetCharAt(i + 2);
605- if (chNext2 == '{') {
606- levelCurrent++;
607- } else if (chNext2 == '}') {
608- levelCurrent--;
609- }
610- }
611- }
618+ // Comment folding
619+ if (foldComment && atEOL && IsCommentLine(lineCurrent, styler))
620+ {
621+ if (!IsCommentLine(lineCurrent - 1, styler)
622+ && IsCommentLine(lineCurrent + 1, styler))
623+ levelCurrent++;
624+ else if (IsCommentLine(lineCurrent - 1, styler)
625+ && !IsCommentLine(lineCurrent+1, styler))
626+ levelCurrent--;
627+ }
612628 if (style == SCE_C_OPERATOR) {
613629 if (ch == '{') {
614630 levelCurrent++;
--- trunk/src/Utils/scintilla/src/LexBasic.cxx (revision 4272)
+++ trunk/src/Utils/scintilla/src/LexBasic.cxx (revision 4273)
@@ -83,7 +83,7 @@
8383 }
8484
8585 static void ColouriseBasicDoc(unsigned int startPos, int length, int initStyle,
86- WordList *keywordlists[], Accessor &styler) {
86+ WordList *keywordlists[], Accessor &styler, char comment_char) {
8787 bool wasfirst = true, isfirst = true; // true if first token in a line
8888 styler.StartAt(startPos);
8989
@@ -159,7 +159,10 @@
159159 if (sc.state == SCE_B_DEFAULT || sc.state == SCE_B_ERROR) {
160160 if (isfirst && sc.Match('.')) {
161161 sc.SetState(SCE_B_LABEL);
162- } else if (sc.Match(';')) {
162+ } else if (isfirst && sc.Match('#')) {
163+ wasfirst = isfirst;
164+ sc.SetState(SCE_B_IDENTIFIER);
165+ } else if (sc.Match(comment_char)) {
163166 sc.SetState(SCE_B_COMMENT);
164167 } else if (sc.Match('"')) {
165168 sc.SetState(SCE_B_STRING);
@@ -220,6 +223,21 @@
220223 return 0;
221224 }
222225
226+static int CheckFreeFoldPoint(char const *token, int &level) {
227+ if (!strcmp(token, "function") ||
228+ !strcmp(token, "sub") ||
229+ !strcmp(token, "type")) {
230+ level |= SC_FOLDLEVELHEADERFLAG;
231+ return 1;
232+ }
233+ if (!strcmp(token, "end function") ||
234+ !strcmp(token, "end sub") ||
235+ !strcmp(token, "end type")) {
236+ return -1;
237+ }
238+ return 0;
239+}
240+
223241 static void FoldBasicDoc(unsigned int startPos, int length,
224242 Accessor &styler, int (*CheckFoldPoint)(char const *, int &)) {
225243 int line = styler.GetLine(startPos);
@@ -283,14 +301,19 @@
283301
284302 static void ColouriseBlitzBasicDoc(unsigned int startPos, int length, int initStyle,
285303 WordList *keywordlists[], Accessor &styler) {
286- ColouriseBasicDoc(startPos, length, initStyle, keywordlists, styler);
304+ ColouriseBasicDoc(startPos, length, initStyle, keywordlists, styler, ';');
287305 }
288306
289307 static void ColourisePureBasicDoc(unsigned int startPos, int length, int initStyle,
290308 WordList *keywordlists[], Accessor &styler) {
291- ColouriseBasicDoc(startPos, length, initStyle, keywordlists, styler);
309+ ColouriseBasicDoc(startPos, length, initStyle, keywordlists, styler, ';');
292310 }
293311
312+static void ColouriseFreeBasicDoc(unsigned int startPos, int length, int initStyle,
313+ WordList *keywordlists[], Accessor &styler) {
314+ ColouriseBasicDoc(startPos, length, initStyle, keywordlists, styler, '\'');
315+}
316+
294317 static void FoldBlitzBasicDoc(unsigned int startPos, int length, int,
295318 WordList *[], Accessor &styler) {
296319 FoldBasicDoc(startPos, length, styler, CheckBlitzFoldPoint);
@@ -301,6 +324,11 @@
301324 FoldBasicDoc(startPos, length, styler, CheckPureFoldPoint);
302325 }
303326
327+static void FoldFreeBasicDoc(unsigned int startPos, int length, int,
328+ WordList *[], Accessor &styler) {
329+ FoldBasicDoc(startPos, length, styler, CheckFreeFoldPoint);
330+}
331+
304332 static const char * const blitzbasicWordListDesc[] = {
305333 "BlitzBasic Keywords",
306334 "user1",
@@ -317,6 +345,14 @@
317345 0
318346 };
319347
348+static const char * const freebasicWordListDesc[] = {
349+ "FreeBasic Keywords",
350+ "FreeBasic PreProcessor Keywords",
351+ "user defined 1",
352+ "user defined 2",
353+ 0
354+};
355+
320356 LexerModule lmBlitzBasic(SCLEX_BLITZBASIC, ColouriseBlitzBasicDoc, "blitzbasic",
321357 FoldBlitzBasicDoc, blitzbasicWordListDesc);
322358
@@ -323,3 +359,6 @@
323359 LexerModule lmPureBasic(SCLEX_PUREBASIC, ColourisePureBasicDoc, "purebasic",
324360 FoldPureBasicDoc, purebasicWordListDesc);
325361
362+LexerModule lmFreeBasic(SCLEX_FREEBASIC, ColouriseFreeBasicDoc, "freebasic",
363+ FoldFreeBasicDoc, freebasicWordListDesc);
364+
--- trunk/src/Utils/scintilla/src/LexCLW.cxx (revision 4272)
+++ trunk/src/Utils/scintilla/src/LexCLW.cxx (revision 4273)
@@ -42,7 +42,8 @@
4242 static void StringUpper(char *szString) {
4343
4444 while (*szString) {
45- *szString++ = CharacterUpper(*szString);
45+ *szString = CharacterUpper(*szString);
46+ szString++;
4647 }
4748 }
4849
--- trunk/src/Utils/scintilla/src/LexCPP.cxx (revision 4272)
+++ trunk/src/Utils/scintilla/src/LexCPP.cxx (revision 4273)
@@ -1,8 +1,8 @@
11 // Scintilla source code edit control
22 /** @file LexCPP.cxx
3- ** Lexer for C++, C, Java, and Javascript.
3+ ** Lexer for C++, C, Java, and JavaScript.
44 **/
5-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
5+// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
66 // The License.txt file describes the conditions under which this software may be distributed.
77
88 #include <stdlib.h>
@@ -23,19 +23,19 @@
2323 #define KEYWORD_BOXHEADER 1
2424 #define KEYWORD_FOLDCONTRACTED 2
2525
26-static bool IsOKBeforeRE(const int ch) {
26+static bool IsOKBeforeRE(int ch) {
2727 return (ch == '(') || (ch == '=') || (ch == ',');
2828 }
2929
30-static inline bool IsAWordChar(const int ch) {
30+static inline bool IsAWordChar(int ch) {
3131 return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
3232 }
3333
34-static inline bool IsAWordStart(const int ch) {
35- return (ch < 0x80) && (isalnum(ch) || ch == '_');
34+static inline bool IsAWordStart(int ch) {
35+ return (ch < 0x80) && (isalpha(ch) || ch == '_');
3636 }
3737
38-static inline bool IsADoxygenChar(const int ch) {
38+static inline bool IsADoxygenChar(int ch) {
3939 return (islower(ch) || ch == '$' || ch == '@' ||
4040 ch == '\\' || ch == '&' || ch == '<' ||
4141 ch == '>' || ch == '#' || ch == '{' ||
@@ -42,18 +42,6 @@
4242 ch == '}' || ch == '[' || ch == ']');
4343 }
4444
45-static inline bool IsStateComment(const int state) {
46- return ((state == SCE_C_COMMENT) ||
47- (state == SCE_C_COMMENTLINE) ||
48- (state == SCE_C_COMMENTDOC) ||
49- (state == SCE_C_COMMENTDOCKEYWORD) ||
50- (state == SCE_C_COMMENTDOCKEYWORDERROR));
51-}
52-
53-static inline bool IsStateString(const int state) {
54- return ((state == SCE_C_STRING) || (state == SCE_C_VERBATIM));
55-}
56-
5745 static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
5846 Accessor &styler, bool caseSensitive) {
5947
@@ -64,21 +52,26 @@
6452
6553 bool stylingWithinPreprocessor = styler.GetPropertyInt("styling.within.preprocessor") != 0;
6654
67- // Do not leak onto next line
68- if (initStyle == SCE_C_STRINGEOL)
69- initStyle = SCE_C_DEFAULT;
70-
7155 int chPrevNonWhite = ' ';
7256 int visibleChars = 0;
7357 bool lastWordWasUUID = false;
58+ int styleBeforeDCKeyword = SCE_C_DEFAULT;
7459
7560 StyleContext sc(startPos, length, initStyle, styler);
7661
7762 for (; sc.More(); sc.Forward()) {
7863
79- if (sc.atLineStart && (sc.state == SCE_C_STRING)) {
80- // Prevent SCE_C_STRINGEOL from leaking back to previous line
81- sc.SetState(SCE_C_STRING);
64+ if (sc.atLineStart) {
65+ if (sc.state == SCE_C_STRING) {
66+ // Prevent SCE_C_STRINGEOL from leaking back to previous line which
67+ // ends with a line continuation by locking in the state upto this position.
68+ sc.SetState(SCE_C_STRING);
69+ }
70+ // Reset states to begining of colourise so no surprises
71+ // if different sets of lines lexed.
72+ chPrevNonWhite = ' ';
73+ visibleChars = 0;
74+ lastWordWasUUID = false;
8275 }
8376
8477 // Handle line continuation generically.
@@ -93,122 +86,152 @@
9386 }
9487
9588 // Determine if the current state should terminate.
96- if (sc.state == SCE_C_OPERATOR) {
97- sc.SetState(SCE_C_DEFAULT);
98- } else if (sc.state == SCE_C_NUMBER) {
99- if (!IsAWordChar(sc.ch)) {
89+ switch (sc.state) {
90+ case SCE_C_OPERATOR:
10091 sc.SetState(SCE_C_DEFAULT);
101- }
102- } else if (sc.state == SCE_C_IDENTIFIER) {
103- if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
104- char s[100];
105- if (caseSensitive) {
106- sc.GetCurrent(s, sizeof(s));
107- } else {
108- sc.GetCurrentLowered(s, sizeof(s));
92+ break;
93+ case SCE_C_NUMBER:
94+ // We accept almost anything because of hex. and number suffixes
95+ if (!IsAWordChar(sc.ch)) {
96+ sc.SetState(SCE_C_DEFAULT);
10997 }
110- if (keywords.InList(s)) {
111- lastWordWasUUID = strcmp(s, "uuid") == 0;
112- sc.ChangeState(SCE_C_WORD);
113- } else if (keywords2.InList(s)) {
114- sc.ChangeState(SCE_C_WORD2);
115- } else if (keywords4.InList(s)) {
116- sc.ChangeState(SCE_C_GLOBALCLASS);
117- }
118- sc.SetState(SCE_C_DEFAULT);
119- }
120- } else if (sc.state == SCE_C_PREPROCESSOR) {
121- if (stylingWithinPreprocessor) {
122- if (IsASpace(sc.ch)) {
98+ break;
99+ case SCE_C_IDENTIFIER:
100+ if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
101+ char s[1000];
102+ if (caseSensitive) {
103+ sc.GetCurrent(s, sizeof(s));
104+ } else {
105+ sc.GetCurrentLowered(s, sizeof(s));
106+ }
107+ if (keywords.InList(s)) {
108+ lastWordWasUUID = strcmp(s, "uuid") == 0;
109+ sc.ChangeState(SCE_C_WORD);
110+ } else if (keywords2.InList(s)) {
111+ sc.ChangeState(SCE_C_WORD2);
112+ } else if (keywords4.InList(s)) {
113+ sc.ChangeState(SCE_C_GLOBALCLASS);
114+ }
123115 sc.SetState(SCE_C_DEFAULT);
124116 }
125- } else {
126- if ((sc.ch == '\r') || (sc.ch == '\n') || (sc.Match('/', '*')) || (sc.Match('/', '/'))) {
117+ break;
118+ case SCE_C_PREPROCESSOR:
119+ if (sc.atLineStart) {
127120 sc.SetState(SCE_C_DEFAULT);
128- }
129- }
130- } else if (sc.state == SCE_C_COMMENT) {
131- if (sc.Match('*', '/')) {
132- sc.Forward();
133- sc.ForwardSetState(SCE_C_DEFAULT);
134- }
135- } else if (sc.state == SCE_C_COMMENTDOC) {
136- if (sc.Match('*', '/')) {
137- sc.Forward();
138- sc.ForwardSetState(SCE_C_DEFAULT);
139- } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
140- // Verify that we have the conditions to mark a comment-doc-keyword
141- if ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) {
142- sc.SetState(SCE_C_COMMENTDOCKEYWORD);
143- }
144- }
145- } else if (sc.state == SCE_C_COMMENTLINE || sc.state == SCE_C_COMMENTLINEDOC) {
146- if (sc.ch == '\r' || sc.ch == '\n') {
147- sc.SetState(SCE_C_DEFAULT);
148- visibleChars = 0;
149- }
150- } else if (sc.state == SCE_C_COMMENTDOCKEYWORD) {
151- if (sc.Match('*', '/')) {
152- sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR);
153- sc.Forward();
154- sc.ForwardSetState(SCE_C_DEFAULT);
155- } else if (!IsADoxygenChar(sc.ch)) {
156- char s[100];
157- if (caseSensitive) {
158- sc.GetCurrent(s, sizeof(s));
121+ } else if (stylingWithinPreprocessor) {
122+ if (IsASpace(sc.ch)) {
123+ sc.SetState(SCE_C_DEFAULT);
124+ }
159125 } else {
160- sc.GetCurrentLowered(s, sizeof(s));
126+ if (sc.Match('/', '*') || sc.Match('/', '/')) {
127+ sc.SetState(SCE_C_DEFAULT);
128+ }
161129 }
162- if (!isspace(sc.ch) || !keywords3.InList(s + 1)) {
163- sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR);
164- }
165- sc.SetState(SCE_C_COMMENTDOC);
166- }
167- } else if (sc.state == SCE_C_STRING) {
168- if (sc.ch == '\\') {
169- if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
130+ break;
131+ case SCE_C_COMMENT:
132+ if (sc.Match('*', '/')) {
170133 sc.Forward();
134+ sc.ForwardSetState(SCE_C_DEFAULT);
171135 }
172- } else if (sc.ch == '\"') {
173- sc.ForwardSetState(SCE_C_DEFAULT);
174- } else if (sc.atLineEnd) {
175- sc.ChangeState(SCE_C_STRINGEOL);
176- sc.ForwardSetState(SCE_C_DEFAULT);
177- visibleChars = 0;
178- }
179- } else if (sc.state == SCE_C_CHARACTER) {
180- if (sc.atLineEnd) {
181- sc.ChangeState(SCE_C_STRINGEOL);
182- sc.ForwardSetState(SCE_C_DEFAULT);
183- visibleChars = 0;
184- } else if (sc.ch == '\\') {
185- if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
136+ break;
137+ case SCE_C_COMMENTDOC:
138+ if (sc.Match('*', '/')) {
186139 sc.Forward();
140+ sc.ForwardSetState(SCE_C_DEFAULT);
141+ } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
142+ // Verify that we have the conditions to mark a comment-doc-keyword
143+ if ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) {
144+ styleBeforeDCKeyword = SCE_C_COMMENTDOC;
145+ sc.SetState(SCE_C_COMMENTDOCKEYWORD);
146+ }
187147 }
188- } else if (sc.ch == '\'') {
189- sc.ForwardSetState(SCE_C_DEFAULT);
190- }
191- } else if (sc.state == SCE_C_REGEX) {
192- if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == '/') {
193- sc.ForwardSetState(SCE_C_DEFAULT);
194- } else if (sc.ch == '\\') {
195- // Gobble up the quoted character
196- if (sc.chNext == '\\' || sc.chNext == '/') {
197- sc.Forward();
148+ break;
149+ case SCE_C_COMMENTLINE:
150+ if (sc.atLineStart) {
151+ sc.SetState(SCE_C_DEFAULT);
198152 }
199- }
200- } else if (sc.state == SCE_C_VERBATIM) {
201- if (sc.ch == '\"') {
202- if (sc.chNext == '\"') {
153+ break;
154+ case SCE_C_COMMENTLINEDOC:
155+ if (sc.atLineStart) {
156+ sc.SetState(SCE_C_DEFAULT);
157+ } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
158+ // Verify that we have the conditions to mark a comment-doc-keyword
159+ if ((IsASpace(sc.chPrev) || sc.chPrev == '/' || sc.chPrev == '!') && (!IsASpace(sc.chNext))) {
160+ styleBeforeDCKeyword = SCE_C_COMMENTLINEDOC;
161+ sc.SetState(SCE_C_COMMENTDOCKEYWORD);
162+ }
163+ }
164+ break;
165+ case SCE_C_COMMENTDOCKEYWORD:
166+ if ((styleBeforeDCKeyword == SCE_C_COMMENTDOC) && sc.Match('*', '/')) {
167+ sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR);
203168 sc.Forward();
204- } else {
205169 sc.ForwardSetState(SCE_C_DEFAULT);
170+ } else if (!IsADoxygenChar(sc.ch)) {
171+ char s[100];
172+ if (caseSensitive) {
173+ sc.GetCurrent(s, sizeof(s));
174+ } else {
175+ sc.GetCurrentLowered(s, sizeof(s));
176+ }
177+ if (!isspace(sc.ch) || !keywords3.InList(s + 1)) {
178+ sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR);
179+ }
180+ sc.SetState(styleBeforeDCKeyword);
206181 }
207- }
208- } else if (sc.state == SCE_C_UUID) {
209- if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ')') {
210- sc.SetState(SCE_C_DEFAULT);
211- }
182+ break;
183+ case SCE_C_STRING:
184+ if (sc.atLineEnd) {
185+ sc.ChangeState(SCE_C_STRINGEOL);
186+ } else if (sc.ch == '\\') {
187+ if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
188+ sc.Forward();
189+ }
190+ } else if (sc.ch == '\"') {
191+ sc.ForwardSetState(SCE_C_DEFAULT);
192+ }
193+ break;
194+ case SCE_C_CHARACTER:
195+ if (sc.atLineEnd) {
196+ sc.ChangeState(SCE_C_STRINGEOL);
197+ } else if (sc.ch == '\\') {
198+ if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
199+ sc.Forward();
200+ }
201+ } else if (sc.ch == '\'') {
202+ sc.ForwardSetState(SCE_C_DEFAULT);
203+ }
204+ break;
205+ case SCE_C_REGEX:
206+ if (sc.atLineStart) {
207+ sc.SetState(SCE_C_DEFAULT);
208+ } else if (sc.ch == '/') {
209+ sc.ForwardSetState(SCE_C_DEFAULT);
210+ } else if (sc.ch == '\\') {
211+ // Gobble up the quoted character
212+ if (sc.chNext == '\\' || sc.chNext == '/') {
213+ sc.Forward();
214+ }
215+ }
216+ break;
217+ case SCE_C_STRINGEOL:
218+ if (sc.atLineStart) {
219+ sc.SetState(SCE_C_DEFAULT);
220+ }
221+ break;
222+ case SCE_C_VERBATIM:
223+ if (sc.ch == '\"') {
224+ if (sc.chNext == '\"') {
225+ sc.Forward();
226+ } else {
227+ sc.ForwardSetState(SCE_C_DEFAULT);
228+ }
229+ }
230+ break;
231+ case SCE_C_UUID:
232+ if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ')') {
233+ sc.SetState(SCE_C_DEFAULT);
234+ }
212235 }
213236
214237 // Determine if a new state should be entered.
@@ -244,7 +267,7 @@
244267 else
245268 sc.SetState(SCE_C_COMMENTLINE);
246269 } else if (sc.ch == '/' && IsOKBeforeRE(chPrevNonWhite)) {
247- sc.SetState(SCE_C_REGEX);
270+ sc.SetState(SCE_C_REGEX); // JavaScript's RegEx
248271 } else if (sc.ch == '\"') {
249272 sc.SetState(SCE_C_STRING);
250273 } else if (sc.ch == '\'') {
@@ -256,7 +279,7 @@
256279 do {
257280 sc.Forward();
258281 } while ((sc.ch == ' ' || sc.ch == '\t') && sc.More());
259- if (sc.ch == '\r' || sc.ch == '\n') {
282+ if (sc.atLineEnd) {
260283 sc.SetState(SCE_C_DEFAULT);
261284 }
262285 } else if (isoperator(static_cast<char>(sc.ch))) {
@@ -264,13 +287,6 @@
264287 }
265288 }
266289
267- if (sc.atLineEnd) {
268- // Reset states to begining of colourise so no surprises
269- // if different sets of lines lexed.
270- chPrevNonWhite = ' ';
271- visibleChars = 0;
272- lastWordWasUUID = false;
273- }
274290 if (!IsASpace(sc.ch)) {
275291 chPrevNonWhite = sc.ch;
276292 visibleChars++;
--- trunk/src/Utils/scintilla/src/LexCsound.cxx (revision 4272)
+++ trunk/src/Utils/scintilla/src/LexCsound.cxx (revision 4273)
@@ -82,7 +82,7 @@
8282 } else if (sc.state == SCE_CSOUND_IDENTIFIER) {
8383 if (!IsAWordChar(sc.ch) ) {
8484 char s[100];
85- sc.GetCurrentLowered(s, sizeof(s));
85+ sc.GetCurrent(s, sizeof(s));
8686
8787 if (opcode.InList(s)) {
8888 sc.ChangeState(SCE_CSOUND_OPCODE);
--- trunk/src/Utils/scintilla/src/LexGen.py (revision 4272)
+++ trunk/src/Utils/scintilla/src/LexGen.py (revision 4273)
@@ -21,6 +21,17 @@
2121 import os
2222 import glob
2323
24+# EOL constants
25+CR = "\r"
26+LF = "\n"
27+CRLF = "\r\n"
28+if sys.platform == "win32":
29+ NATIVE = CRLF
30+else:
31+ # Yes, LF is the native EOL even on Mac OS X. CR is just for
32+ # Mac OS <=9 (a.k.a. "Mac Classic")
33+ NATIVE = LF
34+
2435 # Automatically generated sections contain start and end comments,
2536 # a definition line and the results.
2637 # The results are replaced by regenerating based on the definition line.
@@ -30,11 +41,11 @@
3041 # Backslash is used as an escape within the definition line.
3142 # The part between \( and \) is repeated for each item in the list.
3243 # \* is replaced by each list item. \t, and \n are tab and newline.
33-def CopyWithInsertion(input, commentPrefix, retainDefs, *lists):
44+def CopyWithInsertion(input, commentPrefix, retainDefs, eolType, *lists):
3445 copying = 1
3546 listid = 0
3647 output = []
37- for line in input.split("\n"):
48+ for line in input.splitlines(0):
3849 isStartGenerated = line.startswith(commentPrefix + "++Autogenerated")
3950 if copying and not isStartGenerated:
4051 output.append(line)
@@ -79,14 +90,14 @@
7990 pos = 0
8091 outro = definition[endRepeat+2:]
8192 out += outro
93+ out = out.replace("\n", eolType) # correct EOLs in generated content
8294 output.append(out)
8395 elif line.startswith(commentPrefix + "--Autogenerated"):
8496 copying = 1
8597 if retainDefs:
8698 output.append(line)
87- ret = "\n".join(output)
88- ret = ret.replace(" \n", "\n")
89- return ret
99+ output = [line.rstrip(" \t") for line in output] # trim trailing whitespace
100+ return eolType.join(output) + eolType
90101
91102 def UpdateFile(filename, updated):
92103 """ If the file is different to updated then copy updated
@@ -108,31 +119,38 @@
108119 out.write(updated)
109120 out.close()
110121 print "Changed", filename
122+ #~ else:
123+ #~ print "Unchanged", filename
111124
112-def RegenerateOverLists(inpath, outpath, commentPrefix, crlf, *lists):
125+def Generate(inpath, outpath, commentPrefix, eolType, *lists):
126+ """Generate 'outpath' from 'inpath'.
127+
128+ "eolType" indicates the type of EOLs to use in the generated
129+ file. It should be one of following constants: LF, CRLF,
130+ CR, or NATIVE.
131+ """
132+ #print "generate '%s' -> '%s' (comment prefix: %r, eols: %r)"\
133+ # % (inpath, outpath, commentPrefix, eolType)
113134 try:
114- infile = open(inpath, "rb")
135+ infile = open(inpath, "r")
115136 except IOError:
116137 print "Can not open", inpath
117138 return
118139 original = infile.read()
119140 infile.close()
120- contents = original.replace("\r\n", "\n")
121- updated = CopyWithInsertion(contents, commentPrefix,
122- inpath == outpath, *lists)
123- if crlf:
124- updated = updated.replace("\n", "\r\n")
141+ updated = CopyWithInsertion(original, commentPrefix,
142+ inpath == outpath, eolType, *lists)
125143 UpdateFile(outpath, updated)
126144
127-def Regenerate(filename, commentPrefix, *lists):
128- RegenerateOverLists(filename, filename, commentPrefix, 1, *lists)
145+def Regenerate(filename, commentPrefix, eolType, *lists):
146+ """Regenerate the given file.
129147
130-def RegenerateBinary(filename, commentPrefix, *lists):
131- RegenerateOverLists(filename, filename, commentPrefix, 0, *lists)
148+ "eolType" indicates the type of EOLs to use in the generated
149+ file. It should be one of following constants: LF, CRLF,
150+ CR, or NATIVE.
151+ """
152+ Generate(filename, filename, commentPrefix, eolType, *lists)
132153
133-def Generate(inpath, outpath, commentPrefix, *lists):
134- RegenerateOverLists(inpath, outpath, commentPrefix, 1, *lists)
135-
136154 def FindModules(lexFile):
137155 modules = []
138156 f = open(lexFile)
@@ -143,7 +161,7 @@
143161 return modules
144162
145163 def ciCompare(a,b):
146- return a.lower() < b.lower()
164+ return a.lower() < b.lower()
147165
148166 def RegenerateAll():
149167 root="../../"
@@ -171,15 +189,19 @@
171189 ids = [id for id in [l.split()[1] for l in lines if l.startswith("#define")] if id.startswith("IDM_")]
172190 #print ids
173191
174- Regenerate(root + "scintilla/src/KeyWords.cxx", "//", lexerModules)
175- Regenerate(root + "scintilla/win32/makefile", "#", lexFiles)
176- Regenerate(root + "scintilla/win32/scintilla.mak", "#", lexFiles)
177- Regenerate(root + "scintilla/win32/scintilla_vc6.mak", "#", lexFiles)
178- RegenerateBinary(root + "scintilla/gtk/makefile", "#", lexFiles)
179- Regenerate(root + "scintilla/gtk/scintilla.mak", "#", lexFiles)
180- Regenerate(root + "scite/win32/makefile", "#", lexFiles, propFiles)
181- Regenerate(root + "scite/win32/scite.mak", "#", lexFiles, propFiles)
182- Regenerate(root + "scite/src/SciTEProps.cxx", "//", ids)
183- Generate(root + "scite/boundscheck/vcproj.gen", root + "scite/boundscheck/SciTE.vcproj", "#", lexFiles)
184-
192+ Regenerate(root + "scintilla/src/KeyWords.cxx", "//", NATIVE, lexerModules)
193+ Regenerate(root + "scintilla/win32/makefile", "#", NATIVE, lexFiles)
194+ Regenerate(root + "scintilla/win32/scintilla.mak", "#", NATIVE, lexFiles)
195+ Regenerate(root + "scintilla/win32/scintilla_vc6.mak", "#", NATIVE, lexFiles)
196+ # Use Unix EOLs for gtk Makefiles so they work for Linux users when
197+ # extracted from the Scintilla source ZIP (typically created on
198+ # Windows).
199+ Regenerate(root + "scintilla/gtk/makefile", "#", LF, lexFiles)
200+ Regenerate(root + "scintilla/gtk/scintilla.mak", "#", NATIVE, lexFiles)
201+ Regenerate(root + "scite/win32/makefile", "#", NATIVE, lexFiles, propFiles)
202+ Regenerate(root + "scite/win32/scite.mak", "#", NATIVE, lexFiles, propFiles)
203+ Regenerate(root + "scite/src/SciTEProps.cxx", "//", NATIVE, ids)
204+ Generate(root + "scite/boundscheck/vcproj.gen",
205+ root + "scite/boundscheck/SciTE.vcproj", "#", NATIVE, lexFiles)
206+
185207 RegenerateAll()
--- trunk/src/Utils/scintilla/src/LexHTML.cxx (revision 4272)
+++ trunk/src/Utils/scintilla/src/LexHTML.cxx (revision 4273)
@@ -424,6 +424,8 @@
424424
425425 static int FindPhpStringDelimiter(char *phpStringDelimiter, const int phpStringDelimiterSize, int i, const int lengthDoc, Accessor &styler) {
426426 int j;
427+ while (i < lengthDoc && (styler[i] == ' ' || styler[i] == '\t'))
428+ i++;
427429 phpStringDelimiter[0] = '\n';
428430 for (j = i; j < lengthDoc && styler[j] != '\n' && styler[j] != '\r'; j++) {
429431 if (j - i < phpStringDelimiterSize - 2)
@@ -678,7 +680,7 @@
678680 }
679681
680682 // handle the start of ASP pre-processor = Non-HTML
681- else if (!isCommentASPState(state) && (ch == '<') && (chNext == '%')) {
683+ else if (!isCommentASPState(state) && (ch == '<') && (chNext == '%') && !isPHPStringState(state)) {
682684 styler.ColourTo(i - 1, StateToPrint);
683685 beforePreProc = state;
684686 if (inScriptType == eNonHtmlScript)
--- trunk/src/Utils/scintilla/src/LexLisp.cxx (revision 4272)
+++ trunk/src/Utils/scintilla/src/LexLisp.cxx (revision 4273)
@@ -19,12 +19,16 @@
1919 #include "KeyWords.h"
2020 #include "Scintilla.h"
2121 #include "SciLexer.h"
22+#include "StyleContext.h"
2223
24+#define SCE_LISP_CHARACTER 29
25+#define SCE_LISP_MACRO 30
26+#define SCE_LISP_MACRO_DISPATCH 31
2327
2428 static inline bool isLispoperator(char ch) {
2529 if (isascii(ch) && isalnum(ch))
2630 return false;
27- if (ch == '\'' || ch == '(' || ch == ')' )
31+ if (ch == '\'' || ch == '`' || ch == '(' || ch == ')' )
2832 return true;
2933 return false;
3034 }
@@ -35,7 +39,7 @@
3539 }
3640
3741
38-static void classifyWordLisp(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
42+static void classifyWordLisp(unsigned int start, unsigned int end, WordList &keywords, WordList &keywords_kw, Accessor &styler) {
3943 PLATFORM_ASSERT(end >= start);
4044 char s[100];
4145 unsigned int i;
@@ -51,6 +55,11 @@
5155 else {
5256 if (keywords.InList(s)) {
5357 chAttr = SCE_LISP_KEYWORD;
58+ } else if (keywords_kw.InList(s)) {
59+ chAttr = SCE_LISP_KEYWORD_KW;
60+ } else if ((s[0] == '*' && s[i-1] == '*') ||
61+ (s[0] == '+' && s[i-1] == '+')) {
62+ chAttr = SCE_LISP_SPECIAL;
5463 }
5564 }
5665 styler.ColourTo(end, chAttr);
@@ -62,10 +71,11 @@
6271 Accessor &styler) {
6372
6473 WordList &keywords = *keywordlists[0];
74+ WordList &keywords_kw = *keywordlists[1];
6575
6676 styler.StartAt(startPos);
6777
68- int state = initStyle;
78+ int state = initStyle, radix = -1;
6979 char chNext = styler[startPos];
7080 unsigned int lengthDoc = startPos + length;
7181 styler.StartSegment(startPos);
@@ -82,8 +92,12 @@
8292 }
8393
8494 if (state == SCE_LISP_DEFAULT) {
85- if (isLispwordstart(ch)) {
95+ if (ch == '#') {
8696 styler.ColourTo(i - 1, state);
97+ radix = -1;
98+ state = SCE_LISP_MACRO_DISPATCH;
99+ } else if (isLispwordstart(ch)) {
100+ styler.ColourTo(i - 1, state);
87101 state = SCE_LISP_IDENTIFIER;
88102 }
89103 else if (ch == ';') {
@@ -93,21 +107,92 @@
93107 else if (isLispoperator(ch) || ch=='\'') {
94108 styler.ColourTo(i - 1, state);
95109 styler.ColourTo(i, SCE_LISP_OPERATOR);
110+ if (ch=='\'' && isLispwordstart(chNext)) {
111+ state = SCE_LISP_SYMBOL;
112+ }
96113 }
97114 else if (ch == '\"') {
98115 styler.ColourTo(i - 1, state);
99116 state = SCE_LISP_STRING;
100117 }
101- } else if (state == SCE_LISP_IDENTIFIER) {
118+ } else if (state == SCE_LISP_IDENTIFIER || state == SCE_LISP_SYMBOL) {
102119 if (!isLispwordstart(ch)) {
103- classifyWordLisp(styler.GetStartSegment(), i - 1, keywords, styler);
120+ if (state == SCE_LISP_IDENTIFIER) {
121+ classifyWordLisp(styler.GetStartSegment(), i - 1, keywords, keywords_kw, styler);
122+ } else {
123+ styler.ColourTo(i - 1, state);
124+ }
104125 state = SCE_LISP_DEFAULT;
105126 } /*else*/
106127 if (isLispoperator(ch) || ch=='\'') {
107128 styler.ColourTo(i - 1, state);
108129 styler.ColourTo(i, SCE_LISP_OPERATOR);
130+ if (ch=='\'' && isLispwordstart(chNext)) {
131+ state = SCE_LISP_SYMBOL;
132+ }
109133 }
110-
134+ } else if (state == SCE_LISP_MACRO_DISPATCH) {
135+ if (!isdigit(ch)) {
136+ if (ch != 'r' && ch != 'R' && (i - styler.GetStartSegment()) > 1) {
137+ state = SCE_LISP_DEFAULT;
138+ } else {
139+ switch (ch) {
140+ case '|': state = SCE_LISP_MULTI_COMMENT; break;
141+ case 'o':
142+ case 'O': radix = 8; state = SCE_LISP_MACRO; break;
143+ case 'x':
144+ case 'X': radix = 16; state = SCE_LISP_MACRO; break;
145+ case 'b':
146+ case 'B': radix = 2; state = SCE_LISP_MACRO; break;
147+ case '\\': state = SCE_LISP_CHARACTER; break;
148+ case ':':
149+ case '-':
150+ case '+': state = SCE_LISP_MACRO; break;
151+ case '\'': if (isLispwordstart(chNext)) {
152+ state = SCE_LISP_SPECIAL;
153+ } else {
154+ styler.ColourTo(i - 1, SCE_LISP_DEFAULT);
155+ styler.ColourTo(i, SCE_LISP_OPERATOR);
156+ state = SCE_LISP_DEFAULT;
157+ }
158+ break;
159+ default: if (isLispoperator(ch)) {
160+ styler.ColourTo(i - 1, SCE_LISP_DEFAULT);
161+ styler.ColourTo(i, SCE_LISP_OPERATOR);
162+ }
163+ state = SCE_LISP_DEFAULT;
164+ break;
165+ }
166+ }
167+ }
168+ } else if (state == SCE_LISP_MACRO) {
169+ if (isLispwordstart(ch) && (radix == -1 || IsADigit(ch, radix))) {
170+ state = SCE_LISP_SPECIAL;
171+ } else {
172+ state = SCE_LISP_DEFAULT;
173+ }
174+ } else if (state == SCE_LISP_CHARACTER) {
175+ if (isLispoperator(ch)) {
176+ styler.ColourTo(i, SCE_LISP_SPECIAL);
177+ state = SCE_LISP_DEFAULT;
178+ } else if (isLispwordstart(ch)) {
179+ styler.ColourTo(i, SCE_LISP_SPECIAL);
180+ state = SCE_LISP_SPECIAL;
181+ } else {
182+ state = SCE_LISP_DEFAULT;
183+ }
184+ } else if (state == SCE_LISP_SPECIAL) {
185+ if (!isLispwordstart(ch) || (radix != -1 && !IsADigit(ch, radix))) {
186+ styler.ColourTo(i - 1, state);
187+ state = SCE_LISP_DEFAULT;
188+ }
189+ if (isLispoperator(ch) || ch=='\'') {
190+ styler.ColourTo(i - 1, state);
191+ styler.ColourTo(i, SCE_LISP_OPERATOR);
192+ if (ch=='\'' && isLispwordstart(chNext)) {
193+ state = SCE_LISP_SYMBOL;
194+ }
195+ }
111196 } else {
112197 if (state == SCE_LISP_COMMENT) {
113198 if (atEOL) {
@@ -114,6 +199,13 @@
114199 styler.ColourTo(i - 1, state);
115200 state = SCE_LISP_DEFAULT;
116201 }
202+ } else if (state == SCE_LISP_MULTI_COMMENT) {
203+ if (ch == '|' && chNext == '#') {
204+ i++;
205+ chNext = styler.SafeGetCharAt(i + 1);
206+ styler.ColourTo(i, state);
207+ state = SCE_LISP_DEFAULT;
208+ }
117209 } else if (state == SCE_LISP_STRING) {
118210 if (ch == '\\') {
119211 if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
@@ -175,6 +267,7 @@
175267 }
176268
177269 static const char * const lispWordListDesc[] = {
270+ "Functions and special operators",
178271 "Keywords",
179272 0
180273 };
--- trunk/src/Utils/scintilla/src/LexLua.cxx (revision 4272)
+++ trunk/src/Utils/scintilla/src/LexLua.cxx (revision 4273)
@@ -22,15 +22,18 @@
2222 #include "Scintilla.h"
2323 #include "SciLexer.h"
2424
25-static inline bool IsAWordChar(const int ch) {
26- return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.');
25+// Extended to accept accented characters
26+static inline bool IsAWordChar(int ch) {
27+ return ch >= 0x80 ||
28+ (isalnum(ch) || ch == '.' || ch == '_');
2729 }
2830
29-static inline bool IsAWordStart(const int ch) {
30- return (ch < 0x80) && (isalnum(ch) || ch == '_');
31+static inline bool IsAWordStart(int ch) {
32+ return ch >= 0x80 ||
33+ (isalpha(ch) || ch == '_');
3134 }
3235
33-static inline bool IsANumberChar(const int ch) {
36+static inline bool IsANumberChar(int ch) {
3437 // Not exactly following number definition (several dots are seen as OK, etc.)
3538 // but probably enough in most cases.
3639 return (ch < 0x80) &&
@@ -83,7 +86,7 @@
8386 }
8487
8588 // Do not leak onto next line
86- if (initStyle == SCE_LUA_STRINGEOL || initStyle == SCE_LUA_COMMENTLINE) {
89+ if (initStyle == SCE_LUA_STRINGEOL || initStyle == SCE_LUA_COMMENTLINE || initStyle == SCE_LUA_PREPROCESSOR) {
8790 initStyle = SCE_LUA_DEFAULT;
8891 }
8992
@@ -161,11 +164,11 @@
161164 }
162165 sc.SetState(SCE_LUA_DEFAULT);
163166 }
164- } else if (sc.state == SCE_LUA_COMMENTLINE ) {
167+ } else if (sc.state == SCE_LUA_COMMENTLINE) {
165168 if (sc.atLineEnd) {
166169 sc.ForwardSetState(SCE_LUA_DEFAULT);
167170 }
168- } else if (sc.state == SCE_LUA_PREPROCESSOR ) {
171+ } else if (sc.state == SCE_LUA_PREPROCESSOR) {
169172 if (sc.atLineEnd) {
170173 sc.ForwardSetState(SCE_LUA_DEFAULT);
171174 }
@@ -266,7 +269,7 @@
266269 styleNext = styler.StyleAt(i + 1);
267270 bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
268271 if (style == SCE_LUA_WORD) {
269- if (ch == 'i' || ch == 'd' || ch == 'f' || ch == 'e') {
272+ if (ch == 'i' || ch == 'd' || ch == 'f' || ch == 'e' || ch == 'r' || ch == 'u') {
270273 for (unsigned int j = 0; j < 8; j++) {
271274 if (!iswordchar(styler[i + j])) {
272275 break;
@@ -275,10 +278,10 @@
275278 s[j + 1] = '\0';
276279 }
277280
278- if ((strcmp(s, "if") == 0) || (strcmp(s, "do") == 0) || (strcmp(s, "function") == 0)) {
281+ if ((strcmp(s, "if") == 0) || (strcmp(s, "do") == 0) || (strcmp(s, "function") == 0) || (strcmp(s, "repeat") == 0)) {
279282 levelCurrent++;
280283 }
281- if ((strcmp(s, "end") == 0) || (strcmp(s, "elseif") == 0)) {
284+ if ((strcmp(s, "end") == 0) || (strcmp(s, "elseif") == 0) || (strcmp(s, "until") == 0)) {
282285 levelCurrent--;
283286 }
284287 }
@@ -288,6 +291,12 @@
288291 } else if (ch == '}' || ch == ')') {
289292 levelCurrent--;
290293 }
294+ } else if (style == SCE_LUA_LITERALSTRING || style == SCE_LUA_COMMENT) {
295+ if (ch == '[') {
296+ levelCurrent++;
297+ } else if (ch == ']') {
298+ levelCurrent--;
299+ }
291300 }
292301
293302 if (atEOL) {
@@ -320,8 +329,10 @@
320329 "Basic functions",
321330 "String, (table) & math functions",
322331 "(coroutines), I/O & system facilities",
323- "XXX",
324- "XXX",
332+ "user1",
333+ "user2",
334+ "user3",
335+ "user4",
325336 0
326337 };
327338
--- trunk/src/Utils/scintilla/src/LexMSSQL.cxx (revision 4272)
+++ trunk/src/Utils/scintilla/src/LexMSSQL.cxx (revision 4273)
@@ -2,7 +2,7 @@
22 /** @file LexMSSQL.cxx
33 ** Lexer for MSSQL.
44 **/
5-// Copyright 1998-2002 by Filip Yaghob <fy@eg.cz>
5+// By Filip Yaghob <fyaghob@gmail.com>
66
77
88 #include <stdlib.h>
@@ -27,24 +27,6 @@
2727 #define KW_MSSQL_STORED_PROCEDURES 5
2828 #define KW_MSSQL_OPERATORS 6
2929
30-//~ val SCE_MSSQL_DEFAULT=0
31-//~ val SCE_MSSQL_COMMENT=1
32-//~ val SCE_MSSQL_LINE_COMMENT=2
33-//~ val SCE_MSSQL_NUMBER=3
34-//~ val SCE_MSSQL_STRING=4
35-//~ val SCE_MSSQL_OPERATOR=5
36-//~ val SCE_MSSQL_IDENTIFIER=6
37-//~ val SCE_MSSQL_VARIABLE=7
38-//~ val SCE_MSSQL_COLUMN_NAME=8
39-//~ val SCE_MSSQL_STATEMENT=9
40-//~ val SCE_MSSQL_DATATYPE=10
41-//~ val SCE_MSSQL_SYSTABLE=11
42-//~ val SCE_MSSQL_GLOBAL_VARIABLE=12
43-//~ val SCE_MSSQL_FUNCTION=13
44-//~ val SCE_MSSQL_STORED_PROCEDURE=14
45-//~ val SCE_MSSQL_DEFAULT_PREF_DATATYPE 15
46-//~ val SCE_MSSQL_COLUMN_NAME_2 16
47-
4830 static bool isMSSQLOperator(char ch) {
4931 if (isascii(ch) && isalnum(ch))
5032 return false;
@@ -133,22 +115,7 @@
133115 bool fold = styler.GetPropertyInt("fold") != 0;
134116 int lineCurrent = styler.GetLine(startPos);
135117 int spaceFlags = 0;
136-/*
137- WordList &kwStatements = *keywordlists[KW_MSSQL_STATEMENTS];
138- WordList &kwDataTypes = *keywordlists[KW_MSSQL_DATA_TYPES];
139- WordList &kwSystemTables = *keywordlists[KW_MSSQL_SYSTEM_TABLES];
140- WordList &kwGlobalVariables = *keywordlists[KW_MSSQL_GLOBAL_VARIABLES];
141- WordList &kwFunctions = *keywordlists[KW_MSSQL_FUNCTIONS];
142118
143- char s[100];
144- int iixx = 0;
145- s[0] = 's'; s[1] = 'e'; s[2] = 'l'; s[3] = 'e'; s[4] = 'c'; s[5] = 't'; s[6] = 0;
146- if (kwStatements.InList(s))
147- iixx = 1;
148- s[0] = 's'; s[1] = 'e'; s[2] = 'r'; s[3] = 'v'; s[4] = 'e'; s[5] = 'r'; s[6] = 'n'; s[7] = 'a'; s[8] = 'm'; s[9] = 'e'; s[10] = 0;
149- if (kwGlobalVariables.InList(s))
150- iixx += 2;
151-*/
152119 int state = initStyle;
153120 int prevState = initStyle;
154121 char chPrev = ' ';
@@ -315,6 +282,69 @@
315282 styler.ColourTo(lengthDoc - 1, state);
316283 }
317284
285+static void FoldMSSQLDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
286+ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
287+ bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
288+ unsigned int endPos = startPos + length;
289+ int visibleChars = 0;
290+ int lineCurrent = styler.GetLine(startPos);
291+ int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
292+ int levelCurrent = levelPrev;
293+ char chNext = styler[startPos];
294+ bool inComment = (styler.StyleAt(startPos-1) == SCE_MSSQL_COMMENT);
295+ char s[10];
296+ for (unsigned int i = startPos; i < endPos; i++) {
297+ char ch = chNext;
298+ chNext = styler.SafeGetCharAt(i + 1);
299+ int style = styler.StyleAt(i);
300+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
301+ // Comment folding
302+ if (foldComment) {
303+ if (!inComment && (style == SCE_MSSQL_COMMENT))
304+ levelCurrent++;
305+ else if (inComment && (style != SCE_MSSQL_COMMENT))
306+ levelCurrent--;
307+ inComment = (style == SCE_MSSQL_COMMENT);
308+ }
309+ if (style == SCE_MSSQL_STATEMENT) {
310+ // Folding between begin and end
311+ if (ch == 'b' || ch == 'e') {
312+ for (unsigned int j = 0; j < 5; j++) {
313+ if (!iswordchar(styler[i + j])) {
314+ break;
315+ }
316+ s[j] = styler[i + j];
317+ s[j + 1] = '\0';
318+ }
319+ if (strcmp(s, "begin") == 0) {
320+ levelCurrent++;
321+ }
322+ if (strcmp(s, "end") == 0) {
323+ levelCurrent--;
324+ }
325+ }
326+ }
327+ if (atEOL) {
328+ int lev = levelPrev;
329+ if (visibleChars == 0 && foldCompact)
330+ lev |= SC_FOLDLEVELWHITEFLAG;
331+ if ((levelCurrent > levelPrev) && (visibleChars > 0))
332+ lev |= SC_FOLDLEVELHEADERFLAG;
333+ if (lev != styler.LevelAt(lineCurrent)) {
334+ styler.SetLevel(lineCurrent, lev);
335+ }
336+ lineCurrent++;
337+ levelPrev = levelCurrent;
338+ visibleChars = 0;
339+ }
340+ if (!isspacechar(ch))
341+ visibleChars++;
342+ }
343+ // Fill in the real level of the next line, keeping the current flags as they will be filled in later
344+ int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
345+ styler.SetLevel(lineCurrent, levelPrev | flagsNext);
346+}
347+
318348 static const char * const sqlWordListDesc[] = {
319349 "Statements",
320350 "Data Types",
@@ -326,4 +356,4 @@
326356 0,
327357 };
328358
329-LexerModule lmMSSQL(SCLEX_MSSQL, ColouriseMSSQLDoc, "mssql", 0, sqlWordListDesc);
359+LexerModule lmMSSQL(SCLEX_MSSQL, ColouriseMSSQLDoc, "mssql", FoldMSSQLDoc, sqlWordListDesc);
--- trunk/src/Utils/scintilla/src/LexOthers.cxx (revision 4272)
+++ trunk/src/Utils/scintilla/src/LexOthers.cxx (revision 4273)
@@ -33,6 +33,18 @@
3333 ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n'));
3434 }
3535
36+// Tests for BATCH Operators
37+static bool IsBOperator(char ch) {
38+ return (ch == '=') || (ch == '+') || (ch == '>') || (ch == '<') ||
39+ (ch == '|') || (ch == '?') || (ch == '*');
40+}
41+
42+// Tests for BATCH Separators
43+static bool IsBSeparator(char ch) {
44+ return (ch == ':') || (ch == '\\') || (ch == '.') || (ch == ';') ||
45+ (ch == '\"') || (ch == '\'') || (ch == '/') || (ch == ')');
46+}
47+
3648 static void ColouriseBatchLine(
3749 char *lineBuffer,
3850 unsigned int lengthLine,
@@ -41,95 +53,391 @@
4153 WordList &keywords,
4254 Accessor &styler) {
4355
44- unsigned int i = 0;
45- unsigned int state = SCE_BAT_DEFAULT;
56+ unsigned int offset = 0; // Line Buffer Offset
57+ unsigned int enVarEnd; // Environment Variable End point
58+ unsigned int cmdLoc; // External Command / Program Location
59+ char wordBuffer[81]; // Word Buffer - large to catch long paths
60+ unsigned int wbl; // Word Buffer Length
61+ unsigned int wbo; // Word Buffer Offset - also Special Keyword Buffer Length
62+ bool forFound = false; // No Local Variable without FOR statement
63+ // CHOICE, ECHO, GOTO, PROMPT and SET have Default Text that may contain Regular Keywords
64+ // Toggling Regular Keyword Checking off improves readability
65+ // Other Regular Keywords and External Commands / Programs might also benefit from toggling
66+ // Need a more robust algorithm to properly toggle Regular Keyword Checking
67+ bool continueProcessing = true; // Used to toggle Regular Keyword Checking
68+ // Special Keywords are those that allow certain characters without whitespace after the command
69+ // Examples are: cd. cd\ md. rd. dir| dir> echo: echo. path=
70+ // Special Keyword Buffer used to determine if the first n characters is a Keyword
71+ char sKeywordBuffer[10]; // Special Keyword Buffer
72+ bool sKeywordFound; // Exit Special Keyword for-loop if found
4673
47- while ((i < lengthLine) && isspacechar(lineBuffer[i])) { // Skip initial spaces
48- i++;
74+ // Skip initial spaces
75+ while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) {
76+ offset++;
4977 }
50- if (lineBuffer[i] == '@') { // Hide command (ECHO OFF)
51- styler.ColourTo(startLine + i, SCE_BAT_HIDE);
52- i++;
53- while ((i < lengthLine) && isspacechar(lineBuffer[i])) { // Skip next spaces
54- i++;
55- }
56- }
57- if (lineBuffer[i] == ':') {
58- // Label
59- if (lineBuffer[i + 1] == ':') {
60- // :: is a fake label, similar to REM, see http://content.techweb.com/winmag/columns/explorer/2000/21.htm
78+ // Colorize Default Text
79+ styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
80+ // Set External Command / Program Location
81+ cmdLoc = offset;
82+
83+ // Check for Fake Label (Comment) or Real Label - return if found
84+ if (lineBuffer[offset] == ':') {
85+ if (lineBuffer[offset + 1] == ':') {
86+ // Colorize Fake Label (Comment) - :: is similar to REM, see http://content.techweb.com/winmag/columns/explorer/2000/21.htm
6187 styler.ColourTo(endPos, SCE_BAT_COMMENT);
62- } else { // Real label
88+ } else {
89+ // Colorize Real Label
6390 styler.ColourTo(endPos, SCE_BAT_LABEL);
6491 }
65- } else {
66- // Check if initial word is a keyword
67- char wordBuffer[21];
68- unsigned int wbl = 0, offset = i;
69- // Copy word in buffer
70- for (; offset < lengthLine && wbl < 20 &&
92+ return;
93+ // Check for Drive Change (Drive Change is internal command) - return if found
94+ } else if ((isalpha(lineBuffer[offset])) &&
95+ (lineBuffer[offset + 1] == ':') &&
96+ ((isspacechar(lineBuffer[offset + 2])) ||
97+ (((lineBuffer[offset + 2] == '\\')) &&
98+ (isspacechar(lineBuffer[offset + 3]))))) {
99+ // Colorize Regular Keyword
100+ styler.ColourTo(endPos, SCE_BAT_WORD);
101+ return;
102+ }
103+
104+ // Check for Hide Command (@ECHO OFF/ON)
105+ if (lineBuffer[offset] == '@') {
106+ styler.ColourTo(startLine + offset, SCE_BAT_HIDE);
107+ offset++;
108+ // Check for Argument (%n) or Environment Variable (%x...%)
109+ } else if (lineBuffer[offset] == '%') {
110+ enVarEnd = offset + 1;
111+ // Search end of word for second % (can be a long path)
112+ while ((enVarEnd < lengthLine) &&
113+ (!isspacechar(lineBuffer[enVarEnd])) &&
114+ (lineBuffer[enVarEnd] != '%') &&
115+ (!IsBOperator(lineBuffer[enVarEnd])) &&
116+ (!IsBSeparator(lineBuffer[enVarEnd]))) {
117+ enVarEnd++;
118+ }
119+ // Check for Argument (%n)
120+ if ((Is0To9(lineBuffer[offset + 1])) &&
121+ (lineBuffer[enVarEnd] != '%')) {
122+ // Colorize Argument
123+ styler.ColourTo(startLine + offset + 1, SCE_BAT_IDENTIFIER);
124+ offset += 2;
125+ // Check for External Command / Program
126+ if (!isspacechar(lineBuffer[offset])) {
127+ cmdLoc = offset;
128+ }
129+ // Check for Environment Variable (%x...%)
130+ } else if ((lineBuffer[offset + 1] != '%') &&
131+ (lineBuffer[enVarEnd] == '%')) {
132+ offset = enVarEnd;
133+ // Colorize Environment Variable
134+ styler.ColourTo(startLine + offset, SCE_BAT_IDENTIFIER);
135+ offset++;
136+ // Check for External Command / Program
137+ if (!isspacechar(lineBuffer[offset])) {
138+ cmdLoc = offset;
139+ }
140+ }
141+ }
142+ // Skip next spaces
143+ while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) {
144+ offset++;
145+ }
146+
147+ // Read remainder of line word-at-a-time or remainder-of-word-at-a-time
148+ while (offset < lengthLine) {
149+ if (offset > startLine) {
150+ // Colorize Default Text
151+ styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
152+ }
153+ // Copy word from Line Buffer into Word Buffer
154+ wbl = 0;
155+ for (; offset < lengthLine && wbl < 80 &&
71156 !isspacechar(lineBuffer[offset]); wbl++, offset++) {
72157 wordBuffer[wbl] = static_cast<char>(tolower(lineBuffer[offset]));
73158 }
74159 wordBuffer[wbl] = '\0';
75- // Check if it is a comment
160+ wbo = 0;
161+
162+ // Check for Comment - return if found
76163 if (CompareCaseInsensitive(wordBuffer, "rem") == 0) {
77164 styler.ColourTo(endPos, SCE_BAT_COMMENT);
78165 return;
79166 }
80- // Check if it is in the list
81- if (keywords.InList(wordBuffer)) {
82- styler.ColourTo(startLine + offset - 1, SCE_BAT_WORD); // Regular keyword
83- } else {
84- // Search end of word (can be a long path)
85- while (offset < lengthLine &&
86- !isspacechar(lineBuffer[offset])) {
87- offset++;
167+ // Check for Separator
168+ if (IsBSeparator(wordBuffer[0])) {
169+ // Check for External Command / Program
170+ if ((cmdLoc == offset - wbl) &&
171+ ((wordBuffer[0] == ':') ||
172+ (wordBuffer[0] == '\\') ||
173+ (wordBuffer[0] == '.'))) {
174+ // Reset Offset to re-process remainder of word
175+ offset -= (wbl - 1);
176+ // Colorize External Command / Program
177+ styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
178+ // Reset External Command / Program Location
179+ cmdLoc = offset;
180+ } else {
181+ // Reset Offset to re-process remainder of word
182+ offset -= (wbl - 1);
183+ // Colorize Default Text
184+ styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
88185 }
89- styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND); // External command / program
186+ // Check for Regular Keyword in list
187+ } else if ((keywords.InList(wordBuffer)) &&
188+ (continueProcessing)) {
189+ // Local Variables do not exist if no FOR statement
190+ if (CompareCaseInsensitive(wordBuffer, "for") == 0) {
191+ forFound = true;
192+ }
193+ // ECHO, GOTO, PROMPT and SET require no further Regular Keyword Checking
194+ if ((CompareCaseInsensitive(wordBuffer, "echo") == 0) ||
195+ (CompareCaseInsensitive(wordBuffer, "goto") == 0) ||
196+ (CompareCaseInsensitive(wordBuffer, "prompt") == 0) ||
197+ (CompareCaseInsensitive(wordBuffer, "set") == 0)) {
198+ continueProcessing = false;
199+ }
200+ // Identify External Command / Program Location for ERRORLEVEL, and EXIST
201+ if ((CompareCaseInsensitive(wordBuffer, "errorlevel") == 0) ||
202+ (CompareCaseInsensitive(wordBuffer, "exist") == 0)) {
203+ // Reset External Command / Program Location
204+ cmdLoc = offset;
205+ // Skip next spaces
206+ while ((cmdLoc < lengthLine) &&
207+ (isspacechar(lineBuffer[cmdLoc]))) {
208+ cmdLoc++;
209+ }
210+ // Skip comparison
211+ while ((cmdLoc < lengthLine) &&
212+ (!isspacechar(lineBuffer[cmdLoc]))) {
213+ cmdLoc++;
214+ }
215+ // Skip next spaces
216+ while ((cmdLoc < lengthLine) &&
217+ (isspacechar(lineBuffer[cmdLoc]))) {
218+ cmdLoc++;
219+ }
220+ // Identify External Command / Program Location for CALL, DO, LOADHIGH and LH
221+ } else if ((CompareCaseInsensitive(wordBuffer, "call") == 0) ||
222+ (CompareCaseInsensitive(wordBuffer, "do") == 0) ||
223+ (CompareCaseInsensitive(wordBuffer, "loadhigh") == 0) ||
224+ (CompareCaseInsensitive(wordBuffer, "lh") == 0)) {
225+ // Reset External Command / Program Location
226+ cmdLoc = offset;
227+ // Skip next spaces
228+ while ((cmdLoc < lengthLine) &&
229+ (isspacechar(lineBuffer[cmdLoc]))) {
230+ cmdLoc++;
231+ }
232+ }
233+ // Colorize Regular keyword
234+ styler.ColourTo(startLine + offset - 1, SCE_BAT_WORD);
235+ // No need to Reset Offset
236+ // Check for Special Keyword in list, External Command / Program, or Default Text
237+ } else if ((wordBuffer[0] != '%') &&
238+ (!IsBOperator(wordBuffer[0])) &&
239+ (continueProcessing)) {
240+ // Check for Special Keyword
241+ // Affected Commands are in Length range 2-6
242+ // Good that ERRORLEVEL, EXIST, CALL, DO, LOADHIGH, and LH are unaffected
243+ sKeywordFound = false;
244+ for (unsigned int keywordLength = 2; keywordLength < wbl && keywordLength < 7 && !sKeywordFound; keywordLength++) {
245+ wbo = 0;
246+ // Copy Keyword Length from Word Buffer into Special Keyword Buffer
247+ for (; wbo < keywordLength; wbo++) {
248+ sKeywordBuffer[wbo] = static_cast<char>(wordBuffer[wbo]);
249+ }
250+ sKeywordBuffer[wbo] = '\0';
251+ // Check for Special Keyword in list
252+ if ((keywords.InList(sKeywordBuffer)) &&
253+ ((IsBOperator(wordBuffer[wbo])) ||
254+ (IsBSeparator(wordBuffer[wbo])))) {
255+ sKeywordFound = true;
256+ // ECHO requires no further Regular Keyword Checking
257+ if (CompareCaseInsensitive(sKeywordBuffer, "echo") == 0) {
258+ continueProcessing = false;
259+ }
260+ // Colorize Special Keyword as Regular Keyword
261+ styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_WORD);
262+ // Reset Offset to re-process remainder of word
263+ offset -= (wbl - wbo);
264+ }
90265 }
91- // Remainder of the line: colourise the variables.
92-
93- while (offset < lengthLine) {
94- if (state == SCE_BAT_DEFAULT && lineBuffer[offset] == '%') {
95- styler.ColourTo(startLine + offset - 1, state);
96- if (Is0To9(lineBuffer[offset + 1])) {
97- styler.ColourTo(startLine + offset + 1, SCE_BAT_IDENTIFIER);
98- offset += 2;
99- } else if (lineBuffer[offset + 1] == '%' &&
100- !isspacechar(lineBuffer[offset + 2])) {
101- // Should be safe, as there is CRLF at the end of the line...
102- styler.ColourTo(startLine + offset + 2, SCE_BAT_IDENTIFIER);
103- offset += 3;
266+ // Check for External Command / Program or Default Text
267+ if (!sKeywordFound) {
268+ wbo = 0;
269+ // Check for External Command / Program
270+ if (cmdLoc == offset - wbl) {
271+ // Read up to %, Operator or Separator
272+ while ((wbo < wbl) &&
273+ (wordBuffer[wbo] != '%') &&
274+ (!IsBOperator(wordBuffer[wbo])) &&
275+ (!IsBSeparator(wordBuffer[wbo]))) {
276+ wbo++;
277+ }
278+ // Reset External Command / Program Location
279+ cmdLoc = offset - (wbl - wbo);
280+ // Reset Offset to re-process remainder of word
281+ offset -= (wbl - wbo);
282+ // CHOICE requires no further Regular Keyword Checking
283+ if (CompareCaseInsensitive(wordBuffer, "choice") == 0) {
284+ continueProcessing = false;
285+ }
286+ // Check for START (and its switches) - What follows is External Command \ Program
287+ if (CompareCaseInsensitive(wordBuffer, "start") == 0) {
288+ // Reset External Command / Program Location
289+ cmdLoc = offset;
290+ // Skip next spaces
291+ while ((cmdLoc < lengthLine) &&
292+ (isspacechar(lineBuffer[cmdLoc]))) {
293+ cmdLoc++;
294+ }
295+ // Reset External Command / Program Location if command switch detected
296+ if (lineBuffer[cmdLoc] == '/') {
297+ // Skip command switch
298+ while ((cmdLoc < lengthLine) &&
299+ (!isspacechar(lineBuffer[cmdLoc]))) {
300+ cmdLoc++;
301+ }
302+ // Skip next spaces
303+ while ((cmdLoc < lengthLine) &&
304+ (isspacechar(lineBuffer[cmdLoc]))) {
305+ cmdLoc++;
306+ }
307+ }
308+ }
309+ // Colorize External command / program
310+ styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
311+ // No need to Reset Offset
312+ // Check for Default Text
104313 } else {
105- state = SCE_BAT_IDENTIFIER;
314+ // Read up to %, Operator or Separator
315+ while ((wbo < wbl) &&
316+ (wordBuffer[wbo] != '%') &&
317+ (!IsBOperator(wordBuffer[wbo])) &&
318+ (!IsBSeparator(wordBuffer[wbo]))) {
319+ wbo++;
320+ }
321+ // Colorize Default Text
322+ styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_DEFAULT);
323+ // Reset Offset to re-process remainder of word
324+ offset -= (wbl - wbo);
106325 }
107- } else if (state == SCE_BAT_IDENTIFIER && lineBuffer[offset] == '%') {
108- styler.ColourTo(startLine + offset, state);
109- state = SCE_BAT_DEFAULT;
110- } else if (state == SCE_BAT_DEFAULT &&
111- (lineBuffer[offset] == '*' ||
112- lineBuffer[offset] == '?' ||
113- lineBuffer[offset] == '=' ||
114- lineBuffer[offset] == '<' ||
115- lineBuffer[offset] == '>' ||
116- lineBuffer[offset] == '|')) {
117- styler.ColourTo(startLine + offset - 1, state);
118- styler.ColourTo(startLine + offset, SCE_BAT_OPERATOR);
119326 }
327+ // Check for Argument (%n), Environment Variable (%x...%) or Local Variable (%%a)
328+ } else if (wordBuffer[0] == '%') {
329+ // Colorize Default Text
330+ styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT);
331+ wbo++;
332+ // Search to end of word for second % (can be a long path)
333+ while ((wbo < wbl) &&
334+ (wordBuffer[wbo] != '%') &&
335+ (!IsBOperator(wordBuffer[wbo])) &&
336+ (!IsBSeparator(wordBuffer[wbo]))) {
337+ wbo++;
338+ }
339+ // Check for Argument (%n)
340+ if ((Is0To9(wordBuffer[1])) &&
341+ (wordBuffer[wbo] != '%')) {
342+ // Check for External Command / Program
343+ if (cmdLoc == offset - wbl) {
344+ cmdLoc = offset - (wbl - 2);
345+ }
346+ // Colorize Argument
347+ styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_IDENTIFIER);
348+ // Reset Offset to re-process remainder of word
349+ offset -= (wbl - 2);
350+ // Check for Environment Variable (%x...%)
351+ } else if ((wordBuffer[1] != '%') &&
352+ (wordBuffer[wbo] == '%')) {
353+ wbo++;
354+ // Check for External Command / Program
355+ if (cmdLoc == offset - wbl) {
356+ cmdLoc = offset - (wbl - wbo);
357+ }
358+ // Colorize Environment Variable
359+ styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER);
360+ // Reset Offset to re-process remainder of word
361+ offset -= (wbl - wbo);
362+ // Check for Local Variable (%%a)
363+ } else if ((forFound) &&
364+ (wordBuffer[1] == '%') &&
365+ (wordBuffer[2] != '%') &&
366+ (!IsBOperator(wordBuffer[2])) &&
367+ (!IsBSeparator(wordBuffer[2]))) {
368+ // Check for External Command / Program
369+ if (cmdLoc == offset - wbl) {
370+ cmdLoc = offset - (wbl - 3);
371+ }
372+ // Colorize Local Variable
373+ styler.ColourTo(startLine + offset - 1 - (wbl - 3), SCE_BAT_IDENTIFIER);
374+ // Reset Offset to re-process remainder of word
375+ offset -= (wbl - 3);
376+ }
377+ // Check for Operator
378+ } else if (IsBOperator(wordBuffer[0])) {
379+ // Colorize Default Text
380+ styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT);
381+ // Check for Comparison Operator
382+ if ((wordBuffer[0] == '=') && (wordBuffer[1] == '=')) {
383+ // Identify External Command / Program Location for IF
384+ cmdLoc = offset;
385+ // Skip next spaces
386+ while ((cmdLoc < lengthLine) &&
387+ (isspacechar(lineBuffer[cmdLoc]))) {
388+ cmdLoc++;
389+ }
390+ // Colorize Comparison Operator
391+ styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_OPERATOR);
392+ // Reset Offset to re-process remainder of word
393+ offset -= (wbl - 2);
394+ // Check for Pipe Operator
395+ } else if (wordBuffer[0] == '|') {
396+ // Reset External Command / Program Location
397+ cmdLoc = offset - wbl + 1;
398+ // Skip next spaces
399+ while ((cmdLoc < lengthLine) &&
400+ (isspacechar(lineBuffer[cmdLoc]))) {
401+ cmdLoc++;
402+ }
403+ // Colorize Pipe Operator
404+ styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_BAT_OPERATOR);
405+ // Reset Offset to re-process remainder of word
406+ offset -= (wbl - 1);
407+ // Check for Other Operator
408+ } else {
409+ // Check for > Operator
410+ if (wordBuffer[0] == '>') {
411+ // Turn Keyword and External Command / Program checking back on
412+ continueProcessing = true;
413+ }
414+ // Colorize Other Operator
415+ styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_BAT_OPERATOR);
416+ // Reset Offset to re-process remainder of word
417+ offset -= (wbl - 1);
418+ }
419+ // Check for Default Text
420+ } else {
421+ // Read up to %, Operator or Separator
422+ while ((wbo < wbl) &&
423+ (wordBuffer[wbo] != '%') &&
424+ (!IsBOperator(wordBuffer[wbo])) &&
425+ (!IsBSeparator(wordBuffer[wbo]))) {
426+ wbo++;
427+ }
428+ // Colorize Default Text
429+ styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_DEFAULT);
430+ // Reset Offset to re-process remainder of word
431+ offset -= (wbl - wbo);
432+ }
433+ // Skip next spaces - nothing happens if Offset was Reset
434+ while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) {
120435 offset++;
121436 }
122- // if (endPos > startLine + offset - 1) {
123- styler.ColourTo(endPos, SCE_BAT_DEFAULT); // Remainder of line, currently not lexed
124- // }
125437 }
126-
438+ // Colorize Default Text for remainder of line - currently not lexed
439+ styler.ColourTo(endPos, SCE_BAT_DEFAULT);
127440 }
128-// ToDo: (not necessarily at beginning of line) GOTO, [IF] NOT, ERRORLEVEL
129-// IF [NO] (test) (command) -- test is EXIST (filename) | (string1)==(string2) | ERRORLEVEL (number)
130-// FOR %%(variable) IN (set) DO (command) -- variable is [a-zA-Z] -- eg for %%X in (*.txt) do type %%X
131-// ToDo: %n (parameters), %EnvironmentVariable% colourising
132-// ToDo: Colourise = > >> < | "
133441
134442 static void ColouriseBatchDoc(
135443 unsigned int startPos,
@@ -489,11 +797,17 @@
489797 } else if (lineBuffer[0] == '!') {
490798 return SCE_ERR_DIFF_CHANGED;
491799 } else if (lineBuffer[0] == '+') {
492- return SCE_ERR_DIFF_ADDITION;
493- } else if (lineBuffer[0] == '-' && lineBuffer[1] == '-' && lineBuffer[2] == '-') {
494- return SCE_ERR_DIFF_MESSAGE;
800+ if (strstart(lineBuffer, "+++ ")) {
801+ return SCE_ERR_DIFF_MESSAGE;
802+ } else {
803+ return SCE_ERR_DIFF_ADDITION;
804+ }
495805 } else if (lineBuffer[0] == '-') {
496- return SCE_ERR_DIFF_DELETION;
806+ if (strstart(lineBuffer, "--- ")) {
807+ return SCE_ERR_DIFF_MESSAGE;
808+ } else {
809+ return SCE_ERR_DIFF_DELETION;
810+ }
497811 } else if (strstart(lineBuffer, "cf90-")) {
498812 // Absoft Pro Fortran 90/95 v8.2 error and/or warning message
499813 return SCE_ERR_ABSF;
@@ -669,7 +983,7 @@
669983 }
670984
671985 static void ColouriseErrorListDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
672- char lineBuffer[1024];
986+ char lineBuffer[10000];
673987 styler.StartAt(startPos);
674988 styler.StartSegment(startPos);
675989 unsigned int linePos = 0;
--- trunk/src/Utils/scintilla/src/LexPOV.cxx (revision 4272)
+++ trunk/src/Utils/scintilla/src/LexPOV.cxx (revision 4273)
@@ -3,7 +3,7 @@
33 ** Lexer for POV-Ray SDL (Persistance of Vision Raytracer, Scene Description Language).
44 ** Written by Philippe Lhoste but this is mostly a derivative of LexCPP...
55 **/
6-// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
6+// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
77 // The License.txt file describes the conditions under which this software may be distributed.
88
99 // Some points that distinguish from a simple C lexer:
@@ -29,15 +29,15 @@
2929 #include "Scintilla.h"
3030 #include "SciLexer.h"
3131
32-static inline bool IsAWordChar(const int ch) {
32+static inline bool IsAWordChar(int ch) {
3333 return ch < 0x80 && (isalnum(ch) || ch == '_');
3434 }
3535
36-static inline bool IsAWordStart(const int ch) {
36+static inline bool IsAWordStart(int ch) {
3737 return ch < 0x80 && isalpha(ch);
3838 }
3939
40-static inline bool IsANumberChar(const int ch) {
40+static inline bool IsANumberChar(int ch) {
4141 // Not exactly following number definition (several dots are seen as OK, etc.)
4242 // but probably enough in most cases.
4343 return (ch < 0x80) &&
@@ -69,13 +69,14 @@
6969 }
7070
7171 // Do not leak onto next line
72- if (initStyle == SCE_POV_STRINGEOL) {
72+ if (initStyle == SCE_POV_STRINGEOL || initStyle == SCE_POV_COMMENTLINE) {
7373 initStyle = SCE_POV_DEFAULT;
7474 }
7575
76- StyleContext sc(startPos, length, initStyle, styler);
7776 short stringLen = 0;
7877
78+ StyleContext sc(startPos, length, initStyle, styler);
79+
7980 for (; sc.More(); sc.Forward()) {
8081 if (sc.atLineEnd) {
8182 // Update the line state, so it can be seen by next line
@@ -151,7 +152,7 @@
151152 }
152153 } else if (sc.state == SCE_POV_COMMENTLINE) {
153154 if (sc.atLineEnd) {
154- sc.SetState(SCE_POV_DEFAULT);
155+ sc.ForwardSetState(SCE_POV_DEFAULT);
155156 }
156157 } else if (sc.state == SCE_POV_STRING) {
157158 if (sc.ch == '\\') {
--- trunk/src/Utils/scintilla/src/LexPerl.cxx (revision 4272)
+++ trunk/src/Utils/scintilla/src/LexPerl.cxx (revision 4273)
@@ -20,12 +20,19 @@
2020 #include "Scintilla.h"
2121 #include "SciLexer.h"
2222
23-#define PERLNUM_DECIMAL 1
24-#define PERLNUM_NON_DEC 2
25-#define PERLNUM_FLOAT 3
26-#define PERLNUM_VECTOR 4
27-#define PERLNUM_V_VECTOR 5
23+#define PERLNUM_BINARY 1 // order is significant: 1-4 cannot have a dot
24+#define PERLNUM_HEX 2
25+#define PERLNUM_OCTAL 3
26+#define PERLNUM_FLOAT 4 // actually exponent part
27+#define PERLNUM_DECIMAL 5 // 1-5 are numbers; 6-7 are strings
28+#define PERLNUM_VECTOR 6
29+#define PERLNUM_V_VECTOR 7
30+#define PERLNUM_BAD 8
2831
32+#define BACK_NONE 0 // lookback state for bareword disambiguation:
33+#define BACK_OPERATOR 1 // whitespace/comments are insignificant
34+#define BACK_KEYWORD 2 // operators/keywords are needed for disambiguation
35+
2936 #define HERE_DELIM_MAX 256
3037
3138 static inline bool isEOLChar(char ch) {
@@ -44,7 +51,7 @@
4451 ch == '(' || ch == ')' || ch == '-' || ch == '+' ||
4552 ch == '=' || ch == '|' || ch == '{' || ch == '}' ||
4653 ch == '[' || ch == ']' || ch == ':' || ch == ';' ||
47- ch == '>' || ch == ',' ||
54+ ch == '>' || ch == ',' ||
4855 ch == '?' || ch == '!' || ch == '.' || ch == '~')
4956 return true;
5057 // these chars are already tested before this call
@@ -52,17 +59,13 @@
5259 return false;
5360 }
5461
55-static int classifyWordPerl(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
62+static bool isPerlKeyword(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
5663 char s[100];
57- for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
58- s[i] = styler[start + i];
59- s[i + 1] = '\0';
60- }
61- char chAttr = SCE_PL_IDENTIFIER;
62- if (keywords.InList(s))
63- chAttr = SCE_PL_WORD;
64- styler.ColourTo(end, chAttr);
65- return chAttr;
64+ unsigned int i, len = end - start;
65+ if (len > 30) { len = 30; }
66+ for (i = 0; i < len; i++, start++) s[i] = styler[start];
67+ s[i] = '\0';
68+ return keywords.InList(s);
6669 }
6770
6871 static inline bool isEndVar(char ch) {
@@ -76,16 +79,12 @@
7679 }
7780
7881 static inline char actualNumStyle(int numberStyle) {
79- switch (numberStyle) {
80- case PERLNUM_VECTOR:
81- case PERLNUM_V_VECTOR:
82- return SCE_PL_STRING;
83- case PERLNUM_DECIMAL:
84- case PERLNUM_NON_DEC:
85- case PERLNUM_FLOAT:
86- default:
87- return SCE_PL_NUMBER;
88- }
82+ if (numberStyle == PERLNUM_VECTOR || numberStyle == PERLNUM_V_VECTOR) {
83+ return SCE_PL_STRING;
84+ } else if (numberStyle == PERLNUM_BAD) {
85+ return SCE_PL_ERROR;
86+ }
87+ return SCE_PL_NUMBER;
8988 }
9089
9190 static bool isMatch(Accessor &styler, int lengthDoc, int pos, const char *val) {
@@ -133,6 +132,8 @@
133132 char *Delimiter; // the Delimiter, 256: sizeof PL_tokenbuf
134133 HereDocCls() {
135134 State = 0;
135+ Quote = 0;
136+ Quoted = false;
136137 DelimiterLength = 0;
137138 Delimiter = new char[HERE_DELIM_MAX];
138139 Delimiter[0] = '\0';
@@ -196,6 +197,7 @@
196197 || state == SCE_PL_CHARACTER
197198 || state == SCE_PL_NUMBER
198199 || state == SCE_PL_IDENTIFIER
200+ || state == SCE_PL_ERROR
199201 ) {
200202 while ((startPos > 1) && (styler.StyleAt(startPos - 1) == state)) {
201203 startPos--;
@@ -203,6 +205,22 @@
203205 state = SCE_PL_DEFAULT;
204206 }
205207
208+ // lookback at start of lexing to set proper state for backflag
209+ // after this, they are updated when elements are lexed
210+ int backflag = BACK_NONE;
211+ unsigned int backPos = startPos;
212+ if (backPos > 0) {
213+ backPos--;
214+ int sty = SCE_PL_DEFAULT;
215+ while ((backPos > 0) && (sty = styler.StyleAt(backPos),
216+ sty == SCE_PL_DEFAULT || sty == SCE_PL_COMMENTLINE))
217+ backPos--;
218+ if (sty == SCE_PL_OPERATOR)
219+ backflag = BACK_OPERATOR;
220+ else if (sty == SCE_PL_WORD)
221+ backflag = BACK_KEYWORD;
222+ }
223+
206224 styler.StartAt(startPos);
207225 char chPrev = styler.SafeGetCharAt(startPos - 1);
208226 if (startPos == 0)
@@ -269,25 +287,34 @@
269287 if (isdigit(ch) || (isdigit(chNext) &&
270288 (ch == '.' || ch == 'v'))) {
271289 state = SCE_PL_NUMBER;
290+ backflag = BACK_NONE;
272291 numState = PERLNUM_DECIMAL;
273292 dotCount = 0;
274293 if (ch == '0') { // hex,bin,octal
275- if (chNext == 'x' || chNext == 'b' || isdigit(chNext)) {
276- numState = PERLNUM_NON_DEC;
277- }
294+ if (chNext == 'x') {
295+ numState = PERLNUM_HEX;
296+ } else if (chNext == 'b') {
297+ numState = PERLNUM_BINARY;
298+ } else if (isdigit(chNext)) {
299+ numState = PERLNUM_OCTAL;
300+ }
301+ if (numState != PERLNUM_DECIMAL) {
302+ i++;
303+ ch = chNext;
304+ chNext = chNext2;
305+ }
278306 } else if (ch == 'v') { // vector
279307 numState = PERLNUM_V_VECTOR;
280308 }
281309 } else if (iswordstart(ch)) {
282- if (chPrev == '>' && styler.SafeGetCharAt(i - 2) == '-') {
283- state = SCE_PL_IDENTIFIER; // part of "->" expr
284- if ((!iswordchar(chNext) && chNext != '\'')
285- || (chNext == '.' && chNext2 == '.')) {
286- // We need that if length of word == 1!
287- styler.ColourTo(i, SCE_PL_IDENTIFIER);
288- state = SCE_PL_DEFAULT;
289- }
290- } else if (ch == 's' && !isNonQuote(chNext)) {
310+ // if immediately prefixed by '::', always a bareword
311+ state = SCE_PL_WORD;
312+ if (chPrev == ':' && styler.SafeGetCharAt(i - 2) == ':') {
313+ state = SCE_PL_IDENTIFIER;
314+ }
315+ unsigned int kw = i + 1;
316+ // first check for possible quote-like delimiter
317+ if (ch == 's' && !isNonQuote(chNext)) {
291318 state = SCE_PL_REGSUBST;
292319 Quote.New(2);
293320 } else if (ch == 'm' && !isNonQuote(chNext)) {
@@ -302,30 +329,112 @@
302329 } else if (ch == 't' && chNext == 'r' && !isNonQuote(chNext2)) {
303330 state = SCE_PL_REGSUBST;
304331 Quote.New(2);
305- i++;
306- chNext = chNext2;
332+ kw++;
307333 } else if (ch == 'q' && (chNext == 'q' || chNext == 'r' || chNext == 'w' || chNext == 'x') && !isNonQuote(chNext2)) {
308334 if (chNext == 'q') state = SCE_PL_STRING_QQ;
309335 else if (chNext == 'x') state = SCE_PL_STRING_QX;
310336 else if (chNext == 'r') state = SCE_PL_STRING_QR;
311337 else if (chNext == 'w') state = SCE_PL_STRING_QW;
312- i++;
313- chNext = chNext2;
314338 Quote.New(1);
339+ kw++;
315340 } else if (ch == 'x' && (chNext == '=' || // repetition
316- (chNext != '_' && !isalnum(chNext)) ||
317- (isdigit(chPrev) && isdigit(chNext)))) {
318- styler.ColourTo(i, SCE_PL_OPERATOR);
319- } else {
320- state = SCE_PL_WORD;
321- if ((!iswordchar(chNext) && chNext != '\'')
322- || (chNext == '.' && chNext2 == '.')) {
323- // We need that if length of word == 1!
324- // This test is copied from the SCE_PL_WORD handler.
325- classifyWordPerl(styler.GetStartSegment(), i, keywords, styler);
326- state = SCE_PL_DEFAULT;
327- }
328- }
341+ (chNext != '_' && !isalnum(chNext)) ||
342+ (isdigit(chPrev) && isdigit(chNext)))) {
343+ state = SCE_PL_OPERATOR;
344+ }
345+ // if potentially a keyword, scan forward and grab word, then check
346+ // if it's really one; if yes, disambiguation test is performed
347+ // otherwise it is always a bareword and we skip a lot of scanning
348+ // note: keywords assumed to be limited to [_a-zA-Z] only
349+ if (state == SCE_PL_WORD) {
350+ while (iswordstart(styler.SafeGetCharAt(kw))) kw++;
351+ if (!isPerlKeyword(styler.GetStartSegment(), kw, keywords, styler)) {
352+ state = SCE_PL_IDENTIFIER;
353+ }
354+ }
355+ // if already SCE_PL_IDENTIFIER, then no ambiguity, skip this
356+ // for quote-like delimiters/keywords, attempt to disambiguate
357+ // to select for bareword, change state -> SCE_PL_IDENTIFIER
358+ if (state != SCE_PL_IDENTIFIER && i > 0) {
359+ unsigned int j = i;
360+ bool moreback = false; // true if passed newline/comments
361+ bool brace = false; // true if opening brace found
362+ char ch2;
363+ // first look backwards past whitespace/comments for EOLs
364+ // if BACK_NONE, neither operator nor keyword, so skip test
365+ if (backflag != BACK_NONE) {
366+ while (--j > backPos) {
367+ if (isEOLChar(styler.SafeGetCharAt(j)))
368+ moreback = true;
369+ }
370+ ch2 = styler.SafeGetCharAt(j);
371+ if (ch2 == '{' && !moreback) {
372+ // {bareword: possible variable spec
373+ brace = true;
374+ } else if ((ch2 == '&')
375+ // &bareword: subroutine call
376+ || (ch2 == '>' && styler.SafeGetCharAt(j - 1) == '-')
377+ // ->bareword: part of variable spec
378+ || (ch2 == 'b' && styler.Match(j - 2, "su"))) {
379+ // sub bareword: subroutine declaration
380+ // (implied BACK_KEYWORD, no keywords end in 'sub'!)
381+ state = SCE_PL_IDENTIFIER;
382+ }
383+ // if status still ambiguous, look forward after word past
384+ // tabs/spaces only; if ch2 isn't one of '[{(,' it can never
385+ // match anything, so skip the whole thing
386+ j = kw;
387+ if (state != SCE_PL_IDENTIFIER
388+ && (ch2 == '{' || ch2 == '(' || ch2 == '['|| ch2 == ',')
389+ && kw < lengthDoc) {
390+ while (ch2 = styler.SafeGetCharAt(j),
391+ (ch2 == ' ' || ch2 == '\t') && j < lengthDoc) {
392+ j++;
393+ }
394+ if ((ch2 == '}' && brace)
395+ // {bareword}: variable spec
396+ || (ch2 == '=' && styler.SafeGetCharAt(j + 1) == '>')) {
397+ // [{(, bareword=>: hash literal
398+ state = SCE_PL_IDENTIFIER;
399+ }
400+ }
401+ }
402+ }
403+ backflag = BACK_NONE;
404+ // an identifier or bareword
405+ if (state == SCE_PL_IDENTIFIER) {
406+ if ((!iswordchar(chNext) && chNext != '\'')
407+ || (chNext == '.' && chNext2 == '.')) {
408+ // We need that if length of word == 1!
409+ // This test is copied from the SCE_PL_WORD handler.
410+ styler.ColourTo(i, SCE_PL_IDENTIFIER);
411+ state = SCE_PL_DEFAULT;
412+ }
413+ // a keyword
414+ } else if (state == SCE_PL_WORD) {
415+ i = kw - 1;
416+ if (ch == '_' && chNext == '_' &&
417+ (isMatch(styler, lengthDoc, styler.GetStartSegment(), "__DATA__")
418+ || isMatch(styler, lengthDoc, styler.GetStartSegment(), "__END__"))) {
419+ styler.ColourTo(i, SCE_PL_DATASECTION);
420+ state = SCE_PL_DATASECTION;
421+ } else {
422+ styler.ColourTo(i, SCE_PL_WORD);
423+ state = SCE_PL_DEFAULT;
424+ backflag = BACK_KEYWORD;
425+ backPos = i;
426+ }
427+ ch = styler.SafeGetCharAt(i);
428+ chNext = styler.SafeGetCharAt(i + 1);
429+ // a repetition operator 'x'
430+ } else if (state == SCE_PL_OPERATOR) {
431+ styler.ColourTo(i, SCE_PL_OPERATOR);
432+ state = SCE_PL_DEFAULT;
433+ // quote-like delimiter, skip one char if double-char delimiter
434+ } else {
435+ i = kw - 1;
436+ chNext = styler.SafeGetCharAt(i + 1);
437+ }
329438 } else if (ch == '#') {
330439 state = SCE_PL_COMMENTLINE;
331440 } else if (ch == '\"') {
@@ -332,6 +441,7 @@
332441 state = SCE_PL_STRING;
333442 Quote.New(1);
334443 Quote.Open(ch);
444+ backflag = BACK_NONE;
335445 } else if (ch == '\'') {
336446 if (chPrev == '&') {
337447 // Archaic call
@@ -341,10 +451,12 @@
341451 Quote.New(1);
342452 Quote.Open(ch);
343453 }
454+ backflag = BACK_NONE;
344455 } else if (ch == '`') {
345456 state = SCE_PL_BACKTICKS;
346457 Quote.New(1);
347458 Quote.Open(ch);
459+ backflag = BACK_NONE;
348460 } else if (ch == '$') {
349461 if ((chNext == '{') || isspacechar(chNext)) {
350462 styler.ColourTo(i, SCE_PL_SCALAR);
@@ -360,28 +472,42 @@
360472 chNext = chNext2;
361473 }
362474 }
475+ backflag = BACK_NONE;
363476 } else if (ch == '@') {
364477 if (isalpha(chNext) || chNext == '#' || chNext == '$'
365- || chNext == '_' || chNext == '+') {
478+ || chNext == '_' || chNext == '+' || chNext == '-') {
366479 state = SCE_PL_ARRAY;
367480 } else if (chNext != '{' && chNext != '[') {
368481 styler.ColourTo(i, SCE_PL_ARRAY);
369- i++;
370- ch = ' ';
371482 } else {
372483 styler.ColourTo(i, SCE_PL_ARRAY);
373484 }
485+ backflag = BACK_NONE;
374486 } else if (ch == '%') {
375- if (isalpha(chNext) || chNext == '#' || chNext == '$' || chNext == '_') {
487+ if (isalpha(chNext) || chNext == '#' || chNext == '$'
488+ || chNext == '_' || chNext == '!' || chNext == '^') {
376489 state = SCE_PL_HASH;
490+ i++;
491+ ch = chNext;
492+ chNext = chNext2;
377493 } else if (chNext == '{') {
378494 styler.ColourTo(i, SCE_PL_HASH);
379495 } else {
380496 styler.ColourTo(i, SCE_PL_OPERATOR);
381497 }
498+ backflag = BACK_NONE;
382499 } else if (ch == '*') {
383- if (isalpha(chNext) || chNext == '_' || chNext == '{') {
500+ char strch[2];
501+ strch[0] = chNext;
502+ strch[1] = '\0';
503+ if (isalpha(chNext) || chNext == '_' ||
504+ NULL != strstr("^/|,\\\";#%^:?<>)[]", strch)) {
384505 state = SCE_PL_SYMBOLTABLE;
506+ i++;
507+ ch = chNext;
508+ chNext = chNext2;
509+ } else if (chNext == '{') {
510+ styler.ColourTo(i, SCE_PL_SYMBOLTABLE);
385511 } else {
386512 if (chNext == '*') { // exponentiation
387513 i++;
@@ -390,14 +516,22 @@
390516 }
391517 styler.ColourTo(i, SCE_PL_OPERATOR);
392518 }
393- } else if (ch == '/') {
519+ backflag = BACK_NONE;
520+ } else if (ch == '/' || (ch == '<' && chNext == '<')) {
394521 // Explicit backward peeking to set a consistent preferRE for
395522 // any slash found, so no longer need to track preferRE state.
396523 // Find first previous significant lexed element and interpret.
524+ // Test for HERE doc start '<<' shares this code, helps to
525+ // determine if it should be an operator.
397526 bool preferRE = false;
527+ bool isHereDoc = (ch == '<');
528+ bool hereDocSpace = false; // these are for corner case:
529+ bool hereDocScalar = false; // SCALAR [whitespace] '<<'
398530 unsigned int bk = (i > 0)? i - 1: 0;
399531 char bkch;
400532 styler.Flush();
533+ if (styler.StyleAt(bk) == SCE_PL_DEFAULT)
534+ hereDocSpace = true;
401535 while ((bk > 0) && (styler.StyleAt(bk) == SCE_PL_DEFAULT ||
402536 styler.StyleAt(bk) == SCE_PL_COMMENTLINE)) {
403537 bk--;
@@ -494,6 +628,9 @@
494628 bk--;
495629 }
496630 break;
631+ case SCE_PL_SCALAR: // for $var<< case
632+ hereDocScalar = true;
633+ break;
497634 // other styles uses the default, preferRE=false
498635 case SCE_PL_WORD:
499636 case SCE_PL_POD:
@@ -505,16 +642,27 @@
505642 break;
506643 }
507644 }
508- if (preferRE) {
509- state = SCE_PL_REGEX;
510- Quote.New(1);
511- Quote.Open(ch);
512- } else {
513- styler.ColourTo(i, SCE_PL_OPERATOR);
514- }
515- } else if (ch == '<' && chNext == '<') {
516- state = SCE_PL_HERE_DELIM;
517- HereDoc.State = 0;
645+ if (isHereDoc) { // handle HERE doc
646+ // if SCALAR whitespace '<<', *always* a HERE doc
647+ if (preferRE || (hereDocSpace && hereDocScalar)) {
648+ state = SCE_PL_HERE_DELIM;
649+ HereDoc.State = 0;
650+ } else { // << operator
651+ i++;
652+ ch = chNext;
653+ chNext = chNext2;
654+ styler.ColourTo(i, SCE_PL_OPERATOR);
655+ }
656+ } else { // handle regexp
657+ if (preferRE) {
658+ state = SCE_PL_REGEX;
659+ Quote.New(1);
660+ Quote.Open(ch);
661+ } else { // / operator
662+ styler.ColourTo(i, SCE_PL_OPERATOR);
663+ }
664+ }
665+ backflag = BACK_NONE;
518666 } else if (ch == '<') {
519667 // looks forward for matching > on same line
520668 unsigned int fw = i + 1;
@@ -540,10 +688,12 @@
540688 fw++;
541689 }
542690 styler.ColourTo(i, SCE_PL_OPERATOR);
691+ backflag = BACK_NONE;
543692 } else if (ch == '=' // POD
544693 && isalpha(chNext)
545694 && (isEOLChar(chPrev))) {
546695 state = SCE_PL_POD;
696+ backflag = BACK_NONE;
547697 //sookedpos = 0;
548698 //sooked[sookedpos] = '\0';
549699 } else if (ch == '-' // file test operators
@@ -554,6 +704,7 @@
554704 i++;
555705 ch = chNext;
556706 chNext = chNext2;
707+ backflag = BACK_NONE;
557708 } else if (isPerlOperator(ch)) {
558709 if (ch == '.' && chNext == '.') { // .. and ...
559710 i++;
@@ -563,6 +714,8 @@
563714 chNext = styler.SafeGetCharAt(i + 1);
564715 }
565716 styler.ColourTo(i, SCE_PL_OPERATOR);
717+ backflag = BACK_OPERATOR;
718+ backPos = i;
566719 } else {
567720 // keep colouring defaults to make restart easier
568721 styler.ColourTo(i, SCE_PL_DEFAULT);
@@ -572,7 +725,7 @@
572725 if (chNext == '.') {
573726 // double dot is always an operator
574727 goto numAtEnd;
575- } else if (numState == PERLNUM_NON_DEC || numState == PERLNUM_FLOAT) {
728+ } else if (numState <= PERLNUM_FLOAT) {
576729 // non-decimal number or float exponent, consume next dot
577730 styler.ColourTo(i - 1, SCE_PL_NUMBER);
578731 styler.ColourTo(i, SCE_PL_OPERATOR);
@@ -599,7 +752,7 @@
599752 if (numState == PERLNUM_VECTOR || numState == PERLNUM_V_VECTOR) {
600753 if (isalpha(ch)) {
601754 if (dotCount == 0) { // change to word
602- state = SCE_PL_WORD;
755+ state = SCE_PL_IDENTIFIER;
603756 } else { // vector then word
604757 goto numAtEnd;
605758 }
@@ -619,9 +772,24 @@
619772 if (!isdigit(ch)) { // float then word
620773 goto numAtEnd;
621774 }
622- } else {// (numState == PERLNUM_NON_DEC)
623- // allow alphanum for bin,hex,oct for now
624- }
775+ } else if (numState == PERLNUM_OCTAL) {
776+ if (!isdigit(ch))
777+ goto numAtEnd;
778+ else if (ch > '7')
779+ numState = PERLNUM_BAD;
780+ } else if (numState == PERLNUM_BINARY) {
781+ if (!isdigit(ch))
782+ goto numAtEnd;
783+ else if (ch > '1')
784+ numState = PERLNUM_BAD;
785+ } else if (numState == PERLNUM_HEX) {
786+ int ch2 = toupper(ch);
787+ if (!isdigit(ch) && !(ch2 >= 'A' && ch2 <= 'F'))
788+ goto numAtEnd;
789+ } else {//(numState == PERLNUM_BAD) {
790+ if (!isdigit(ch))
791+ goto numAtEnd;
792+ }
625793 } else {
626794 // complete current number or vector
627795 numAtEnd:
@@ -629,25 +797,8 @@
629797 state = SCE_PL_DEFAULT;
630798 goto restartLexer;
631799 }
632- } else if (state == SCE_PL_WORD) {
633- if ((!iswordchar(chNext) && chNext != '\'')
634- || chNext == '.') {
635- // ".." is always an operator if preceded by a SCE_PL_WORD.
636- // "." never used in Perl variable names
637- // Archaic Perl has quotes inside names
638- if (isMatch(styler, lengthDoc, styler.GetStartSegment(), "__DATA__")
639- || isMatch(styler, lengthDoc, styler.GetStartSegment(), "__END__")) {
640- styler.ColourTo(i, SCE_PL_DATASECTION);
641- state = SCE_PL_DATASECTION;
642- } else {
643- classifyWordPerl(styler.GetStartSegment(), i, keywords, styler);
644- state = SCE_PL_DEFAULT;
645- ch = ' ';
646- }
647- }
648800 } else if (state == SCE_PL_IDENTIFIER) {
649- if ((!iswordchar(chNext) && chNext != '\'')
650- || chNext == '.') {
801+ if (!iswordstart(chNext) && chNext != '\'') {
651802 styler.ColourTo(i, SCE_PL_IDENTIFIER);
652803 state = SCE_PL_DEFAULT;
653804 ch = ' ';
@@ -690,29 +841,46 @@
690841 // Whitespace acceptable after <<[-] operator.
691842 //
692843 if (HereDoc.State == 0) { // '<<' encountered
844+ bool gotspace = false;
845+ unsigned int oldi = i;
846+ if (chNext == ' ' || chNext == '\t') {
847+ // skip whitespace; legal for quoted delimiters
848+ gotspace = true;
849+ do {
850+ i++;
851+ chNext = styler.SafeGetCharAt(i + 1);
852+ } while ((i + 1 < lengthDoc) && (chNext == ' ' || chNext == '\t'));
853+ chNext2 = styler.SafeGetCharAt(i + 2);
854+ }
693855 HereDoc.State = 1;
694856 HereDoc.Quote = chNext;
695857 HereDoc.Quoted = false;
696858 HereDoc.DelimiterLength = 0;
697859 HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
698- if (chNext == '\'' || chNext == '"' || chNext == '`') { // a quoted here-doc delimiter
860+ if (chNext == '\'' || chNext == '"' || chNext == '`') {
861+ // a quoted here-doc delimiter
699862 i++;
700863 ch = chNext;
701864 chNext = chNext2;
702865 HereDoc.Quoted = true;
703- } else if (isalpha(chNext) || chNext == '_') {
704- // an unquoted here-doc delimiter, no special handling
705866 } else if (isspacechar(chNext) || isdigit(chNext) || chNext == '\\'
706- || chNext == '=' || chNext == '$' || chNext == '@') {
867+ || chNext == '=' || chNext == '$' || chNext == '@'
868+ || ((isalpha(chNext) || chNext == '_') && gotspace)) {
707869 // left shift << or <<= operator cases
870+ // restore position if operator
871+ i = oldi;
708872 styler.ColourTo(i, SCE_PL_OPERATOR);
709873 state = SCE_PL_DEFAULT;
710874 HereDoc.State = 0;
875+ goto restartLexer;
711876 } else {
877+ // an unquoted here-doc delimiter, no special handling
878+ // (cannot be prefixed by spaces/tabs), or
712879 // symbols terminates; deprecated zero-length delimiter
713880 }
714881
715882 } else if (HereDoc.State == 1) { // collect the delimiter
883+ backflag = BACK_NONE;
716884 if (HereDoc.Quoted) { // a quoted here-doc delimiter
717885 if (ch == HereDoc.Quote) { // closing quote => end of delimiter
718886 styler.ColourTo(i, state);
@@ -751,6 +919,7 @@
751919 if (isEOLChar(ch)) {
752920 styler.ColourTo(i - 1, state);
753921 state = SCE_PL_DEFAULT;
922+ backflag = BACK_NONE;
754923 HereDoc.State = 0;
755924 goto restartLexer;
756925 }
@@ -759,7 +928,7 @@
759928 } else if (state == SCE_PL_POD
760929 || state == SCE_PL_POD_VERB) {
761930 if (isEOLChar(chPrev)) {
762- if (ch ==' ' || ch == '\t') {
931+ if (ch == ' ' || ch == '\t') {
763932 styler.ColourTo(i - 1, state);
764933 state = SCE_PL_POD_VERB;
765934 } else {
@@ -787,8 +956,7 @@
787956 chNext = chNext2;
788957 }
789958 else if (isEndVar(ch)) {
790- if ((state == SCE_PL_SCALAR || state == SCE_PL_ARRAY)
791- && i == (styler.GetStartSegment() + 1)) {
959+ if (i == (styler.GetStartSegment() + 1)) {
792960 // Special variable: $(, $_ etc.
793961 styler.ColourTo(i, state);
794962 state = SCE_PL_DEFAULT;
@@ -932,6 +1100,20 @@
9321100 styler.ColourTo(lengthDoc - 1, state);
9331101 }
9341102
1103+static bool IsCommentLine(int line, Accessor &styler) {
1104+ int pos = styler.LineStart(line);
1105+ int eol_pos = styler.LineStart(line + 1) - 1;
1106+ for (int i = pos; i < eol_pos; i++) {
1107+ char ch = styler[i];
1108+ int style = styler.StyleAt(i);
1109+ if (ch == '#' && style == SCE_PL_COMMENTLINE)
1110+ return true;
1111+ else if (ch != ' ' && ch != '\t')
1112+ return false;
1113+ }
1114+ return false;
1115+}
1116+
9351117 static void FoldPerlDoc(unsigned int startPos, int length, int, WordList *[],
9361118 Accessor &styler) {
9371119 bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
@@ -942,7 +1124,9 @@
9421124 unsigned int endPos = startPos + length;
9431125 int visibleChars = 0;
9441126 int lineCurrent = styler.GetLine(startPos);
945- int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
1127+ int levelPrev = SC_FOLDLEVELBASE;
1128+ if (lineCurrent > 0)
1129+ levelPrev = styler.LevelAt(lineCurrent - 1) >> 16;
9461130 int levelCurrent = levelPrev;
9471131 char chNext = styler[startPos];
9481132 char chPrev = styler.SafeGetCharAt(startPos - 1);
@@ -957,16 +1141,16 @@
9571141 styleNext = styler.StyleAt(i + 1);
9581142 bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
9591143 bool atLineStart = isEOLChar(chPrev) || i == 0;
960- if (foldComment && (style == SCE_PL_COMMENTLINE)) {
961- if ((ch == '/') && (chNext == '/')) {
962- char chNext2 = styler.SafeGetCharAt(i + 2);
963- if (chNext2 == '{') {
964- levelCurrent++;
965- } else if (chNext2 == '}') {
966- levelCurrent--;
967- }
968- }
969- }
1144+ // Comment folding
1145+ if (foldComment && atEOL && IsCommentLine(lineCurrent, styler))
1146+ {
1147+ if (!IsCommentLine(lineCurrent - 1, styler)
1148+ && IsCommentLine(lineCurrent + 1, styler))
1149+ levelCurrent++;
1150+ else if (IsCommentLine(lineCurrent - 1, styler)
1151+ && !IsCommentLine(lineCurrent+1, styler))
1152+ levelCurrent--;
1153+ }
9701154 if (style == SCE_C_OPERATOR) {
9711155 if (ch == '{') {
9721156 levelCurrent++;
@@ -984,7 +1168,18 @@
9841168 levelCurrent--;
9851169 else if (styler.Match(i, "=head"))
9861170 isPodHeading = true;
987- }
1171+ } else if (style == SCE_PL_DATASECTION) {
1172+ if (ch == '=' && isalpha(chNext) && levelCurrent == SC_FOLDLEVELBASE)
1173+ levelCurrent++;
1174+ else if (styler.Match(i, "=cut") && levelCurrent > SC_FOLDLEVELBASE)
1175+ levelCurrent--;
1176+ else if (styler.Match(i, "=head"))
1177+ isPodHeading = true;
1178+ // if package used or unclosed brace, level > SC_FOLDLEVELBASE!
1179+ // reset needed as level test is vs. SC_FOLDLEVELBASE
1180+ else if (styler.Match(i, "__END__"))
1181+ levelCurrent = SC_FOLDLEVELBASE;
1182+ }
9881183 }
9891184 // Custom package folding
9901185 if (foldPackage && atLineStart) {
@@ -995,26 +1190,26 @@
9951190
9961191 if (atEOL) {
9971192 int lev = levelPrev;
998- if (visibleChars == 0 && foldCompact)
999- lev |= SC_FOLDLEVELWHITEFLAG;
1000- if ((levelCurrent > levelPrev) && (visibleChars > 0))
1001- lev |= SC_FOLDLEVELHEADERFLAG;
1002- if (lev != styler.LevelAt(lineCurrent)) {
1003- styler.SetLevel(lineCurrent, lev);
1004- }
10051193 if (isPodHeading) {
1006- lev = styler.LevelAt(lineCurrent) - 1;
1007- lev |= SC_FOLDLEVELHEADERFLAG;
1008- styler.SetLevel(lineCurrent, lev);
1009- isPodHeading = false;
1194+ lev = levelPrev - 1;
1195+ lev |= SC_FOLDLEVELHEADERFLAG;
1196+ isPodHeading = false;
10101197 }
10111198 // Check if line was a package declaration
10121199 // because packages need "special" treatment
10131200 if (isPackageLine) {
1014- styler.SetLevel(lineCurrent, SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG);
1201+ lev = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
10151202 levelCurrent = SC_FOLDLEVELBASE + 1;
10161203 isPackageLine = false;
10171204 }
1205+ lev |= levelCurrent << 16;
1206+ if (visibleChars == 0 && foldCompact)
1207+ lev |= SC_FOLDLEVELWHITEFLAG;
1208+ if ((levelCurrent > levelPrev) && (visibleChars > 0))
1209+ lev |= SC_FOLDLEVELHEADERFLAG;
1210+ if (lev != styler.LevelAt(lineCurrent)) {
1211+ styler.SetLevel(lineCurrent, lev);
1212+ }
10181213 lineCurrent++;
10191214 levelPrev = levelCurrent;
10201215 visibleChars = 0;
--- trunk/src/Utils/scintilla/src/LexRuby.cxx (revision 4272)
+++ trunk/src/Utils/scintilla/src/LexRuby.cxx (revision 4273)
@@ -19,342 +19,1233 @@
1919 #include "Scintilla.h"
2020 #include "SciLexer.h"
2121
22-static void ClassifyWordRb(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord) {
22+#ifdef SCI_NAMESPACE
23+using namespace Scintilla;
24+#endif
25+
26+//XXX Identical to Perl, put in common area
27+static inline bool isEOLChar(char ch) {
28+ return (ch == '\r') || (ch == '\n');
29+}
30+
31+static inline bool isRubyOperatorChar(char ch) {
32+ return strchr("%^&*\\()-+=|{}[]:;<>,/?!.~",ch) != NULL;
33+}
34+
35+
36+static inline bool isSafeAlpha(char ch) {
37+ return ((unsigned int) ch <= 127) && isalpha(ch);
38+}
39+
40+#define MAX_KEYWORD_LENGTH 200
41+
42+#define STYLE_MASK 63
43+#define actual_style(style) (style & STYLE_MASK)
44+
45+static bool followsDot(unsigned int pos, Accessor &styler) {
46+ styler.Flush();
47+ for (; pos >= 1; --pos) {
48+ int style = actual_style(styler.StyleAt(pos));
49+ char ch;
50+ switch (style) {
51+ case SCE_RB_DEFAULT:
52+ ch = styler[pos];
53+ if (ch == ' ' || ch == '\t') {
54+ //continue
55+ } else {
56+ return false;
57+ }
58+ break;
59+
60+ case SCE_RB_OPERATOR:
61+ return styler[pos] == '.';
62+
63+ default:
64+ return false;
65+ }
66+ }
67+ return false;
68+}
69+
70+// Forward declarations
71+static bool keywordIsAmbiguous(const char *prevWord);
72+static bool keywordDoStartsLoop(int pos,
73+ Accessor &styler);
74+static bool keywordIsModifier(const char *word,
75+ int pos,
76+ Accessor &styler);
77+
78+static int ClassifyWordRb(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord) {
2379 char s[100];
24- bool wordIsNumber = isdigit(styler[start]) != 0;
25- for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
26- s[i] = styler[start + i];
27- s[i + 1] = '\0';
80+ unsigned int i, j;
81+ unsigned int lim = end - start + 1; // num chars to copy
82+ if (lim >= MAX_KEYWORD_LENGTH) {
83+ lim = MAX_KEYWORD_LENGTH - 1;
2884 }
29- char chAttr = SCE_P_IDENTIFIER;
85+ for (i = start, j = 0; j < lim; i++, j++) {
86+ s[j] = styler[i];
87+ }
88+ s[j] = '\0';
89+ int chAttr;
3090 if (0 == strcmp(prevWord, "class"))
31- chAttr = SCE_P_CLASSNAME;
91+ chAttr = SCE_RB_CLASSNAME;
3292 else if (0 == strcmp(prevWord, "module"))
33- chAttr = SCE_P_CLASSNAME;
93+ chAttr = SCE_RB_MODULE_NAME;
3494 else if (0 == strcmp(prevWord, "def"))
35- chAttr = SCE_P_DEFNAME;
36- else if (wordIsNumber)
37- chAttr = SCE_P_NUMBER;
38- else if (keywords.InList(s))
39- chAttr = SCE_P_WORD;
40- // make sure that dot-qualifiers inside the word are lexed correct
41- else for (unsigned int i = 0; i < end - start + 1; i++) {
42- if (styler[start + i] == '.') {
43- styler.ColourTo(start + i - 1, chAttr);
44- styler.ColourTo(start + i, SCE_P_OPERATOR);
95+ chAttr = SCE_RB_DEFNAME;
96+ else if (keywords.InList(s) && !followsDot(start - 1, styler)) {
97+ if (keywordIsAmbiguous(s)
98+ && keywordIsModifier(s, start, styler)) {
99+
100+ // Demoted keywords are colored as keywords,
101+ // but do not affect changes in indentation.
102+ //
103+ // Consider the word 'if':
104+ // 1. <<if test ...>> : normal
105+ // 2. <<stmt if test>> : demoted
106+ // 3. <<lhs = if ...>> : normal: start a new indent level
107+ // 4. <<obj.if = 10>> : color as identifer, since it follows '.'
108+
109+ chAttr = SCE_RB_WORD_DEMOTED;
110+ } else {
111+ chAttr = SCE_RB_WORD;
112+ }
113+ } else
114+ chAttr = SCE_RB_IDENTIFIER;
115+ styler.ColourTo(end, chAttr);
116+ if (chAttr == SCE_RB_WORD) {
117+ strcpy(prevWord, s);
118+ } else {
119+ prevWord[0] = 0;
120+ }
121+ return chAttr;
122+}
123+
124+
125+//XXX Identical to Perl, put in common area
126+static bool isMatch(Accessor &styler, int lengthDoc, int pos, const char *val) {
127+ if ((pos + static_cast<int>(strlen(val))) >= lengthDoc) {
128+ return false;
129+ }
130+ while (*val) {
131+ if (*val != styler[pos++]) {
132+ return false;
45133 }
134+ val++;
46135 }
47- styler.ColourTo(end, chAttr);
48- strcpy(prevWord, s);
136+ return true;
49137 }
50138
51-static bool IsRbComment(Accessor &styler, int pos, int len) {
52- return len>0 && styler[pos]=='#';
139+// Do Ruby better -- find the end of the line, work back,
140+// and then check for leading white space
141+
142+// Precondition: the here-doc target can be indented
143+static bool lookingAtHereDocDelim(Accessor &styler,
144+ int pos,
145+ int lengthDoc,
146+ const char *HereDocDelim)
147+{
148+ if (!isMatch(styler, lengthDoc, pos, HereDocDelim)) {
149+ return false;
150+ }
151+ while (--pos > 0) {
152+ char ch = styler[pos];
153+ if (isEOLChar(ch)) {
154+ return true;
155+ } else if (ch != ' ' && ch != '\t') {
156+ return false;
157+ }
158+ }
159+ return false;
53160 }
54161
55-static bool IsRbStringStart(char ch, char chNext, char chNext2) {
56- if (ch == '\'' || ch == '"')
57- return true;
58- if (ch == 'u' || ch == 'U') {
59- if (chNext == '"' || chNext == '\'')
60- return true;
61- if ((chNext == 'r' || chNext == 'R') && (chNext2 == '"' || chNext2 == '\''))
62- return true;
63- }
64- if ((ch == 'r' || ch == 'R') && (chNext == '"' || chNext == '\''))
65- return true;
162+//XXX Identical to Perl, put in common area
163+static char opposite(char ch) {
164+ if (ch == '(')
165+ return ')';
166+ if (ch == '[')
167+ return ']';
168+ if (ch == '{')
169+ return '}';
170+ if (ch == '<')
171+ return '>';
172+ return ch;
173+}
66174
67- return false;
175+// Null transitions when we see we've reached the end
176+// and need to relex the curr char.
177+
178+static void redo_char(int &i, char &ch, char &chNext, char &chNext2,
179+ int &state) {
180+ i--;
181+ chNext2 = chNext;
182+ chNext = ch;
183+ state = SCE_RB_DEFAULT;
68184 }
69185
70-static bool IsRbWordStart(char ch, char chNext, char chNext2) {
71- return (iswordchar(ch) && !IsRbStringStart(ch, chNext, chNext2));
186+static void advance_char(int &i, char &ch, char &chNext, char &chNext2) {
187+ i++;
188+ ch = chNext;
189+ chNext = chNext2;
72190 }
73191
74-/* Return the state to use for the string starting at i; *nextIndex will be set to the first index following the quote(s) */
75-static int GetRbStringState(Accessor &styler, int i, int *nextIndex) {
76- char ch = styler.SafeGetCharAt(i);
77- char chNext = styler.SafeGetCharAt(i + 1);
192+// precondition: startPos points to one after the EOL char
193+static bool currLineContainsHereDelims(int& startPos,
194+ Accessor &styler) {
195+ if (startPos <= 1)
196+ return false;
78197
79- // Advance beyond r, u, or ur prefix, but bail if there are any unexpected chars
80- if (ch == 'r' || ch == 'R') {
81- i++;
82- ch = styler.SafeGetCharAt(i);
83- chNext = styler.SafeGetCharAt(i + 1);
84- }
85- else if (ch == 'u' || ch == 'U') {
86- if (chNext == 'r' || chNext == 'R')
87- i += 2;
88- else
89- i += 1;
90- ch = styler.SafeGetCharAt(i);
91- chNext = styler.SafeGetCharAt(i + 1);
92- }
198+ int pos;
199+ for (pos = startPos - 1; pos > 0; pos--) {
200+ char ch = styler.SafeGetCharAt(pos);
201+ if (isEOLChar(ch)) {
202+ // Leave the pointers where they are -- there are no
203+ // here doc delims on the current line, even if
204+ // the EOL isn't default style
205+
206+ return false;
207+ } else {
208+ styler.Flush();
209+ if (actual_style(styler.StyleAt(pos)) == SCE_RB_HERE_DELIM) {
210+ break;
211+ }
212+ }
213+ }
214+ if (pos == 0) {
215+ return false;
216+ }
217+ // Update the pointers so we don't have to re-analyze the string
218+ startPos = pos;
219+ return true;
220+}
93221
94- if (ch != '"' && ch != '\'') {
95- *nextIndex = i + 1;
96- return SCE_P_DEFAULT;
97- }
98222
99- if (i>0 && styler.SafeGetCharAt(i-1) == '$') {
100- *nextIndex = i + 1;
101- return SCE_P_DEFAULT;
102- }
223+static bool isEmptyLine(int pos,
224+ Accessor &styler) {
225+ int spaceFlags = 0;
226+ int lineCurrent = styler.GetLine(pos);
227+ int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL);
228+ return (indentCurrent & SC_FOLDLEVELWHITEFLAG) != 0;
229+}
103230
104- if (ch == chNext && ch == styler.SafeGetCharAt(i + 2)) {
105- *nextIndex = i + 3;
231+static bool RE_CanFollowKeyword(const char *keyword) {
232+ if (!strcmp(keyword, "and")
233+ || !strcmp(keyword, "begin")
234+ || !strcmp(keyword, "break")
235+ || !strcmp(keyword, "case")
236+ || !strcmp(keyword, "do")
237+ || !strcmp(keyword, "else")
238+ || !strcmp(keyword, "elsif")
239+ || !strcmp(keyword, "if")
240+ || !strcmp(keyword, "next")
241+ || !strcmp(keyword, "return")
242+ || !strcmp(keyword, "when")
243+ || !strcmp(keyword, "unless")
244+ || !strcmp(keyword, "until")
245+ || !strcmp(keyword, "not")
246+ || !strcmp(keyword, "or")) {
247+ return true;
248+ }
249+ return false;
250+}
251+
106252
107- if (ch == '"')
108- return SCE_P_TRIPLEDOUBLE;
109- else
110- return SCE_P_TRIPLE;
111- } else {
112- *nextIndex = i + 1;
253+//todo: if we aren't looking at a stdio character,
254+// move to the start of the first line that is not in a
255+// multi-line construct
113256
114- if (ch == '"')
115- return SCE_P_STRING;
116- else
117- return SCE_P_CHARACTER;
118- }
257+static void synchronizeDocStart(unsigned int& startPos,
258+ int &length,
259+ int &initStyle,
260+ Accessor &styler,
261+ bool skipWhiteSpace=false) {
262+
263+ styler.Flush();
264+ int style = actual_style(styler.StyleAt(startPos));
265+ switch (style) {
266+ case SCE_RB_STDIN:
267+ case SCE_RB_STDOUT:
268+ case SCE_RB_STDERR:
269+ // Don't do anything else with these.
270+ return;
271+ }
272+
273+ int pos = startPos;
274+ // Quick way to characterize each line
275+ int lineStart;
276+ for (lineStart = styler.GetLine(pos); lineStart > 0; lineStart--) {
277+ // Now look at the style before the previous line's EOL
278+ pos = styler.LineStart(lineStart) - 1;
279+ if (pos <= 10) {
280+ lineStart = 0;
281+ break;
282+ }
283+ char ch = styler.SafeGetCharAt(pos);
284+ char chPrev = styler.SafeGetCharAt(pos - 1);
285+ if (ch == '\n' && chPrev == '\r') {
286+ pos--;
287+ }
288+ if (styler.SafeGetCharAt(pos - 1) == '\\') {
289+ // Continuation line -- keep going
290+ } else if (actual_style(styler.StyleAt(pos)) != SCE_RB_DEFAULT) {
291+ // Part of multi-line construct -- keep going
292+ } else if (currLineContainsHereDelims(pos, styler)) {
293+ // Keep going, with pos and length now pointing
294+ // at the end of the here-doc delimiter
295+ } else if (skipWhiteSpace && isEmptyLine(pos, styler)) {
296+ // Keep going
297+ } else {
298+ break;
299+ }
300+ }
301+ pos = styler.LineStart(lineStart);
302+ length += (startPos - pos);
303+ startPos = pos;
304+ initStyle = SCE_RB_DEFAULT;
119305 }
120306
121307 static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
122308 WordList *keywordlists[], Accessor &styler) {
123309
124- int lengthDoc = startPos + length;
310+ // Lexer for Ruby often has to backtrack to start of current style to determine
311+ // which characters are being used as quotes, how deeply nested is the
312+ // start position and what the termination string is for here documents
313+
314+ WordList &keywords = *keywordlists[0];
125315
126- // Backtrack to previous line in case need to fix its tab whinging
127- if (startPos > 0) {
128- int lineCurrent = styler.GetLine(startPos);
129- if (lineCurrent > 0) {
130- startPos = styler.LineStart(lineCurrent-1);
131- if (startPos == 0)
132- initStyle = SCE_P_DEFAULT;
133- else
134- initStyle = styler.StyleAt(startPos-1);
316+ class HereDocCls {
317+ public:
318+ int State;
319+ // States
320+ // 0: '<<' encountered
321+ // 1: collect the delimiter
322+ // 1b: text between the end of the delimiter and the EOL
323+ // 2: here doc text (lines after the delimiter)
324+ char Quote; // the char after '<<'
325+ bool Quoted; // true if Quote in ('\'','"','`')
326+ int DelimiterLength; // strlen(Delimiter)
327+ char Delimiter[256]; // the Delimiter, limit of 256: from Perl
328+ bool CanBeIndented;
329+ HereDocCls() {
330+ State = 0;
331+ DelimiterLength = 0;
332+ Delimiter[0] = '\0';
333+ CanBeIndented = false;
135334 }
136- }
335+ };
336+ HereDocCls HereDoc;
137337
138- // Ruby uses a different mask because bad indentation is marked by oring with 32
139- styler.StartAt(startPos, 127);
338+ class QuoteCls {
339+ public:
340+ int Count;
341+ char Up;
342+ char Down;
343+ QuoteCls() {
344+ this->New();
345+ }
346+ void New() {
347+ Count = 0;
348+ Up = '\0';
349+ Down = '\0';
350+ }
351+ void Open(char u) {
352+ Count++;
353+ Up = u;
354+ Down = opposite(Up);
355+ }
356+ };
357+ QuoteCls Quote;
140358
141- WordList &keywords = *keywordlists[0];
359+ int numDots = 0; // For numbers --
360+ // Don't start lexing in the middle of a num
142361
143- int whingeLevel = styler.GetPropertyInt("tab.timmy.whinge.level");
144- char prevWord[200];
362+ synchronizeDocStart(startPos, length, initStyle, styler, // ref args
363+ false);
364+
365+ bool preferRE = true;
366+ int state = initStyle;
367+ int lengthDoc = startPos + length;
368+
369+ char prevWord[MAX_KEYWORD_LENGTH + 1]; // 1 byte for zero
145370 prevWord[0] = '\0';
146371 if (length == 0)
147- return ;
372+ return;
148373
149- int state = initStyle & 31;
374+ char chPrev = styler.SafeGetCharAt(startPos - 1);
375+ char chNext = styler.SafeGetCharAt(startPos);
376+ // Ruby uses a different mask because bad indentation is marked by oring with 32
377+ styler.StartAt(startPos, 127);
378+ styler.StartSegment(startPos);
150379
151- int nextIndex = 0;
152- char chPrev = ' ';
153- char chPrev2 = ' ';
154- char chNext = styler[startPos];
155- styler.StartSegment(startPos);
156- bool atStartLine = true;
157- int spaceFlags = 0;
380+ static int q_states[] = {SCE_RB_STRING_Q,
381+ SCE_RB_STRING_QQ,
382+ SCE_RB_STRING_QR,
383+ SCE_RB_STRING_QW,
384+ SCE_RB_STRING_QW,
385+ SCE_RB_STRING_QX};
386+ static const char* q_chars = "qQrwWx";
387+
158388 for (int i = startPos; i < lengthDoc; i++) {
159-
160- if (atStartLine) {
161- char chBad = static_cast<char>(64);
162- char chGood = static_cast<char>(0);
163- char chFlags = chGood;
164- if (whingeLevel == 1) {
165- chFlags = (spaceFlags & wsInconsistent) ? chBad : chGood;
166- } else if (whingeLevel == 2) {
167- chFlags = (spaceFlags & wsSpaceTab) ? chBad : chGood;
168- } else if (whingeLevel == 3) {
169- chFlags = (spaceFlags & wsSpace) ? chBad : chGood;
170- } else if (whingeLevel == 4) {
171- chFlags = (spaceFlags & wsTab) ? chBad : chGood;
172- }
173- styler.SetFlags(chFlags, static_cast<char>(state));
174- atStartLine = false;
175- }
176-
177389 char ch = chNext;
178390 chNext = styler.SafeGetCharAt(i + 1);
179391 char chNext2 = styler.SafeGetCharAt(i + 2);
180392
181- if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == lengthDoc)) {
182- if ((state == SCE_P_DEFAULT) || (state == SCE_P_TRIPLE) || (state == SCE_P_TRIPLEDOUBLE)) {
183- // Perform colourisation of white space and triple quoted strings at end of each line to allow
184- // tab marking to work inside white space and triple quoted strings
185- styler.ColourTo(i, state);
186- }
187- atStartLine = true;
188- }
189-
190- if (styler.IsLeadByte(ch)) {
191- chNext = styler.SafeGetCharAt(i + 2);
393+ if (styler.IsLeadByte(ch)) {
394+ chNext = chNext2;
192395 chPrev = ' ';
193- chPrev2 = ' ';
194396 i += 1;
195397 continue;
196398 }
399+
400+ // skip on DOS/Windows
401+ //No, don't, because some things will get tagged on,
402+ // so we won't recognize keywords, for example
403+#if 0
404+ if (ch == '\r' && chNext == '\n') {
405+ continue;
406+ }
407+#endif
408+
409+ if (HereDoc.State == 1 && isEOLChar(ch)) {
410+ // Begin of here-doc (the line after the here-doc delimiter):
411+ HereDoc.State = 2;
412+ styler.ColourTo(i-1, state);
413+ // Don't check for a missing quote, just jump into
414+ // the here-doc state
415+ state = SCE_RB_HERE_Q;
416+ }
197417
198- if (state == SCE_P_STRINGEOL) {
199- if (ch != '\r' && ch != '\n') {
200- styler.ColourTo(i - 1, state);
201- state = SCE_P_DEFAULT;
202- }
203- }
204- if (state == SCE_P_DEFAULT) {
205- if (IsRbWordStart(ch, chNext, chNext2)) {
206- styler.ColourTo(i - 1, state);
207- state = SCE_P_WORD;
418+ // Regular transitions
419+ if (state == SCE_RB_DEFAULT) {
420+ if (isdigit(ch)) {
421+ styler.ColourTo(i - 1, state);
422+ state = SCE_RB_NUMBER;
423+ numDots = 0;
424+ } else if (iswordstart(ch)) {
425+ styler.ColourTo(i - 1, state);
426+ state = SCE_RB_WORD;
208427 } else if (ch == '#') {
209428 styler.ColourTo(i - 1, state);
210- state = chNext == '#' ? SCE_P_COMMENTBLOCK : SCE_P_COMMENTLINE;
211- } else if (ch == '=' && chNext == 'b') {
429+ state = SCE_RB_COMMENTLINE;
430+ } else if (ch == '=') {
212431 // =begin indicates the start of a comment (doc) block
213- if(styler.SafeGetCharAt(i + 2) == 'e' && styler.SafeGetCharAt(i + 3) == 'g' && styler.SafeGetCharAt(i + 4) == 'i' && styler.SafeGetCharAt(i + 5) == 'n') {
432+ if (i == 0 || isEOLChar(chPrev)
433+ && chNext == 'b'
434+ && styler.SafeGetCharAt(i + 2) == 'e'
435+ && styler.SafeGetCharAt(i + 3) == 'g'
436+ && styler.SafeGetCharAt(i + 4) == 'i'
437+ && styler.SafeGetCharAt(i + 5) == 'n'
438+ && !iswordchar(styler.SafeGetCharAt(i + 6))) {
439+ styler.ColourTo(i - 1, state);
440+ state = SCE_RB_POD;
441+ } else {
214442 styler.ColourTo(i - 1, state);
215- state = SCE_P_TRIPLEDOUBLE; //SCE_C_COMMENT;
443+ styler.ColourTo(i, SCE_RB_OPERATOR);
444+ preferRE = true;
216445 }
217- } else if (IsRbStringStart(ch, chNext, chNext2)) {
446+ } else if (ch == '"') {
218447 styler.ColourTo(i - 1, state);
219- state = GetRbStringState(styler, i, &nextIndex);
220- if (nextIndex != i + 1) {
221- i = nextIndex - 1;
222- ch = ' ';
223- chPrev = ' ';
224- chNext = styler.SafeGetCharAt(i + 1);
225- }
226- } else if (isoperator(ch)) {
448+ state = SCE_RB_STRING;
449+ Quote.New();
450+ Quote.Open(ch);
451+ } else if (ch == '\'') {
452+ styler.ColourTo(i - 1, state);
453+ state = SCE_RB_CHARACTER;
454+ Quote.New();
455+ Quote.Open(ch);
456+ } else if (ch == '`') {
227457 styler.ColourTo(i - 1, state);
228- styler.ColourTo(i, SCE_P_OPERATOR);
229- }
230- } else if (state == SCE_P_WORD) {
231- if (!iswordchar(ch)) {
232- ClassifyWordRb(styler.GetStartSegment(), i - 1, keywords, styler, prevWord);
233- state = SCE_P_DEFAULT;
234- if (ch == '#') {
235- state = chNext == '#' ? SCE_P_COMMENTBLOCK : SCE_P_COMMENTLINE;
236- } else if (IsRbStringStart(ch, chNext, chNext2)) {
237- styler.ColourTo(i - 1, state);
238- state = GetRbStringState(styler, i, &nextIndex);
239- if (nextIndex != i + 1) {
240- i = nextIndex - 1;
241- ch = ' ';
242- chPrev = ' ';
458+ state = SCE_RB_BACKTICKS;
459+ Quote.New();
460+ Quote.Open(ch);
461+ } else if (ch == '@') {
462+ // Instance or class var
463+ styler.ColourTo(i - 1, state);
464+ if (chNext == '@') {
465+ state = SCE_RB_CLASS_VAR;
466+ advance_char(i, ch, chNext, chNext2); // pass by ref
467+ } else {
468+ state = SCE_RB_INSTANCE_VAR;
469+ }
470+ } else if (ch == '$') {
471+ // Check for a builtin global
472+ styler.ColourTo(i - 1, state);
473+ // Recognize it bit by bit
474+ state = SCE_RB_GLOBAL;
475+ } else if (ch == '/' && preferRE) {
476+ // Ambigous operator
477+ styler.ColourTo(i - 1, state);
478+ state = SCE_RB_REGEX;
479+ Quote.New();
480+ Quote.Open(ch);
481+ } else if (ch == '<' && chNext == '<' && chNext2 != '=') {
482+
483+ // Recognise the '<<' symbol - either a here document or a binary op
484+
485+ styler.ColourTo(i - 1, state);
486+ i++;
487+ chNext = chNext2;
488+ styler.ColourTo(i, SCE_RB_OPERATOR);
489+
490+ if (preferRE) {
491+ state = SCE_RB_HERE_DELIM;
492+ HereDoc.State = 0;
493+ } else {
494+ // leave state as default
495+ // We don't have all the heuristics Perl has for indications
496+ // of a here-doc, because '<<' is overloadable and used
497+ // for so many other classes.
498+ preferRE = true;
499+ }
500+ } else if (ch == ':') {
501+ styler.ColourTo(i - 1, state);
502+ if (chNext == ':') {
503+ // Mark "::" as an operator, not symbol start
504+ styler.ColourTo(i + 1, SCE_RB_OPERATOR);
505+ advance_char(i, ch, chNext, chNext2); // pass by ref
506+ state = SCE_RB_DEFAULT;
507+ preferRE = false;
508+ } else if (iswordchar(chNext)) {
509+ state = SCE_RB_SYMBOL;
510+ } else if (strchr("[*!~+-*/%=<>&^|", chNext)) {
511+ // Do the operator analysis in-line, looking ahead
512+ // Based on the table in pickaxe 2nd ed., page 339
513+ bool doColoring = true;
514+ switch (chNext) {
515+ case '[':
516+ if (chNext2 == ']' ) {
517+ char ch_tmp = styler.SafeGetCharAt(i + 3);
518+ if (ch_tmp == '=') {
519+ i += 3;
520+ ch = ch_tmp;
521+ chNext = styler.SafeGetCharAt(i + 1);
522+ } else {
523+ i += 2;
524+ ch = chNext2;
525+ chNext = ch_tmp;
526+ }
527+ } else {
528+ doColoring = false;
529+ }
530+ break;
531+
532+ case '*':
533+ if (chNext2 == '*') {
534+ i += 2;
535+ ch = chNext2;
536+ chNext = styler.SafeGetCharAt(i + 1);
537+ } else {
538+ advance_char(i, ch, chNext, chNext2);
539+ }
540+ break;
541+
542+ case '!':
543+ if (chNext2 == '=' || chNext2 == '~') {
544+ i += 2;
545+ ch = chNext2;
546+ chNext = styler.SafeGetCharAt(i + 1);
547+ } else {
548+ advance_char(i, ch, chNext, chNext2);
549+ }
550+ break;
551+
552+ case '<':
553+ if (chNext2 == '<') {
554+ i += 2;
555+ ch = chNext2;
556+ chNext = styler.SafeGetCharAt(i + 1);
557+ } else if (chNext2 == '=') {
558+ char ch_tmp = styler.SafeGetCharAt(i + 3);
559+ if (ch_tmp == '>') { // <=> operator
560+ i += 3;
561+ ch = ch_tmp;
562+ chNext = styler.SafeGetCharAt(i + 1);
563+ } else {
564+ i += 2;
565+ ch = chNext2;
566+ chNext = ch_tmp;
567+ }
568+ } else {
569+ advance_char(i, ch, chNext, chNext2);
570+ }
571+ break;
572+
573+ default:
574+ // Simple one-character operators
575+ advance_char(i, ch, chNext, chNext2);
576+ break;
577+ }
578+ if (doColoring) {
579+ styler.ColourTo(i, SCE_RB_SYMBOL);
580+ state = SCE_RB_DEFAULT;
581+ }
582+ } else if (!preferRE) {
583+ // Don't color symbol strings (yet)
584+ // Just color the ":" and color rest as string
585+ styler.ColourTo(i, SCE_RB_SYMBOL);
586+ state = SCE_RB_DEFAULT;
587+ } else {
588+ styler.ColourTo(i, SCE_RB_OPERATOR);
589+ state = SCE_RB_DEFAULT;
590+ preferRE = true;
591+ }
592+ } else if (ch == '%') {
593+ styler.ColourTo(i - 1, state);
594+ bool have_string = false;
595+ if (strchr(q_chars, chNext) && !iswordchar(chNext2)) {
596+ Quote.New();
597+ const char *hit = strchr(q_chars, chNext);
598+ if (hit != NULL) {
599+ state = q_states[hit - q_chars];
600+ Quote.Open(chNext2);
601+ i += 2;
602+ ch = chNext2;
243603 chNext = styler.SafeGetCharAt(i + 1);
604+ have_string = true;
605+ }
606+ } else if (!iswordchar(chNext)) {
607+ state = SCE_RB_STRING_QQ;
608+ Quote.Open(chNext);
609+ advance_char(i, ch, chNext, chNext2); // pass by ref
610+ have_string = true;
611+ }
612+ if (!have_string) {
613+ styler.ColourTo(i, SCE_RB_OPERATOR);
614+ // stay in default
615+ preferRE = true;
616+ }
617+ } else if (isoperator(ch)) {
618+ styler.ColourTo(i - 1, state);
619+ styler.ColourTo(i, SCE_RB_OPERATOR);
620+ // If we're ending an expression or block,
621+ // assume it ends an object, and the ambivalent
622+ // constructs are binary operators
623+ //
624+ // So if we don't have one of these chars,
625+ // we aren't ending an object exp'n, and ops
626+ // like : << / are unary operators.
627+
628+ preferRE = (strchr(")}]", ch) == NULL);
629+ // Stay in default state
630+ } else if (isEOLChar(ch)) {
631+ // Make sure it's a true line-end, with no backslash
632+ if ((ch == '\r' || (ch == '\n' && chPrev != '\r'))
633+ && chPrev != '\\') {
634+ // Assume we've hit the end of the statement.
635+ preferRE = true;
636+ }
637+ }
638+ } else if (state == SCE_RB_WORD) {
639+ if (ch == '.' || !iswordchar(ch)) {
640+ // Words include x? in all contexts,
641+ // and <letters>= after either 'def' or a dot
642+ // Move along until a complete word is on our left
643+
644+ // Default accessor treats '.' as word-chars,
645+ // but we don't for now.
646+
647+ if (ch == '='
648+ && iswordchar(chPrev)
649+ && (chNext == '('
650+ || strchr(" \t\n\r", chNext) != NULL)
651+ && (!strcmp(prevWord, "def")
652+ || followsDot(styler.GetStartSegment(), styler))) {
653+ // <name>= is a name only when being def'd -- Get it the next time
654+ // This means that <name>=<name> is always lexed as
655+ // <name>, (op, =), <name>
656+ } else if ((ch == '?' || ch == '!')
657+ && iswordchar(chPrev)
658+ && !iswordchar(chNext)) {
659+ // <name>? is a name -- Get it the next time
660+ // But <name>?<name> is always lexed as
661+ // <name>, (op, ?), <name>
662+ // Same with <name>! to indicate a method that
663+ // modifies its target
664+ } else if (isEOLChar(ch)
665+ && isMatch(styler, lengthDoc, i - 7, "__END__")) {
666+ styler.ColourTo(i, SCE_RB_DATASECTION);
667+ state = SCE_RB_DATASECTION;
668+ // No need to handle this state -- we'll just move to the end
669+ preferRE = false;
670+ } else {
671+ int wordStartPos = styler.GetStartSegment();
672+ int word_style = ClassifyWordRb(wordStartPos, i - 1, keywords, styler, prevWord);
673+ switch (word_style) {
674+ case SCE_RB_WORD:
675+ preferRE = RE_CanFollowKeyword(prevWord);
676+ break;
677+
678+ case SCE_RB_WORD_DEMOTED:
679+ preferRE = true;
680+ break;
681+
682+ case SCE_RB_IDENTIFIER:
683+ if (isMatch(styler, lengthDoc, wordStartPos, "print")) {
684+ preferRE = true;
685+ } else if (isEOLChar(ch)) {
686+ preferRE = true;
687+ } else {
688+ preferRE = false;
689+ }
690+ break;
691+ default:
692+ preferRE = false;
693+ }
694+ redo_char(i, ch, chNext, chNext2, state); // pass by ref
695+ }
696+ }
697+ } else if (state == SCE_RB_NUMBER) {
698+ if (isalnum(ch) || ch == '_') {
699+ // Keep going
700+ } else if (ch == '.' && ++numDots == 1) {
701+ // Keep going
702+ } else {
703+ styler.ColourTo(i - 1, state);
704+ redo_char(i, ch, chNext, chNext2, state); // pass by ref
705+ preferRE = false;
706+ }
707+ } else if (state == SCE_RB_COMMENTLINE) {
708+ if (isEOLChar(ch)) {
709+ styler.ColourTo(i - 1, state);
710+ state = SCE_RB_DEFAULT;
711+ // Use whatever setting we had going into the comment
712+ }
713+ } else if (state == SCE_RB_HERE_DELIM) {
714+ // See the comment for SCE_RB_HERE_DELIM in LexPerl.cxx
715+ // Slightly different: if we find an immediate '-',
716+ // the target can appear indented.
717+
718+ if (HereDoc.State == 0) { // '<<' encountered
719+ HereDoc.State = 1;
720+ HereDoc.DelimiterLength = 0;
721+ if (ch == '-') {
722+ HereDoc.CanBeIndented = true;
723+ advance_char(i, ch, chNext, chNext2); // pass by ref
724+ } else {
725+ HereDoc.CanBeIndented = false;
726+ }
727+ if (isEOLChar(ch)) {
728+ // Bail out of doing a here doc if there's no target
729+ state = SCE_RB_DEFAULT;
730+ preferRE = false;
731+ } else {
732+ HereDoc.Quote = ch;
733+
734+ if (ch == '\'' || ch == '"' || ch == '`') {
735+ HereDoc.Quoted = true;
736+ HereDoc.Delimiter[0] = '\0';
737+ } else {
738+ HereDoc.Quoted = false;
739+ HereDoc.Delimiter[0] = ch;
740+ HereDoc.Delimiter[1] = '\0';
741+ HereDoc.DelimiterLength = 1;
742+ }
743+ }
744+ } else if (HereDoc.State == 1) { // collect the delimiter
745+ if (isEOLChar(ch)) {
746+ // End the quote now, and go back for more
747+ styler.ColourTo(i - 1, state);
748+ state = SCE_RB_DEFAULT;
749+ i--;
750+ chNext = ch;
751+ chNext2 = chNext;
752+ preferRE = false;
753+ } else if (HereDoc.Quoted) {
754+ if (ch == HereDoc.Quote) { // closing quote => end of delimiter
755+ styler.ColourTo(i, state);
756+ state = SCE_RB_DEFAULT;
757+ preferRE = false;
758+ } else {
759+ if (ch == '\\' && !isEOLChar(chNext)) {
760+ advance_char(i, ch, chNext, chNext2);
761+ }
762+ HereDoc.Delimiter[HereDoc.DelimiterLength++] = ch;
763+ HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
764+ }
765+ } else { // an unquoted here-doc delimiter
766+ if (isalnum(ch) || ch == '_') {
767+ HereDoc.Delimiter[HereDoc.DelimiterLength++] = ch;
768+ HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
769+ } else {
770+ styler.ColourTo(i - 1, state);
771+ redo_char(i, ch, chNext, chNext2, state);
772+ preferRE = false;
244773 }
245- } else if (isoperator(ch)) {
246- styler.ColourTo(i, SCE_P_OPERATOR);
247- }
248- }
249- } else {
250- if (state == SCE_P_COMMENTLINE || state == SCE_P_COMMENTBLOCK) {
251- if (ch == '\r' || ch == '\n') {
774+ }
775+ if (HereDoc.DelimiterLength >= static_cast<int>(sizeof(HereDoc.Delimiter)) - 1) {
252776 styler.ColourTo(i - 1, state);
253- state = SCE_P_DEFAULT;
777+ state = SCE_RB_ERROR;
778+ preferRE = false;
254779 }
255- } else if (state == SCE_P_STRING) {
256- if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) {
257- styler.ColourTo(i - 1, state);
258- state = SCE_P_STRINGEOL;
259- } else if (ch == '\\') {
260- if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
261- i++;
780+ }
781+ } else if (state == SCE_RB_HERE_Q) {
782+ // Not needed: HereDoc.State == 2
783+ // Indentable here docs: look backwards
784+ // Non-indentable: look forwards, like in Perl
785+ //
786+ // Why: so we can quickly resolve things like <<-" abc"
787+
788+ if (!HereDoc.CanBeIndented) {
789+ if (isEOLChar(chPrev)
790+ && isMatch(styler, lengthDoc, i, HereDoc.Delimiter)) {
791+ styler.ColourTo(i - 1, state);
792+ i += HereDoc.DelimiterLength - 1;
793+ chNext = styler.SafeGetCharAt(i + 1);
794+ if (isEOLChar(chNext)) {
795+ styler.ColourTo(i, SCE_RB_HERE_DELIM);
796+ state = SCE_RB_DEFAULT;
797+ HereDoc.State = 0;
798+ preferRE = false;
799+ }
800+ // Otherwise we skipped through the here doc faster.
801+ }
802+ } else if (isEOLChar(chNext)
803+ && lookingAtHereDocDelim(styler,
804+ i - HereDoc.DelimiterLength + 1,
805+ lengthDoc,
806+ HereDoc.Delimiter)) {
807+ styler.ColourTo(i - 1 - HereDoc.DelimiterLength, state);
808+ styler.ColourTo(i, SCE_RB_HERE_DELIM);
809+ state = SCE_RB_DEFAULT;
810+ preferRE = false;
811+ HereDoc.State = 0;
812+ }
813+ } else if (state == SCE_RB_CLASS_VAR
814+ || state == SCE_RB_INSTANCE_VAR
815+ || state == SCE_RB_SYMBOL) {
816+ if (!iswordchar(ch)) {
817+ styler.ColourTo(i - 1, state);
818+ redo_char(i, ch, chNext, chNext2, state); // pass by ref
819+ preferRE = false;
820+ }
821+ } else if (state == SCE_RB_GLOBAL) {
822+ if (!iswordchar(ch)) {
823+ // handle special globals here as well
824+ if (chPrev == '$') {
825+ if (ch == '-') {
826+ // Include the next char, like $-a
827+ advance_char(i, ch, chNext, chNext2);
828+ }
829+ styler.ColourTo(i, state);
830+ state = SCE_RB_DEFAULT;
831+ } else {
832+ styler.ColourTo(i - 1, state);
833+ redo_char(i, ch, chNext, chNext2, state); // pass by ref
834+ }
835+ preferRE = false;
836+ }
837+ } else if (state == SCE_RB_POD) {
838+ // PODs end with ^=end\s, -- any whitespace can follow =end
839+ if (strchr(" \t\n\r", ch) != NULL
840+ && i > 5
841+ && isEOLChar(styler[i - 5])
842+ && isMatch(styler, lengthDoc, i - 4, "=end")) {
843+ styler.ColourTo(i - 1, state);
844+ state = SCE_RB_DEFAULT;
845+ preferRE = false;
846+ }
847+ } else if (state == SCE_RB_REGEX || state == SCE_RB_STRING_QR) {
848+ if (ch == '\\' && Quote.Up != '\\') {
849+ // Skip one
850+ advance_char(i, ch, chNext, chNext2);
851+ } else if (ch == Quote.Down) {
852+ Quote.Count--;
853+ if (Quote.Count == 0) {
854+ // Include the options
855+ while (isSafeAlpha(chNext)) {
856+ i++;
262857 ch = chNext;
263- chNext = styler.SafeGetCharAt(i + 1);
264- }
265- } else if (ch == '\"') {
266- styler.ColourTo(i, state);
267- state = SCE_P_DEFAULT;
268- }
269- } else if (state == SCE_P_CHARACTER) {
270- if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) {
271- styler.ColourTo(i - 1, state);
272- state = SCE_P_STRINGEOL;
273- } else if (ch == '\\') {
274- if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
275- i++;
276- ch = chNext;
277- chNext = styler.SafeGetCharAt(i + 1);
278- }
279- } else if (ch == '\'') {
280- styler.ColourTo(i, state);
281- state = SCE_P_DEFAULT;
282- }
283- } else if (state == SCE_P_TRIPLE) {
284- if (ch == '\'' && chPrev == '\'' && chPrev2 == '\'') {
285- styler.ColourTo(i, state);
286- state = SCE_P_DEFAULT;
287- }
288- } else if (state == SCE_P_TRIPLEDOUBLE) {
289- // =end terminates the comment block
290- if (ch == 'd' && chPrev == 'n' && chPrev2 == 'e') {
291- if (styler.SafeGetCharAt(i - 3) == '=') {
292- styler.ColourTo(i, state);
293- state = SCE_P_DEFAULT;
294- }
295- }
858+ chNext = styler.SafeGetCharAt(i + 1);
859+ }
860+ styler.ColourTo(i, state);
861+ state = SCE_RB_DEFAULT;
862+ preferRE = false;
863+ }
864+ } else if (ch == Quote.Up) {
865+ // Only if close quoter != open quoter
866+ Quote.Count++;
867+
868+ } else if (ch == '#' ) {
869+ //todo: distinguish comments from pound chars
870+ // for now, handle as comment
871+ styler.ColourTo(i - 1, state);
872+ bool inEscape = false;
873+ while (++i < lengthDoc) {
874+ ch = styler.SafeGetCharAt(i);
875+ if (ch == '\\') {
876+ inEscape = true;
877+ } else if (isEOLChar(ch)) {
878+ // Comment inside a regex
879+ styler.ColourTo(i - 1, SCE_RB_COMMENTLINE);
880+ break;
881+ } else if (inEscape) {
882+ inEscape = false; // don't look at char
883+ } else if (ch == Quote.Down) {
884+ // Have the regular handler deal with this
885+ // to get trailing modifiers.
886+ i--;
887+ ch = styler[i];
888+ break;
889+ }
890+ }
891+ chNext = styler.SafeGetCharAt(i + 1);
892+ chNext2 = styler.SafeGetCharAt(i + 2);
893+ }
894+ // Quotes of all kinds...
895+ } else if (state == SCE_RB_STRING_Q || state == SCE_RB_STRING_QQ ||
896+ state == SCE_RB_STRING_QX || state == SCE_RB_STRING_QW ||
897+ state == SCE_RB_STRING || state == SCE_RB_CHARACTER ||
898+ state == SCE_RB_BACKTICKS) {
899+ if (!Quote.Down && !isspacechar(ch)) {
900+ Quote.Open(ch);
901+ } else if (ch == '\\' && Quote.Up != '\\') {
902+ //Riddle me this: Is it safe to skip *every* escaped char?
903+ advance_char(i, ch, chNext, chNext2);
904+ } else if (ch == Quote.Down) {
905+ Quote.Count--;
906+ if (Quote.Count == 0) {
907+ styler.ColourTo(i, state);
908+ state = SCE_RB_DEFAULT;
909+ preferRE = false;
910+ }
911+ } else if (ch == Quote.Up) {
912+ Quote.Count++;
913+ }
914+ }
915+
916+ if (state == SCE_RB_ERROR) {
917+ break;
918+ }
919+ chPrev = ch;
920+ }
921+ if (state == SCE_RB_WORD) {
922+ // We've ended on a word, possibly at EOF, and need to
923+ // classify it.
924+ (void) ClassifyWordRb(styler.GetStartSegment(), lengthDoc - 1, keywords, styler, prevWord);
925+ } else {
926+ styler.ColourTo(lengthDoc - 1, state);
927+ }
928+}
929+
930+// Helper functions for folding
931+
932+static void getPrevWord(int pos,
933+ char *prevWord,
934+ Accessor &styler,
935+ int word_state)
936+{
937+ int i;
938+ styler.Flush();
939+ for (i = pos - 1; i > 0; i--) {
940+ if (actual_style(styler.StyleAt(i)) != word_state) {
941+ i++;
942+ break;
943+ }
944+ }
945+ if (i < pos - MAX_KEYWORD_LENGTH) // overflow
946+ i = pos - MAX_KEYWORD_LENGTH;
947+ char *dst = prevWord;
948+ for (; i <= pos; i++) {
949+ *dst++ = styler[i];
950+ }
951+ *dst = 0;
952+}
953+
954+static bool keywordIsAmbiguous(const char *prevWord)
955+{
956+ // Order from most likely used to least likely
957+ // Lots of ways to do a loop in Ruby besides 'while/until'
958+ if (!strcmp(prevWord, "if")
959+ || !strcmp(prevWord, "do")
960+ || !strcmp(prevWord, "while")
961+ || !strcmp(prevWord, "unless")
962+ || !strcmp(prevWord, "until")) {
963+ return true;
964+ } else {
965+ return false;
966+ }
967+}
968+
969+static bool inline iswhitespace(char ch) {
970+ return ch == ' ' || ch == '\t';
971+}
972+
973+// Demote keywords in the following conditions:
974+// if, while, unless, until modify a statement
975+// do after a while or until, as a noise word (like then after if)
976+
977+static bool keywordIsModifier(const char *word,
978+ int pos,
979+ Accessor &styler)
980+{
981+ if (word[0] == 'd' && word[1] == 'o' && !word[2]) {
982+ return keywordDoStartsLoop(pos, styler);
983+ }
984+ char ch;
985+ int style = SCE_RB_DEFAULT;
986+ int lineStart = styler.GetLine(pos);
987+ int lineStartPosn = styler.LineStart(lineStart);
988+ styler.Flush();
989+ while (--pos >= lineStartPosn) {
990+ style = actual_style(styler.StyleAt(pos));
991+ if (style == SCE_RB_DEFAULT) {
992+ if (iswhitespace(ch = styler[pos])) {
993+ //continue
994+ } else if (ch == '\r' || ch == '\n') {
995+ // Scintilla's LineStart() and GetLine() routines aren't
996+ // platform-independent, so if we have text prepared with
997+ // a different system we can't rely on it.
998+ return false;
296999 }
1000+ } else {
1001+ break;
2971002 }
298- chPrev2 = chPrev;
299- chPrev = ch;
300- }
301- if (state == SCE_P_WORD) {
302- ClassifyWordRb(styler.GetStartSegment(), lengthDoc-1, keywords, styler, prevWord);
303- } else {
304- styler.ColourTo(lengthDoc-1, state);
305- }
1003+ }
1004+ if (pos < lineStartPosn) {
1005+ return false; //XXX not quite right if the prev line is a continuation
1006+ }
1007+ // First things where the action is unambiguous
1008+ switch (style) {
1009+ case SCE_RB_DEFAULT:
1010+ case SCE_RB_COMMENTLINE:
1011+ case SCE_RB_POD:
1012+ case SCE_RB_CLASSNAME:
1013+ case SCE_RB_DEFNAME:
1014+ case SCE_RB_MODULE_NAME:
1015+ return false;
1016+ case SCE_RB_OPERATOR:
1017+ break;
1018+ case SCE_RB_WORD:
1019+ // Watch out for uses of 'else if'
1020+ //XXX: Make a list of other keywords where 'if' isn't a modifier
1021+ // and can appear legitimately
1022+ // Formulate this to avoid warnings from most compilers
1023+ if (strcmp(word, "if") == 0) {
1024+ char prevWord[MAX_KEYWORD_LENGTH + 1];
1025+ getPrevWord(pos, prevWord, styler, SCE_RB_WORD);
1026+ return strcmp(prevWord, "else") != 0;
1027+ }
1028+ return true;
1029+ default:
1030+ return true;
1031+ }
1032+ // Assume that if the keyword follows an operator,
1033+ // usually it's a block assignment, like
1034+ // a << if x then y else z
1035+
1036+ ch = styler[pos];
1037+ switch (ch) {
1038+ case ')':
1039+ case ']':
1040+ case '}':
1041+ return true;
1042+ default:
1043+ return false;
1044+ }
3061045 }
3071046
1047+#define WHILE_BACKWARDS "elihw"
1048+#define UNTIL_BACKWARDS "litnu"
1049+
1050+// Nothing fancy -- look to see if we follow a while/until somewhere
1051+// on the current line
1052+
1053+static bool keywordDoStartsLoop(int pos,
1054+ Accessor &styler)
1055+{
1056+ char ch;
1057+ int style;
1058+ int lineStart = styler.GetLine(pos);
1059+ int lineStartPosn = styler.LineStart(lineStart);
1060+ styler.Flush();
1061+ while (--pos >= lineStartPosn) {
1062+ style = actual_style(styler.StyleAt(pos));
1063+ if (style == SCE_RB_DEFAULT) {
1064+ if ((ch = styler[pos]) == '\r' || ch == '\n') {
1065+ // Scintilla's LineStart() and GetLine() routines aren't
1066+ // platform-independent, so if we have text prepared with
1067+ // a different system we can't rely on it.
1068+ return false;
1069+ }
1070+ } else if (style == SCE_RB_WORD) {
1071+ // Check for while or until, but write the word in backwards
1072+ char prevWord[MAX_KEYWORD_LENGTH + 1]; // 1 byte for zero
1073+ char *dst = prevWord;
1074+ int wordLen = 0;
1075+ int start_word;
1076+ for (start_word = pos;
1077+ start_word >= lineStartPosn && actual_style(styler.StyleAt(start_word)) == SCE_RB_WORD;
1078+ start_word--) {
1079+ if (++wordLen < MAX_KEYWORD_LENGTH) {
1080+ *dst++ = styler[start_word];
1081+ }
1082+ }
1083+ *dst = 0;
1084+ // Did we see our keyword?
1085+ if (!strcmp(prevWord, WHILE_BACKWARDS)
1086+ || !strcmp(prevWord, UNTIL_BACKWARDS)) {
1087+ return true;
1088+ }
1089+ // We can move pos to the beginning of the keyword, and then
1090+ // accept another decrement, as we can never have two contiguous
1091+ // keywords:
1092+ // word1 word2
1093+ // ^
1094+ // <- move to start_word
1095+ // ^
1096+ // <- loop decrement
1097+ // ^ # pointing to end of word1 is fine
1098+ pos = start_word;
1099+ }
1100+ }
1101+ return false;
1102+}
1103+
1104+/*
1105+ * Folding Ruby
1106+ *
1107+ * The language is quite complex to analyze without a full parse.
1108+ * For example, this line shouldn't affect fold level:
1109+ *
1110+ * print "hello" if feeling_friendly?
1111+ *
1112+ * Neither should this:
1113+ *
1114+ * print "hello" \
1115+ * if feeling_friendly?
1116+ *
1117+ *
1118+ * But this should:
1119+ *
1120+ * if feeling_friendly? #++
1121+ * print "hello" \
1122+ * print "goodbye"
1123+ * end #--
1124+ *
1125+ * So we cheat, by actually looking at the existing indentation
1126+ * levels for each line, and just echoing it back. Like Python.
1127+ * Then if we get better at it, we'll take braces into consideration,
1128+ * which always affect folding levels.
1129+
1130+ * How the keywords should work:
1131+ * No effect:
1132+ * __FILE__ __LINE__ BEGIN END alias and
1133+ * defined? false in nil not or self super then
1134+ * true undef
1135+
1136+ * Always increment:
1137+ * begin class def do for module when {
1138+ *
1139+ * Always decrement:
1140+ * end }
1141+ *
1142+ * Increment if these start a statement
1143+ * if unless until while -- do nothing if they're modifiers
1144+
1145+ * These end a block if there's no modifier, but don't bother
1146+ * break next redo retry return yield
1147+ *
1148+ * These temporarily de-indent, but re-indent
1149+ * case else elsif ensure rescue
1150+ *
1151+ * This means that the folder reflects indentation rather
1152+ * than setting it. The language-service updates indentation
1153+ * when users type return and finishes entering de-denters.
1154+ *
1155+ * Later offer to fold POD, here-docs, strings, and blocks of comments
1156+ */
1157+
3081158 static void FoldRbDoc(unsigned int startPos, int length, int initStyle,
309- WordList *[], Accessor &styler) {
310- int lengthDoc = startPos + length;
311-
312- // Backtrack to previous line in case need to fix its fold status
1159+ WordList *[], Accessor &styler) {
1160+ const bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
1161+ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
1162+
1163+ synchronizeDocStart(startPos, length, initStyle, styler, // ref args
1164+ false);
1165+ unsigned int endPos = startPos + length;
1166+ int visibleChars = 0;
3131167 int lineCurrent = styler.GetLine(startPos);
314- if (startPos > 0) {
315- if (lineCurrent > 0) {
316- lineCurrent--;
317- startPos = styler.LineStart(lineCurrent);
318- if (startPos == 0)
319- initStyle = SCE_P_DEFAULT;
320- else
321- initStyle = styler.StyleAt(startPos-1);
322- }
323- }
324- int state = initStyle & 31;
325- int spaceFlags = 0;
326- int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsRbComment);
327- if ((state == SCE_P_TRIPLE) || (state == SCE_P_TRIPLEDOUBLE))
328- indentCurrent |= SC_FOLDLEVELWHITEFLAG;
1168+ int levelPrev = startPos == 0 ? 0 : (styler.LevelAt(lineCurrent)
1169+ & SC_FOLDLEVELNUMBERMASK
1170+ & ~SC_FOLDLEVELBASE);
1171+ int levelCurrent = levelPrev;
3291172 char chNext = styler[startPos];
330- for (int i = startPos; i < lengthDoc; i++) {
1173+ int styleNext = styler.StyleAt(startPos);
1174+ int stylePrev = startPos <= 1 ? SCE_RB_DEFAULT : styler.StyleAt(startPos - 1);
1175+ bool buffer_ends_with_eol = false;
1176+ for (unsigned int i = startPos; i < endPos; i++) {
3311177 char ch = chNext;
3321178 chNext = styler.SafeGetCharAt(i + 1);
333- int style = styler.StyleAt(i) & 31;
334-
335- if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == lengthDoc)) {
336- int lev = indentCurrent;
337- int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsRbComment);
338- if ((style == SCE_P_TRIPLE) || (style== SCE_P_TRIPLEDOUBLE))
339- indentNext |= SC_FOLDLEVELWHITEFLAG;
340- if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
341- // Only non whitespace lines can be headers
342- if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
343- lev |= SC_FOLDLEVELHEADERFLAG;
344- } else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
345- // Line after is blank so check the next - maybe should continue further?
346- int spaceFlags2 = 0;
347- int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsRbComment);
348- if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
349- lev |= SC_FOLDLEVELHEADERFLAG;
350- }
1179+ int style = styleNext;
1180+ styleNext = styler.StyleAt(i + 1);
1181+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
1182+ if (style == SCE_RB_COMMENTLINE) {
1183+ if (foldComment && stylePrev != SCE_RB_COMMENTLINE) {
1184+ if (chNext == '{') {
1185+ levelCurrent++;
1186+ } else if (chNext == '}') {
1187+ levelCurrent--;
3511188 }
1189+ }
1190+ } else if (style == SCE_RB_OPERATOR) {
1191+ if (strchr("[{(", ch)) {
1192+ levelCurrent++;
1193+ } else if (strchr(")}]", ch)) {
1194+ // Don't decrement below 0
1195+ if (levelCurrent > 0)
1196+ levelCurrent--;
3521197 }
353- indentCurrent = indentNext;
354- styler.SetLevel(lineCurrent, lev);
1198+ } else if (style == SCE_RB_WORD && styleNext != SCE_RB_WORD) {
1199+ // Look at the keyword on the left and decide what to do
1200+ char prevWord[MAX_KEYWORD_LENGTH + 1]; // 1 byte for zero
1201+ prevWord[0] = 0;
1202+ getPrevWord(i, prevWord, styler, SCE_RB_WORD);
1203+ if (!strcmp(prevWord, "end")) {
1204+ // Don't decrement below 0
1205+ if (levelCurrent > 0)
1206+ levelCurrent--;
1207+ } else if ( !strcmp(prevWord, "if")
1208+ || !strcmp(prevWord, "def")
1209+ || !strcmp(prevWord, "class")
1210+ || !strcmp(prevWord, "module")
1211+ || !strcmp(prevWord, "begin")
1212+ || !strcmp(prevWord, "case")
1213+ || !strcmp(prevWord, "do")
1214+ || !strcmp(prevWord, "while")
1215+ || !strcmp(prevWord, "unless")
1216+ || !strcmp(prevWord, "until")
1217+ || !strcmp(prevWord, "for")
1218+ ) {
1219+ levelCurrent++;
1220+ }
1221+ }
1222+ if (atEOL) {
1223+ int lev = levelPrev;
1224+ if (visibleChars == 0 && foldCompact)
1225+ lev |= SC_FOLDLEVELWHITEFLAG;
1226+ if ((levelCurrent > levelPrev) && (visibleChars > 0))
1227+ lev |= SC_FOLDLEVELHEADERFLAG;
1228+ styler.SetLevel(lineCurrent, lev|SC_FOLDLEVELBASE);
3551229 lineCurrent++;
356- }
357- }
1230+ levelPrev = levelCurrent;
1231+ visibleChars = 0;
1232+ buffer_ends_with_eol = true;
1233+ } else if (!isspacechar(ch)) {
1234+ visibleChars++;
1235+ buffer_ends_with_eol = false;
1236+ }
1237+ }
1238+ // Fill in the real level of the next line, keeping the current flags as they will be filled in later
1239+ if (!buffer_ends_with_eol) {
1240+ lineCurrent++;
1241+ int new_lev = levelCurrent;
1242+ if (visibleChars == 0 && foldCompact)
1243+ new_lev |= SC_FOLDLEVELWHITEFLAG;
1244+ if ((levelCurrent > levelPrev) && (visibleChars > 0))
1245+ new_lev |= SC_FOLDLEVELHEADERFLAG;
1246+ levelCurrent = new_lev;
1247+ }
1248+ styler.SetLevel(lineCurrent, levelCurrent|SC_FOLDLEVELBASE);
3581249 }
3591250
3601251 static const char * const rubyWordListDesc[] = {
--- trunk/src/Utils/scintilla/src/LexTADS3.cxx (revision 4272)
+++ trunk/src/Utils/scintilla/src/LexTADS3.cxx (revision 4273)
@@ -31,19 +31,6 @@
3131 * These embedded constructs influence the output and formatting and are an
3232 * important part of a program and require highlighting.
3333 *
34- * Because strings, html tags, library directives, message parameters, and
35- * interpolated expressions may span multiple lines it is necessary to have
36- * multiple states for a single construct so that the surrounding context can be
37- * known. This is important if scanning starts part way through a source file.
38- *
39- * States that have a Single quoted string context have _S_ in the name
40- * States that have a Double quoted string context have _D_ in the name
41- * States that have an interpolated eXpression context have _X_ in the name
42- * eg SCE_T3_X_S_MSG_PARAM is a message parameter in a single quoted string
43- * that is part of an interpolated expression.
44- * "You see << isKnown? '{iobj/him} lying' : 'nothing' >> on the ground. "
45- * ----------
46- *
4734 * LINKS
4835 * http://www.tads.org/
4936 */
@@ -63,10 +50,11 @@
6350 #include "Scintilla.h"
6451 #include "SciLexer.h"
6552
66-static unsigned int endPos;
53+static const int T3_SINGLE_QUOTE = 1;
54+static const int T3_INT_EXPRESSION = 2;
6755
68-static inline bool IsEOL(const int ch) {
69- return ch == '\r' || ch == '\n';
56+static inline bool IsEOL(const int ch, const int chNext) {
57+ return (ch == '\r' && chNext != '\n') || (ch == '\n');
7058 }
7159
7260 static inline bool IsASpaceOrTab(const int ch) {
@@ -74,13 +62,15 @@
7462 }
7563
7664 static inline bool IsATADS3Operator(const int ch) {
77- return ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '|'
78- || ch == '!' || ch == ':' || ch == '?' || ch == '@' || ch == ';'
79- || ch == '&' || ch == '<' || ch == '>' || ch == '=';
65+ return ch == '=' || ch == '{' || ch == '}' || ch == '(' || ch == ')'
66+ || ch == '[' || ch == ']' || ch == ',' || ch == ':' || ch == ';'
67+ || ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '%'
68+ || ch == '?' || ch == '!' || ch == '<' || ch == '>' || ch == '|'
69+ || ch == '@' || ch == '&' || ch == '~';
8070 }
8171
8272 static inline bool IsAWordChar(const int ch) {
83- return isalnum(ch) || ch == '_';
73+ return isalnum(ch) || ch == '_' || ch == '.';
8474 }
8575
8676 static inline bool IsAWordStart(const int ch) {
@@ -93,11 +83,6 @@
9383 || lch == 'd' || lch == 'e' || lch == 'f';
9484 }
9585
96-static inline bool IsABracket(const int ch) {
97- return ch == '{' || ch == '[' || ch == '('
98- || ch == '}' || ch == ']' || ch == ')';
99-}
100-
10186 static inline bool IsAnHTMLChar(int ch) {
10287 return isalnum(ch) || ch == '-' || ch == '_' || ch == '.';
10388 }
@@ -117,31 +102,44 @@
117102 sc.ForwardSetState(initState);
118103 }
119104
120-inline static void ColouriseTADS3Bracket(StyleContext &sc) {
121- int initState = sc.state;
122- sc.SetState(SCE_T3_BRACKET);
123- sc.ForwardSetState(initState);
124-}
125-
126-static void ColouriseTADSHTMLString(StyleContext &sc) {
127- int initState = sc.state;
105+static void ColouriseTADSHTMLString(StyleContext &sc, int &lineState) {
106+ int endState = sc.state;
128107 int chQuote = sc.ch;
108+ if (endState == SCE_T3_HTML_STRING) {
109+ if (lineState&T3_SINGLE_QUOTE) {
110+ endState = SCE_T3_S_STRING;
111+ chQuote = '"';
112+ } else if (lineState&T3_INT_EXPRESSION) {
113+ endState = SCE_T3_X_STRING;
114+ chQuote = '\'';
115+ } else {
116+ endState = SCE_T3_D_STRING;
117+ chQuote = '\'';
118+ }
119+ } else {
120+ sc.SetState(SCE_T3_HTML_STRING);
121+ sc.Forward();
122+ }
129123 int chString = chQuote == '"'? '\'': '"';
130- sc.SetState(SCE_T3_HTML_STRING);
131- sc.Forward();
132124
133125 while (sc.More()) {
126+ if (IsEOL(sc.ch, sc.chNext)) {
127+ return;
128+ }
129+ if (sc.ch == chQuote) {
130+ sc.ForwardSetState(endState);
131+ return;
132+ }
133+ if (sc.ch == chString) {
134+ sc.SetState(endState);
135+ return;
136+ }
134137 if (sc.Match('\\', static_cast<char>(chQuote))
135138 || sc.Match('\\', static_cast<char>(chString))) {
136139 sc.Forward(2);
137- } else if (sc.ch == chQuote || IsEOL(sc.ch)) {
138- sc.ForwardSetState(initState);
139- return;
140- } else if (sc.ch == chString) {
141- sc.SetState(initState);
142- return;
140+ } else {
141+ sc.Forward();
143142 }
144- sc.Forward();
145143 }
146144 }
147145
@@ -156,65 +154,56 @@
156154 }
157155 }
158156
159-static void ColouriseTADS3HTMLTag(StyleContext &sc) {
160- int initState = sc.state;
161- int chQuote = '\'';
162- int chString = '"';
163- switch (initState) {
157+static void ColouriseTADS3HTMLTag(StyleContext &sc, int &lineState) {
158+ int endState = sc.state;
159+ int chQuote = '"';
160+ int chString = '\'';
161+ switch (endState) {
164162 case SCE_T3_S_STRING:
165163 ColouriseTADS3HTMLTagStart(sc);
166- sc.SetState(SCE_T3_S_H_DEFAULT);
164+ sc.SetState(SCE_T3_HTML_DEFAULT);
165+ chQuote = '\'';
166+ chString = '"';
167167 break;
168168 case SCE_T3_D_STRING:
169+ case SCE_T3_X_STRING:
169170 ColouriseTADS3HTMLTagStart(sc);
170- sc.SetState(SCE_T3_S_H_DEFAULT);
171- chQuote = '"';
172- chString = '\'';
171+ sc.SetState(SCE_T3_HTML_DEFAULT);
173172 break;
174- case SCE_T3_X_S_STRING:
175- ColouriseTADS3HTMLTagStart(sc);
176- sc.SetState(SCE_T3_X_S_H_DEFAULT);
173+ case SCE_T3_HTML_DEFAULT:
174+ if (lineState&T3_SINGLE_QUOTE) {
175+ endState = SCE_T3_S_STRING;
176+ chQuote = '\'';
177+ chString = '"';
178+ } else if (lineState&T3_INT_EXPRESSION) {
179+ endState = SCE_T3_X_STRING;
180+ } else {
181+ endState = SCE_T3_D_STRING;
182+ }
177183 break;
178- case SCE_T3_X_D_STRING:
179- ColouriseTADS3HTMLTagStart(sc);
180- sc.SetState(SCE_T3_X_D_H_DEFAULT);
181- chQuote = '"';
182- chString = '\'';
183- break;
184- case SCE_T3_S_H_DEFAULT:
185- initState = SCE_T3_S_STRING;
186- break;
187- case SCE_T3_D_H_DEFAULT:
188- initState = SCE_T3_D_STRING;
189- chQuote = '"';
190- chString = '\'';
191- break;
192- case SCE_T3_X_S_H_DEFAULT:
193- initState = SCE_T3_X_S_STRING;
194- break;
195- case SCE_T3_X_D_H_DEFAULT:
196- initState = SCE_T3_X_D_STRING;
197- chQuote = '"';
198- chString = '\'';
199- break;
200184 }
201185
202186 while (sc.More()) {
187+ if (IsEOL(sc.ch, sc.chNext)) {
188+ return;
189+ }
203190 if (sc.Match('/', '>')) {
204191 sc.SetState(SCE_T3_HTML_TAG);
205192 sc.Forward(2);
206- sc.SetState(initState);
193+ sc.SetState(endState);
207194 return;
208- } else if (sc.ch == '>') {
195+ }
196+ if (sc.ch == '>') {
209197 sc.SetState(SCE_T3_HTML_TAG);
210- sc.ForwardSetState(initState);
198+ sc.ForwardSetState(endState);
211199 return;
212- } else if (sc.ch == chQuote) {
213- sc.SetState(initState);
200+ }
201+ if (sc.ch == chQuote) {
202+ sc.SetState(endState);
214203 return;
215204 }
216205 if (sc.ch == chString) {
217- ColouriseTADSHTMLString(sc);
206+ ColouriseTADSHTMLString(sc, lineState);
218207 } else if (sc.ch == '=') {
219208 ColouriseTADS3Operator(sc);
220209 } else {
@@ -224,24 +213,19 @@
224213 }
225214
226215 static void ColouriseTADS3Keyword(StyleContext &sc,
227- WordList *keywordlists[]) {
228- static char s[250];
216+ WordList *keywordlists[], unsigned int endPos) {
217+ char s[250];
229218 WordList &keywords = *keywordlists[0];
230219 WordList &userwords1 = *keywordlists[1];
231220 WordList &userwords2 = *keywordlists[2];
221+ WordList &userwords3 = *keywordlists[3];
232222 int initState = sc.state;
233- sc.SetState(SCE_T3_KEYWORD);
234- while (sc.More() && (IsAWordChar(sc.ch) || sc.ch == '.')) {
223+ sc.SetState(SCE_T3_IDENTIFIER);
224+ while (sc.More() && (IsAWordChar(sc.ch))) {
235225 sc.Forward();
236226 }
237227 sc.GetCurrent(s, sizeof(s));
238- if (userwords1.InList(s)) {
239- sc.ChangeState(SCE_T3_USER1);
240- } else if (userwords2.InList(s)) {
241- sc.ChangeState(SCE_T3_USER2);
242- } else if (keywords.InList(s)) {
243- // state already correct
244- } else if ( strcmp(s, "is") == 0 || strcmp(s, "not") == 0) {
228+ if ( strcmp(s, "is") == 0 || strcmp(s, "not") == 0) {
245229 // have to find if "in" is next
246230 int n = 1;
247231 while (n + sc.currentPos < endPos && IsASpaceOrTab(sc.GetRelative(n)))
@@ -248,54 +232,49 @@
248232 n++;
249233 if (sc.GetRelative(n) == 'i' && sc.GetRelative(n+1) == 'n') {
250234 sc.Forward(n+2);
251- } else {
252- sc.ChangeState(initState);
235+ sc.ChangeState(SCE_T3_KEYWORD);
253236 }
254- } else {
255- sc.ChangeState(initState);
237+ } else if (keywords.InList(s)) {
238+ sc.ChangeState(SCE_T3_KEYWORD);
239+ } else if (userwords3.InList(s)) {
240+ sc.ChangeState(SCE_T3_USER3);
241+ } else if (userwords2.InList(s)) {
242+ sc.ChangeState(SCE_T3_USER2);
243+ } else if (userwords1.InList(s)) {
244+ sc.ChangeState(SCE_T3_USER1);
256245 }
257-
258246 sc.SetState(initState);
259247 }
260248
261-static void ColouriseTADS3MsgParam(StyleContext &sc) {
262- int initState = sc.state;
249+static void ColouriseTADS3MsgParam(StyleContext &sc, int &lineState) {
250+ int endState = sc.state;
263251 int chQuote = '"';
264- switch (initState) {
252+ switch (endState) {
265253 case SCE_T3_S_STRING:
266- sc.SetState(SCE_T3_S_MSG_PARAM);
254+ sc.SetState(SCE_T3_MSG_PARAM);
267255 sc.Forward();
268256 chQuote = '\'';
269257 break;
270258 case SCE_T3_D_STRING:
271- sc.SetState(SCE_T3_D_MSG_PARAM);
259+ case SCE_T3_X_STRING:
260+ sc.SetState(SCE_T3_MSG_PARAM);
272261 sc.Forward();
273262 break;
274- case SCE_T3_X_S_STRING:
275- sc.SetState(SCE_T3_X_S_MSG_PARAM);
276- sc.Forward();
277- chQuote = '\'';
263+ case SCE_T3_MSG_PARAM:
264+ if (lineState&T3_SINGLE_QUOTE) {
265+ endState = SCE_T3_S_STRING;
266+ chQuote = '\'';
267+ } else if (lineState&T3_INT_EXPRESSION) {
268+ endState = SCE_T3_X_STRING;
269+ } else {
270+ endState = SCE_T3_D_STRING;
271+ }
278272 break;
279- case SCE_T3_X_D_STRING:
280- sc.SetState(SCE_T3_X_D_MSG_PARAM);
281- sc.Forward();
282- break;
283- case SCE_T3_S_MSG_PARAM:
284- initState = SCE_T3_S_STRING;
285- chQuote = '\'';
286- break;
287- case SCE_T3_D_MSG_PARAM:
288- initState = SCE_T3_D_STRING;
289- break;
290- case SCE_T3_X_S_MSG_PARAM:
291- initState = SCE_T3_X_S_STRING;
292- chQuote = '\'';
293- break;
294- case SCE_T3_X_D_MSG_PARAM:
295- initState = SCE_T3_X_D_STRING;
296- break;
297273 }
298274 while (sc.More() && sc.ch != '}' && sc.ch != chQuote) {
275+ if (IsEOL(sc.ch, sc.chNext)) {
276+ return;
277+ }
299278 if (sc.ch == '\\') {
300279 sc.Forward();
301280 }
@@ -302,50 +281,38 @@
302281 sc.Forward();
303282 }
304283 if (sc.ch == chQuote) {
305- sc.SetState(initState);
284+ sc.SetState(endState);
306285 } else {
307- sc.ForwardSetState(initState);
286+ sc.ForwardSetState(endState);
308287 }
309288 }
310289
311-static void ColouriseTADS3LibDirective(StyleContext &sc) {
290+static void ColouriseTADS3LibDirective(StyleContext &sc, int &lineState) {
312291 int initState = sc.state;
313292 int chQuote = '"';
314293 switch (initState) {
315294 case SCE_T3_S_STRING:
316- sc.SetState(SCE_T3_S_LIB_DIRECTIVE);
295+ sc.SetState(SCE_T3_LIB_DIRECTIVE);
317296 sc.Forward(2);
318297 chQuote = '\'';
319298 break;
320299 case SCE_T3_D_STRING:
321- sc.SetState(SCE_T3_D_LIB_DIRECTIVE);
300+ sc.SetState(SCE_T3_LIB_DIRECTIVE);
322301 sc.Forward(2);
323302 break;
324- case SCE_T3_X_S_STRING:
325- sc.SetState(SCE_T3_X_S_LIB_DIRECTIVE);
326- sc.Forward(2);
327- chQuote = '\'';
303+ case SCE_T3_LIB_DIRECTIVE:
304+ if (lineState&T3_SINGLE_QUOTE) {
305+ initState = SCE_T3_S_STRING;
306+ chQuote = '\'';
307+ } else {
308+ initState = SCE_T3_D_STRING;
309+ }
328310 break;
329- case SCE_T3_X_D_STRING:
330- sc.SetState(SCE_T3_X_D_LIB_DIRECTIVE);
331- sc.Forward(2);
332- break;
333- case SCE_T3_S_LIB_DIRECTIVE:
334- initState = SCE_T3_S_STRING;
335- chQuote = '\'';
336- break;
337- case SCE_T3_D_LIB_DIRECTIVE:
338- initState = SCE_T3_D_STRING;
339- break;
340- case SCE_T3_X_S_LIB_DIRECTIVE:
341- initState = SCE_T3_X_S_STRING;
342- chQuote = '\'';
343- break;
344- case SCE_T3_X_D_LIB_DIRECTIVE:
345- initState = SCE_T3_X_D_STRING;
346- break;
347311 }
348312 while (sc.More() && IsADirectiveChar(sc.ch)) {
313+ if (IsEOL(sc.ch, sc.chNext)) {
314+ return;
315+ }
349316 sc.Forward();
350317 };
351318 if (sc.ch == '>' || !sc.More()) {
@@ -358,61 +325,61 @@
358325 }
359326 }
360327
361-static void ColouriseTADS3String(StyleContext &sc) {
328+static void ColouriseTADS3String(StyleContext &sc, int &lineState) {
362329 int chQuote = sc.ch;
363- int initState = sc.state;
330+ int endState = sc.state;
364331 switch (sc.state) {
365332 case SCE_T3_DEFAULT:
333+ case SCE_T3_X_DEFAULT:
366334 if (chQuote == '"') {
367- sc.SetState(SCE_T3_D_STRING);
335+ if (sc.state == SCE_T3_DEFAULT) {
336+ sc.SetState(SCE_T3_D_STRING);
337+ } else {
338+ sc.SetState(SCE_T3_X_STRING);
339+ }
340+ lineState &= ~T3_SINGLE_QUOTE;
368341 } else {
369342 sc.SetState(SCE_T3_S_STRING);
343+ lineState |= T3_SINGLE_QUOTE;
370344 }
371345 sc.Forward();
372346 break;
373- case SCE_T3_X_DEFAULT:
374- if (chQuote == '"') {
375- sc.SetState(SCE_T3_X_D_STRING);
376- } else {
377- sc.SetState(SCE_T3_X_S_STRING);
378- }
379- sc.Forward();
380- break;
381347 case SCE_T3_S_STRING:
382348 chQuote = '\'';
383- initState = SCE_T3_DEFAULT;
349+ endState = lineState&T3_INT_EXPRESSION ?
350+ SCE_T3_X_DEFAULT : SCE_T3_DEFAULT;
384351 break;
385352 case SCE_T3_D_STRING:
386353 chQuote = '"';
387- initState = SCE_T3_DEFAULT;
354+ endState = SCE_T3_DEFAULT;
388355 break;
389- case SCE_T3_X_S_STRING:
390- chQuote = '\'';
391- initState = SCE_T3_X_DEFAULT;
392- break;
393- case SCE_T3_X_D_STRING:
356+ case SCE_T3_X_STRING:
394357 chQuote = '"';
395- initState = SCE_T3_X_DEFAULT;
358+ endState = SCE_T3_X_DEFAULT;
396359 break;
397360 }
398361 while (sc.More()) {
399- if (sc.Match('\\', static_cast<char>(chQuote))) {
400- sc.Forward(2);
362+ if (IsEOL(sc.ch, sc.chNext)) {
363+ return;
401364 }
402365 if (sc.ch == chQuote) {
403- sc.ForwardSetState(initState);
366+ sc.ForwardSetState(endState);
404367 return;
405368 }
406- if (sc.ch == '{') {
407- ColouriseTADS3MsgParam(sc);
408- } else if (sc.state == SCE_T3_D_STRING && sc.Match('<', '<')) {
369+ if (sc.state == SCE_T3_D_STRING && sc.Match('<', '<')) {
370+ lineState |= T3_INT_EXPRESSION;
409371 sc.SetState(SCE_T3_X_DEFAULT);
410372 sc.Forward(2);
411373 return;
374+ }
375+ if (sc.Match('\\', static_cast<char>(chQuote))) {
376+ sc.Forward(2);
377+ } else if (sc.ch == '{') {
378+ ColouriseTADS3MsgParam(sc, lineState);
412379 } else if (sc.Match('<', '.')) {
413- ColouriseTADS3LibDirective(sc);
380+ ColouriseTADS3LibDirective(sc, lineState);
414381 } else if (sc.ch == '<') {
415- ColouriseTADS3HTMLTag(sc);
382+ ColouriseTADS3HTMLTag(sc, lineState);
416383 } else {
417384 sc.Forward();
418385 }
@@ -419,44 +386,40 @@
419386 }
420387 }
421388
422-static void ColouriseTADS3Comment(StyleContext &sc, const int initState,
423- const int endState) {
424- if (sc.state != initState) {
425- sc.SetState(initState);
426- }
427- for (; sc.More(); sc.Forward()) {
389+static void ColouriseTADS3Comment(StyleContext &sc, int endState) {
390+ sc.SetState(SCE_T3_BLOCK_COMMENT);
391+ while (sc.More()) {
392+ if (IsEOL(sc.ch, sc.chNext)) {
393+ return;
394+ }
428395 if (sc.Match('*', '/')) {
429396 sc.Forward(2);
430397 sc.SetState(endState);
431398 return;
432399 }
400+ sc.Forward();
433401 }
434402 }
435403
436-static void ColouriseToEndOfLine(StyleContext &sc, const int initState,
437- const int endState) {
438- if (sc.state != initState) {
439- sc.SetState(initState);
440- }
441- for (; sc.More(); sc.Forward()) {
404+static void ColouriseToEndOfLine(StyleContext &sc, int initState, int endState) {
405+ sc.SetState(initState);
406+ while (sc.More()) {
442407 if (sc.ch == '\\') {
443- if (IsEOL(sc.chNext)) {
444- sc.Forward();
445- if (sc.ch == '\r' && sc.chNext == '\n') {
446- sc.Forward();
447- }
448- continue;
408+ sc.Forward();
409+ if (IsEOL(sc.ch, sc.chNext)) {
410+ return;
449411 }
450412 }
451- if (IsEOL(sc.ch)) {
413+ if (IsEOL(sc.ch, sc.chNext)) {
452414 sc.SetState(endState);
453415 return;
454416 }
417+ sc.Forward();
455418 }
456419 }
457420
458421 static void ColouriseTADS3Number(StyleContext &sc) {
459- int initState = sc.state;
422+ int endState = sc.state;
460423 bool inHexNumber = false;
461424 bool seenE = false;
462425 bool seenDot = sc.ch == '.';
@@ -468,7 +431,7 @@
468431 inHexNumber = true;
469432 sc.Forward();
470433 }
471- for (; sc.More(); sc.Forward()) {
434+ while (sc.More()) {
472435 if (inHexNumber) {
473436 if (!IsAHexDigit(sc.ch)) {
474437 break;
@@ -486,8 +449,9 @@
486449 break;
487450 }
488451 }
452+ sc.Forward();
489453 }
490- sc.SetState(initState);
454+ sc.SetState(endState);
491455 }
492456
493457 static void ColouriseTADS3Doc(unsigned int startPos, int length, int initStyle,
@@ -494,120 +458,97 @@
494458 WordList *keywordlists[], Accessor &styler) {
495459 int visibleChars = 0;
496460 int bracketLevel = 0;
497- endPos = startPos + length;
461+ int lineState = 0;
462+ unsigned int endPos = startPos + length;
463+ int lineCurrent = styler.GetLine(startPos);
464+ if (lineCurrent > 0) {
465+ lineState = styler.GetLineState(lineCurrent-1);
466+ }
498467 StyleContext sc(startPos, length, initStyle, styler);
499468
500469 while (sc.More()) {
501470
502- if (IsEOL(sc.ch)) {
471+ if (IsEOL(sc.ch, sc.chNext)) {
472+ styler.SetLineState(lineCurrent, lineState);
473+ lineCurrent++;
503474 visibleChars = 0;
504475 sc.Forward();
505- continue;
476+ if (sc.ch == '\n') {
477+ sc.Forward();
478+ }
506479 }
507480
508481 switch(sc.state) {
509482 case SCE_T3_PREPROCESSOR:
510483 case SCE_T3_LINE_COMMENT:
511- ColouriseToEndOfLine(sc, sc.state, SCE_T3_DEFAULT);
484+ ColouriseToEndOfLine(sc, sc.state, lineState&T3_INT_EXPRESSION ?
485+ SCE_T3_X_DEFAULT : SCE_T3_DEFAULT);
512486 break;
513- case SCE_T3_X_PREPROCESSOR:
514- case SCE_T3_X_LINE_COMMENT:
515- ColouriseToEndOfLine(sc, sc.state, SCE_T3_X_DEFAULT);
516- break;
517487 case SCE_T3_S_STRING:
518488 case SCE_T3_D_STRING:
519- case SCE_T3_X_S_STRING:
520- case SCE_T3_X_D_STRING:
521- ColouriseTADS3String(sc);
489+ case SCE_T3_X_STRING:
490+ ColouriseTADS3String(sc, lineState);
522491 visibleChars++;
523492 break;
524- case SCE_T3_S_MSG_PARAM:
525- case SCE_T3_D_MSG_PARAM:
526- case SCE_T3_X_S_MSG_PARAM:
527- case SCE_T3_X_D_MSG_PARAM:
528- ColouriseTADS3MsgParam(sc);
493+ case SCE_T3_MSG_PARAM:
494+ ColouriseTADS3MsgParam(sc, lineState);
529495 break;
530- case SCE_T3_S_LIB_DIRECTIVE:
531- case SCE_T3_D_LIB_DIRECTIVE:
532- case SCE_T3_X_S_LIB_DIRECTIVE:
533- case SCE_T3_X_D_LIB_DIRECTIVE:
534- ColouriseTADS3LibDirective(sc);
496+ case SCE_T3_LIB_DIRECTIVE:
497+ ColouriseTADS3LibDirective(sc, lineState);
535498 break;
536- case SCE_T3_S_H_DEFAULT:
537- case SCE_T3_D_H_DEFAULT:
538- case SCE_T3_X_S_H_DEFAULT:
539- case SCE_T3_X_D_H_DEFAULT:
540- ColouriseTADS3HTMLTag(sc);
499+ case SCE_T3_HTML_DEFAULT:
500+ ColouriseTADS3HTMLTag(sc, lineState);
541501 break;
502+ case SCE_T3_HTML_STRING:
503+ ColouriseTADSHTMLString(sc, lineState);
504+ break;
542505 case SCE_T3_BLOCK_COMMENT:
543- ColouriseTADS3Comment(sc, SCE_T3_BLOCK_COMMENT, SCE_T3_DEFAULT);
506+ ColouriseTADS3Comment(sc, lineState&T3_INT_EXPRESSION ?
507+ SCE_T3_X_DEFAULT : SCE_T3_DEFAULT);
544508 break;
545- case SCE_T3_X_BLOCK_COMMENT:
546- ColouriseTADS3Comment(sc, SCE_T3_X_BLOCK_COMMENT, SCE_T3_X_DEFAULT);
547- break;
548509 case SCE_T3_DEFAULT:
510+ case SCE_T3_X_DEFAULT:
549511 if (IsASpaceOrTab(sc.ch)) {
550512 sc.Forward();
551513 } else if (sc.ch == '#' && visibleChars == 0) {
552- ColouriseToEndOfLine(sc, SCE_T3_PREPROCESSOR, SCE_T3_DEFAULT);
514+ ColouriseToEndOfLine(sc, SCE_T3_PREPROCESSOR, sc.state);
553515 } else if (sc.Match('/', '*')) {
554- ColouriseTADS3Comment(sc, SCE_T3_BLOCK_COMMENT, SCE_T3_DEFAULT);
516+ ColouriseTADS3Comment(sc, sc.state);
555517 visibleChars++;
556518 } else if (sc.Match('/', '/')) {
557- ColouriseToEndOfLine(sc, SCE_T3_LINE_COMMENT, SCE_T3_DEFAULT);
558- } else if (sc.ch == '\'' || sc.ch == '"') {
559- ColouriseTADS3String(sc);
519+ ColouriseToEndOfLine(sc, SCE_T3_LINE_COMMENT, sc.state);
520+ } else if (sc.ch == '"') {
521+ bracketLevel = 0;
522+ ColouriseTADS3String(sc, lineState);
560523 visibleChars++;
561- } else if (IsATADS3Operator(sc.ch)) {
562- ColouriseTADS3Operator(sc);
524+ } else if (sc.ch == '\'') {
525+ ColouriseTADS3String(sc, lineState);
563526 visibleChars++;
564- } else if (IsANumberStart(sc)) {
565- ColouriseTADS3Number(sc);
566- visibleChars++;
567- } else if (IsABracket(sc.ch)) {
568- ColouriseTADS3Bracket(sc);
569- visibleChars++;
570- } else if (IsAWordStart(sc.ch)) {
571- ColouriseTADS3Keyword(sc, keywordlists);
572- visibleChars++;
573- } else {
574- sc.Forward();
575- visibleChars++;
576- }
577- break;
578- case SCE_T3_X_DEFAULT:
579- if (IsASpaceOrTab(sc.ch)) {
580- sc.Forward();
581- } else if (sc.ch == '#' && visibleChars == 0) {
582- ColouriseToEndOfLine(sc, SCE_T3_X_PREPROCESSOR, SCE_T3_X_DEFAULT);
583- } else if (sc.Match('/', '*')) {
584- ColouriseTADS3Comment(sc, SCE_T3_X_BLOCK_COMMENT, SCE_T3_X_DEFAULT);
585- visibleChars++;
586- } else if (sc.Match('/', '/')) {
587- ColouriseToEndOfLine(sc, SCE_T3_X_LINE_COMMENT, SCE_T3_X_DEFAULT);
588- } else if (sc.ch == '\'' || sc.ch == '"') {
589- ColouriseTADS3String(sc);
590- visibleChars++;
591- } else if (bracketLevel == 0 && sc.Match('>', '>')) {
527+ } else if (sc.state == SCE_T3_X_DEFAULT && bracketLevel == 0
528+ && sc.Match('>', '>')) {
592529 sc.Forward(2);
593530 sc.SetState(SCE_T3_D_STRING);
531+ lineState &= ~(T3_SINGLE_QUOTE|T3_INT_EXPRESSION);
594532 } else if (IsATADS3Operator(sc.ch)) {
533+ if (sc.state == SCE_T3_X_DEFAULT) {
534+ if (sc.ch == '(') {
535+ bracketLevel++;
536+ } else if (sc.ch == ')') {
537+ bracketLevel--;
538+ }
539+ }
595540 ColouriseTADS3Operator(sc);
596541 visibleChars++;
597542 } else if (IsANumberStart(sc)) {
598543 ColouriseTADS3Number(sc);
599544 visibleChars++;
600- } else if (IsABracket(sc.ch)) {
601- if (sc.ch == '(') {
602- bracketLevel++;
603- } else if (sc.ch == ')') {
604- bracketLevel && bracketLevel--;
605- }
606- ColouriseTADS3Bracket(sc);
607- visibleChars++;
608545 } else if (IsAWordStart(sc.ch)) {
609- ColouriseTADS3Keyword(sc, keywordlists);
546+ ColouriseTADS3Keyword(sc, keywordlists, endPos);
610547 visibleChars++;
548+ } else if (sc.Match("...")) {
549+ sc.SetState(SCE_T3_IDENTIFIER);
550+ sc.Forward(3);
551+ sc.SetState(SCE_T3_DEFAULT);
611552 } else {
612553 sc.Forward();
613554 visibleChars++;
@@ -633,7 +574,7 @@
633574
634575 silverKey : Key {
635576 'small silver key'
636- 'small silver key'
577+ 'small silver key'
637578 "A small key glints in the sunlight. "
638579 }
639580
@@ -672,41 +613,14 @@
672613 static const int T3_EXPECTINGIDENTIFIER = 1 << 13;
673614 static const int T3_EXPECTINGPUNCTUATION = 1 << 14;
674615
675-static inline bool IsStreamCommentStyle(int style) {
676- return style == SCE_T3_BLOCK_COMMENT
677- || style == SCE_T3_X_BLOCK_COMMENT;
678-}
679-
680616 static inline bool IsStringTransition(int s1, int s2) {
681- switch (s1) {
682- case SCE_T3_S_STRING:
683- return s2 != s1
684- && s2 != SCE_T3_S_LIB_DIRECTIVE
685- && s2 != SCE_T3_S_MSG_PARAM
686- && s2 != SCE_T3_HTML_TAG
687- && s2 != SCE_T3_HTML_STRING;
688- case SCE_T3_D_STRING:
689- return s2 != s1
690- && s2 != SCE_T3_D_LIB_DIRECTIVE
691- && s2 != SCE_T3_D_MSG_PARAM
692- && s2 != SCE_T3_HTML_TAG
693- && s2 != SCE_T3_X_DEFAULT
694- && s2 != SCE_T3_HTML_STRING;
695- case SCE_T3_X_S_STRING:
696- return s2 != s1
697- && s2 != SCE_T3_X_S_LIB_DIRECTIVE
698- && s2 != SCE_T3_X_S_MSG_PARAM
699- && s2 != SCE_T3_HTML_TAG
700- && s2 != SCE_T3_HTML_STRING;
701- case SCE_T3_X_D_STRING:
702- return s2 != s1
703- && s2 != SCE_T3_X_D_LIB_DIRECTIVE
704- && s2 != SCE_T3_X_D_MSG_PARAM
705- && s2 != SCE_T3_HTML_TAG
706- && s2 != SCE_T3_HTML_STRING;
707- default:
708- return false;
709- }
617+ return s1 != s2
618+ && (s1 == SCE_T3_S_STRING || s1 == SCE_T3_X_STRING
619+ || s1 == SCE_T3_D_STRING && s2 != SCE_T3_X_DEFAULT)
620+ && s2 != SCE_T3_LIB_DIRECTIVE
621+ && s2 != SCE_T3_MSG_PARAM
622+ && s2 != SCE_T3_HTML_TAG
623+ && s2 != SCE_T3_HTML_STRING;
710624 }
711625
712626 static inline bool IsATADS3Punctuation(const int ch) {
@@ -713,11 +627,11 @@
713627 return ch == ':' || ch == ',' || ch == '(' || ch == ')';
714628 }
715629
716-static inline bool IsAnIdentifier(const int ch, const int style) {
717- return IsAWordChar(ch) && style == SCE_T3_DEFAULT
630+static inline bool IsAnIdentifier(const int style) {
631+ return style == SCE_T3_IDENTIFIER
718632 || style == SCE_T3_USER1
719633 || style == SCE_T3_USER2
720- || ch == '.' && style == SCE_T3_DEFAULT;
634+ || style == SCE_T3_USER3;
721635 }
722636
723637 static inline bool IsSpaceEquivalent(const int ch, const int style) {
@@ -733,7 +647,7 @@
733647 int style = styler.StyleAt(i);
734648 char ch = styler[i];
735649 if (!IsSpaceEquivalent(ch, style)) {
736- if (IsAnIdentifier(ch, style)) {
650+ if (IsAnIdentifier(style)) {
737651 return 'a';
738652 }
739653 if (IsATADS3Punctuation(ch)) {
@@ -778,7 +692,7 @@
778692 style = styleNext;
779693 styleNext = styler.StyleAt(i + 1);
780694 }
781- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
695+ bool atEOL = IsEOL(ch, chNext);
782696
783697 if (levelNext == SC_FOLDLEVELBASE) {
784698 if (IsSpaceEquivalent(ch, style)) {
@@ -793,7 +707,9 @@
793707 seenStart = 0;
794708 } else if (ch == '\'' || ch == '"' || ch == '[') {
795709 levelNext++;
796- redo = true;
710+ if (seenStart) {
711+ redo = true;
712+ }
797713 } else if (ch == ';') {
798714 seenStart = 0;
799715 expectingIdentifier = 0;
@@ -805,11 +721,11 @@
805721 } else {
806722 expectingPunctuation = 0;
807723 }
808- } else if (!IsAnIdentifier(ch, style)) {
724+ } else if (!IsAnIdentifier(style)) {
809725 levelNext++;
810726 }
811727 } else if (expectingIdentifier && !expectingPunctuation) {
812- if (!IsAnIdentifier(ch, style)) {
728+ if (!IsAnIdentifier(style)) {
813729 levelNext++;
814730 } else {
815731 expectingPunctuation = T3_EXPECTINGPUNCTUATION;
@@ -826,7 +742,7 @@
826742 }
827743 }
828744 } else if (!expectingIdentifier && !expectingPunctuation) {
829- if (IsAnIdentifier(ch, style)) {
745+ if (IsAnIdentifier(style)) {
830746 seenStart = T3_SEENSTART;
831747 expectingIdentifier = T3_EXPECTINGIDENTIFIER;
832748 expectingPunctuation = T3_EXPECTINGPUNCTUATION;
@@ -842,10 +758,10 @@
842758 && ch == ';' && style == SCE_T3_OPERATOR ) {
843759 levelNext--;
844760 seenStart = 0;
845- } else if (IsStreamCommentStyle(style)) {
846- if (!IsStreamCommentStyle(stylePrev)) {
761+ } else if (style == SCE_T3_BLOCK_COMMENT) {
762+ if (stylePrev != SCE_T3_BLOCK_COMMENT) {
847763 levelNext++;
848- } else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
764+ } else if (styleNext != SCE_T3_BLOCK_COMMENT && !atEOL) {
849765 // Comments don't end at end of line and the next character may be unstyled.
850766 levelNext--;
851767 }
@@ -858,7 +774,7 @@
858774 } else if (IsStringTransition(style, styleNext)) {
859775 levelNext--;
860776 }
861- } else if (style == SCE_T3_BRACKET) {
777+ } else if (style == SCE_T3_OPERATOR) {
862778 if (ch == '{' || ch == '[') {
863779 // Measure the minimum before a '{' to allow
864780 // folding on "} else {"
@@ -913,6 +829,8 @@
913829 static const char * const tads3WordList[] = {
914830 "TADS3 Keywords",
915831 "User defined 1",
832+ "User defined 2",
833+ "User defined 3",
916834 0
917835 };
918836
--- trunk/src/Utils/scintilla/src/LexVB.cxx (revision 4272)
+++ trunk/src/Utils/scintilla/src/LexVB.cxx (revision 4273)
@@ -2,7 +2,7 @@
22 /** @file LexVB.cxx
33 ** Lexer for Visual Basic and VBScript.
44 **/
5-// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
5+// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
66 // The License.txt file describes the conditions under which this software may be distributed.
77
88 #include <stdlib.h>
@@ -20,8 +20,12 @@
2020 #include "Scintilla.h"
2121 #include "SciLexer.h"
2222
23+// Internal state, highlighted as number
24+#define SCE_B_FILENUMBER SCE_B_DEFAULT+100
25+
26+
2327 static bool IsVBComment(Accessor &styler, int pos, int len) {
24- return len>0 && styler[pos]=='\'';
28+ return len > 0 && styler[pos] == '\'';
2529 }
2630
2731 static inline bool IsTypeCharacter(int ch) {
@@ -36,12 +40,15 @@
3640
3741 static inline bool IsAWordStart(int ch) {
3842 return ch >= 0x80 ||
39- (isalnum(ch) || ch == '_');
43+ (isalpha(ch) || ch == '_');
4044 }
4145
42-static inline bool IsADateCharacter(const int ch) {
46+static inline bool IsANumberChar(int ch) {
47+ // Not exactly following number definition (several dots are seen as OK, etc.)
48+ // but probably enough in most cases.
4349 return (ch < 0x80) &&
44- (isalnum(ch) || ch == '|' || ch == '-' || ch == '/' || ch == ':' || ch == ' ' || ch == '\t');
50+ (isdigit(ch) || toupper(ch) == 'E' ||
51+ ch == '.' || ch == '-' || ch == '+');
4552 }
4653
4754 static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle,
@@ -55,7 +62,13 @@
5562 styler.StartAt(startPos);
5663
5764 int visibleChars = 0;
65+ int fileNbDigits = 0;
5866
67+ // Do not leak onto next line
68+ if (initStyle == SCE_B_STRINGEOL || initStyle == SCE_B_COMMENT || initStyle == SCE_B_PREPROCESSOR) {
69+ initStyle = SCE_B_DEFAULT;
70+ }
71+
5972 StyleContext sc(startPos, length, initStyle, styler);
6073
6174 for (; sc.More(); sc.Forward()) {
@@ -96,7 +109,9 @@
96109 }
97110 }
98111 } else if (sc.state == SCE_B_NUMBER) {
99- if (!IsAWordChar(sc.ch)) {
112+ // We stop the number definition on non-numerical non-dot non-eE non-sign char
113+ // Also accepts A-F for hex. numbers
114+ if (!IsANumberChar(sc.ch) && !(tolower(sc.ch) >= 'a' && tolower(sc.ch) <= 'f')) {
100115 sc.SetState(SCE_B_DEFAULT);
101116 }
102117 } else if (sc.state == SCE_B_STRING) {
@@ -113,15 +128,39 @@
113128 }
114129 } else if (sc.state == SCE_B_COMMENT) {
115130 if (sc.atLineEnd) {
116- sc.SetState(SCE_B_DEFAULT);
131+ sc.ForwardSetState(SCE_B_DEFAULT);
117132 }
118133 } else if (sc.state == SCE_B_PREPROCESSOR) {
119134 if (sc.atLineEnd) {
135+ sc.ForwardSetState(SCE_B_DEFAULT);
136+ }
137+ } else if (sc.state == SCE_B_FILENUMBER) {
138+ if (IsADigit(sc.ch)) {
139+ fileNbDigits++;
140+ if (fileNbDigits > 3) {
141+ sc.ChangeState(SCE_B_DATE);
142+ }
143+ } else if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ',') {
144+ // Regular uses: Close #1; Put #1, ...; Get #1, ... etc.
145+ // Too bad if date is format #27, Oct, 2003# or something like that...
146+ // Use regular number state
147+ sc.ChangeState(SCE_B_NUMBER);
120148 sc.SetState(SCE_B_DEFAULT);
149+ } else if (sc.ch == '#') {
150+ sc.ChangeState(SCE_B_DATE);
151+ sc.ForwardSetState(SCE_B_DEFAULT);
152+ } else {
153+ sc.ChangeState(SCE_B_DATE);
121154 }
155+ if (sc.state != SCE_B_FILENUMBER) {
156+ fileNbDigits = 0;
157+ }
122158 } else if (sc.state == SCE_B_DATE) {
123- if (sc.ch == '#' || !IsADateCharacter(sc.chNext)) {
159+ if (sc.atLineEnd) {
160+ sc.ChangeState(SCE_B_STRINGEOL);
124161 sc.ForwardSetState(SCE_B_DEFAULT);
162+ } else if (sc.ch == '#') {
163+ sc.ForwardSetState(SCE_B_DEFAULT);
125164 }
126165 }
127166
@@ -134,26 +173,24 @@
134173 // Preprocessor commands are alone on their line
135174 sc.SetState(SCE_B_PREPROCESSOR);
136175 } else if (sc.ch == '#') {
137- int n = 1;
138- int chSeek = ' ';
139- while ((n < 100) && (chSeek == ' ' || chSeek == '\t')) {
140- chSeek = sc.GetRelative(n);
141- n++;
142- }
143- if (IsADigit(chSeek)) {
144- sc.SetState(SCE_B_DATE);
145- } else {
146- sc.SetState(SCE_B_OPERATOR);
147- }
176+ // It can be a date literal, ending with #, or a file number, from 1 to 511
177+ // The date literal depends on the locale, so anything can go between #'s.
178+ // Can be #January 1, 1993# or #1 Jan 93# or #05/11/2003#, etc.
179+ // So we set the FILENUMBER state, and switch to DATE if it isn't a file number
180+ sc.SetState(SCE_B_FILENUMBER);
148181 } else if (sc.ch == '&' && tolower(sc.chNext) == 'h') {
182+ // Hexadecimal number
149183 sc.SetState(SCE_B_NUMBER);
184+ sc.Forward();
150185 } else if (sc.ch == '&' && tolower(sc.chNext) == 'o') {
186+ // Octal number
151187 sc.SetState(SCE_B_NUMBER);
188+ sc.Forward();
152189 } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
153190 sc.SetState(SCE_B_NUMBER);
154191 } else if (IsAWordStart(sc.ch) || (sc.ch == '[')) {
155192 sc.SetState(SCE_B_IDENTIFIER);
156- } else if (isoperator(static_cast<char>(sc.ch)) || (sc.ch == '\\')) {
193+ } else if (isoperator(static_cast<char>(sc.ch)) || (sc.ch == '\\')) { // Integer division
157194 sc.SetState(SCE_B_OPERATOR);
158195 }
159196 }
--- trunk/src/Utils/scintilla/src/PropSet.cxx (revision 4272)
+++ trunk/src/Utils/scintilla/src/PropSet.cxx (revision 4273)
@@ -329,6 +329,8 @@
329329
330330 // End SString functions
331331
332+bool PropSet::caseSensitiveFilenames = false;
333+
332334 PropSet::PropSet() {
333335 superPS = 0;
334336 for (int root = 0; root < hashRoots; root++)
@@ -536,16 +538,23 @@
536538 return true;
537539 }
538540
539-static bool IsSuffixCaseInsensitive(const char *target, const char *suffix) {
541+static bool IsSuffix(const char *target, const char *suffix, bool caseSensitive) {
540542 size_t lentarget = strlen(target);
541543 size_t lensuffix = strlen(suffix);
542544 if (lensuffix > lentarget)
543545 return false;
546+ if (caseSensitive) {
547+ for (int i = static_cast<int>(lensuffix) - 1; i >= 0; i--) {
548+ if (target[i + lentarget - lensuffix] != suffix[i])
549+ return false;
550+ }
551+ } else {
544552 for (int i = static_cast<int>(lensuffix) - 1; i >= 0; i--) {
545553 if (MakeUpperCase(target[i + lentarget - lensuffix]) !=
546554 MakeUpperCase(suffix[i]))
547555 return false;
548556 }
557+ }
549558 return true;
550559 }
551560
@@ -577,7 +586,7 @@
577586 char delchr = *del;
578587 *del = '\0';
579588 if (*keyfile == '*') {
580- if (IsSuffixCaseInsensitive(filename, keyfile + 1)) {
589+ if (IsSuffix(filename, keyfile + 1, caseSensitiveFilenames)) {
581590 *del = delchr;
582591 delete []keyptr;
583592 return p->val;
--- trunk/src/Utils/scintilla/src/RESearch.h (revision 4272)
+++ trunk/src/Utils/scintilla/src/RESearch.h (revision 4273)
@@ -20,6 +20,8 @@
2020 class CharacterIndexer {
2121 public:
2222 virtual char CharAt(int index)=0;
23+ virtual ~CharacterIndexer() {
24+ }
2325 };
2426
2527 class RESearch {
--- trunk/src/Utils/scintilla/src/ScintillaBase.cxx (revision 4272)
+++ trunk/src/Utils/scintilla/src/ScintillaBase.cxx (revision 4273)
@@ -41,6 +41,7 @@
4141 maxListWidth = 0;
4242 #ifdef SCI_LEXER
4343 lexLanguage = SCLEX_CONTAINER;
44+ performingStyle = false;
4445 lexCurrent = 0;
4546 for (int wl = 0;wl < numWordLists;wl++)
4647 keyWordLists[wl] = new WordList;
@@ -441,29 +442,38 @@
441442 }
442443
443444 void ScintillaBase::Colourise(int start, int end) {
444- int lengthDoc = pdoc->Length();
445- if (end == -1)
446- end = lengthDoc;
447- int len = end - start;
445+ if (!performingStyle) {
446+ // Protect against reentrance, which may occur, for example, when
447+ // fold points are discovered while performing styling and the folding
448+ // code looks for child lines which may trigger styling.
449+ performingStyle = true;
448450
449- PLATFORM_ASSERT(len >= 0);
450- PLATFORM_ASSERT(start + len <= lengthDoc);
451+ int lengthDoc = pdoc->Length();
452+ if (end == -1)
453+ end = lengthDoc;
454+ int len = end - start;
451455
452- //WindowAccessor styler(wMain.GetID(), props);
453- DocumentAccessor styler(pdoc, props, wMain.GetID());
456+ PLATFORM_ASSERT(len >= 0);
457+ PLATFORM_ASSERT(start + len <= lengthDoc);
454458
455- int styleStart = 0;
456- if (start > 0)
457- styleStart = styler.StyleAt(start - 1);
458- styler.SetCodePage(pdoc->dbcsCodePage);
459+ //WindowAccessor styler(wMain.GetID(), props);
460+ DocumentAccessor styler(pdoc, props, wMain.GetID());
459461
460- if (lexCurrent && (len > 0)) { // Should always succeed as null lexer should always be available
461- lexCurrent->Lex(start, len, styleStart, keyWordLists, styler);
462- styler.Flush();
463- if (styler.GetPropertyInt("fold")) {
464- lexCurrent->Fold(start, len, styleStart, keyWordLists, styler);
462+ int styleStart = 0;
463+ if (start > 0)
464+ styleStart = styler.StyleAt(start - 1);
465+ styler.SetCodePage(pdoc->dbcsCodePage);
466+
467+ if (lexCurrent && (len > 0)) { // Should always succeed as null lexer should always be available
468+ lexCurrent->Lex(start, len, styleStart, keyWordLists, styler);
465469 styler.Flush();
470+ if (styler.GetPropertyInt("fold")) {
471+ lexCurrent->Fold(start, len, styleStart, keyWordLists, styler);
472+ styler.Flush();
473+ }
466474 }
475+
476+ performingStyle = false;
467477 }
468478 }
469479 #endif
--- trunk/src/Utils/scintilla/src/ScintillaBase.h (revision 4272)
+++ trunk/src/Utils/scintilla/src/ScintillaBase.h (revision 4273)
@@ -40,6 +40,8 @@
4040 SString listSelected; ///< Receives listbox selected string
4141 int maxListWidth; /// Maximum width of list, in average character widths
4242
43+ bool performingStyle; ///< Prevent reentrance
44+
4345 #ifdef SCI_LEXER
4446 int lexLanguage;
4547 const LexerModule *lexCurrent;
--- trunk/src/Utils/scintilla/src/XPM.cxx (revision 4272)
+++ trunk/src/Utils/scintilla/src/XPM.cxx (revision 4273)
@@ -103,6 +103,11 @@
103103 height = atoi(line0);
104104 line0 = NextField(line0);
105105 nColours = atoi(line0);
106+ line0 = NextField(line0);
107+ if (atoi(line0) != 1) {
108+ // Only one char per pixel is supported
109+ return;
110+ }
106111 codes = new char[nColours];
107112 colours = new ColourPair[nColours];
108113
--- trunk/src/Utils/scintilla/version.txt (revision 4272)
+++ trunk/src/Utils/scintilla/version.txt (revision 4273)
@@ -1 +1 @@
1-164
1+166
--- trunk/src/Utils/scintilla/win32/PlatWin.cxx (revision 4272)
+++ trunk/src/Utils/scintilla/win32/PlatWin.cxx (revision 4273)
@@ -771,11 +771,21 @@
771771 RECT rcOther;
772772 ::GetWindowRect(reinterpret_cast<HWND>(w.GetID()), &rcOther);
773773 rc.Move(rcOther.left, rcOther.top);
774- if (rc.left < 0) {
775- rc.Move(-rc.left,0);
774+
775+ // Retrieve desktop bounds and make sure window popup's origin isn't left-top of the screen.
776+ RECT rcDesktop = {0, 0, 0, 0};
777+#ifdef SM_XVIRTUALSCREEN
778+ rcDesktop.left = ::GetSystemMetrics(SM_XVIRTUALSCREEN);
779+ rcDesktop.top = ::GetSystemMetrics(SM_YVIRTUALSCREEN);
780+ rcDesktop.right = rcDesktop.left + ::GetSystemMetrics(SM_CXVIRTUALSCREEN);
781+ rcDesktop.bottom = rcDesktop.top + ::GetSystemMetrics(SM_CYVIRTUALSCREEN);
782+#endif
783+
784+ if (rc.left < rcDesktop.left) {
785+ rc.Move(rcDesktop.left - rc.left,0);
776786 }
777- if (rc.top < 0) {
778- rc.Move(0,-rc.top);
787+ if (rc.top < rcDesktop.top) {
788+ rc.Move(0,rcDesktop.top - rc.top);
779789 }
780790 }
781791 SetPosition(rc);
@@ -1325,7 +1335,7 @@
13251335 int count = lti.Count();
13261336 ::SendMessage(lb, LB_INITSTORAGE, count, 0);
13271337 for (int j=0; j<count; j++) {
1328- ::SendMessage(lb, LB_ADDSTRING, 0, 0);
1338+ ::SendMessage(lb, LB_ADDSTRING, 0, j+1);
13291339 }
13301340 }
13311341 SetRedraw(true);
@@ -1355,7 +1365,10 @@
13551365 }
13561366
13571367 Point ListBoxX::MaxTrackSize() const {
1358- PRectangle rc(0, 0, maxCharWidth * maxItemCharacters, ItemHeight() * lti.Count());
1368+ PRectangle rc(0, 0,
1369+ maxCharWidth * maxItemCharacters + TextInset.x * 2 +
1370+ TextOffset() + ::GetSystemMetrics(SM_CXVSCROLL),
1371+ ItemHeight() * lti.Count());
13591372 AdjustWindowRect(&rc);
13601373 return Point(rc.Width(), rc.Height());
13611374 }
@@ -1531,7 +1544,7 @@
15311544 Point extent = GetClientExtent();
15321545 HBITMAP hBitmap = ::CreateCompatibleBitmap(hDC, extent.x, extent.y);
15331546 HDC bitmapDC = ::CreateCompatibleDC(hDC);
1534- SelectBitmap(bitmapDC, hBitmap);
1547+ HBITMAP hBitmapOld = SelectBitmap(bitmapDC, hBitmap);
15351548 // The list background is mainly erased during painting, but can be a small
15361549 // unpainted area when at the end of a non-integrally sized list with a
15371550 // vertical scroll bar
@@ -1540,6 +1553,9 @@
15401553 // Paint the entire client area and vertical scrollbar
15411554 ::SendMessage(lb, WM_PRINT, reinterpret_cast<WPARAM>(bitmapDC), PRF_CLIENT|PRF_NONCLIENT);
15421555 ::BitBlt(hDC, 0, 0, extent.x, extent.y, bitmapDC, 0, 0, SRCCOPY);
1556+ // Select a stock brush to prevent warnings from BoundsChecker
1557+ ::SelectObject(bitmapDC, GetStockFont(WHITE_BRUSH));
1558+ SelectBitmap(bitmapDC, hBitmapOld);
15431559 ::DeleteDC(bitmapDC);
15441560 ::DeleteObject(hBitmap);
15451561 }
--- trunk/src/Utils/scintilla/win32/ScintillaWin.cxx (revision 4272)
+++ trunk/src/Utils/scintilla/win32/ScintillaWin.cxx (revision 4273)
@@ -904,7 +904,7 @@
904904 }
905905 CharacterRange *pCR = reinterpret_cast<CharacterRange *>(lParam);
906906 selType = selStream;
907- if (pCR->cpMax == 0 && pCR->cpMax == -1) {
907+ if (pCR->cpMin == 0 && pCR->cpMax == -1) {
908908 SetSelection(pCR->cpMin, pdoc->Length());
909909 } else {
910910 SetSelection(pCR->cpMin, pCR->cpMax);
@@ -1832,6 +1832,8 @@
18321832 void ScintillaWin::RealizeWindowPalette(bool inBackGround) {
18331833 RefreshStyleData();
18341834 HDC hdc = ::GetDC(MainHWND());
1835+ // Select a stock font to prevent warnings from BoundsChecker
1836+ ::SelectObject(hdc, GetStockFont(DEFAULT_GUI_FONT));
18351837 AutoSurface surfaceWindow(hdc, this);
18361838 if (surfaceWindow) {
18371839 int changes = surfaceWindow->SetPalette(&palette, inBackGround);
Show on old repository browser