updated Scintilla to version 1.68
git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@246 ea778897-0a13-0410-b9d1-a72fbfd435f5
This commit is contained in:
parent
11675fac67
commit
92b433a90a
@ -13,6 +13,9 @@
|
||||
#include "Scintilla.h"
|
||||
#include "CallTip.h"
|
||||
|
||||
static const int insetX = 5; // text inset in x from calltip border
|
||||
static const int widthArrow = 14;
|
||||
|
||||
CallTip::CallTip() {
|
||||
wCallTip = 0;
|
||||
inCallTipMode = false;
|
||||
@ -23,6 +26,8 @@ CallTip::CallTip() {
|
||||
lineHeight = 1;
|
||||
startHighlight = 0;
|
||||
endHighlight = 0;
|
||||
tabSize = 0;
|
||||
useStyleCallTip = false; // for backwards compatibility
|
||||
|
||||
colourBG.desired = ColourDesired(0xff, 0xff, 0xff);
|
||||
colourUnSel.desired = ColourDesired(0x80, 0x80, 0x80);
|
||||
@ -38,8 +43,6 @@ CallTip::~CallTip() {
|
||||
val = 0;
|
||||
}
|
||||
|
||||
const int widthArrow = 14;
|
||||
|
||||
void CallTip::RefreshColourPalette(Palette &pal, bool want) {
|
||||
pal.WantFind(colourBG, want);
|
||||
pal.WantFind(colourUnSel, want);
|
||||
@ -48,19 +51,42 @@ void CallTip::RefreshColourPalette(Palette &pal, bool want) {
|
||||
pal.WantFind(colourLight, want);
|
||||
}
|
||||
|
||||
// Although this test includes 0, we should never see a \0 character.
|
||||
static bool IsArrowCharacter(char ch) {
|
||||
return (ch == 0) || (ch == '\001') || (ch == '\002');
|
||||
}
|
||||
|
||||
// We ignore tabs unless a tab width has been set.
|
||||
bool CallTip::IsTabCharacter(char ch) {
|
||||
return (tabSize > 0) && (ch == '\t');
|
||||
}
|
||||
|
||||
int CallTip::NextTabPos(int x) {
|
||||
if (tabSize > 0) { // paranoia... not called unless this is true
|
||||
x -= insetX; // position relative to text
|
||||
x = (x + tabSize) / tabSize; // tab "number"
|
||||
return tabSize*x + insetX; // position of next tab
|
||||
} else {
|
||||
return x + 1; // arbitrary
|
||||
}
|
||||
}
|
||||
|
||||
// Draw a section of the call tip that does not include \n in one colour.
|
||||
// The text may include up to numEnds tabs or arrow characters.
|
||||
void CallTip::DrawChunk(Surface *surface, int &x, const char *s,
|
||||
int posStart, int posEnd, int ytext, PRectangle rcClient,
|
||||
bool highlight, bool draw) {
|
||||
s += posStart;
|
||||
int len = posEnd - posStart;
|
||||
|
||||
// Divide the text into sections that are all text, or that are
|
||||
// single arrows or single tab characters (if tabSize > 0).
|
||||
int maxEnd = 0;
|
||||
int ends[10];
|
||||
const int numEnds = 10;
|
||||
int ends[numEnds + 2];
|
||||
for (int i=0;i<len;i++) {
|
||||
if (IsArrowCharacter(s[i])) {
|
||||
if ((maxEnd < numEnds) &&
|
||||
(IsArrowCharacter(s[i]) || IsTabCharacter(s[i])) ) {
|
||||
if (i > 0)
|
||||
ends[maxEnd++] = i;
|
||||
ends[maxEnd++] = i+1;
|
||||
@ -73,20 +99,19 @@ void CallTip::DrawChunk(Surface *surface, int &x, const char *s,
|
||||
int endSeg = ends[seg];
|
||||
if (endSeg > startSeg) {
|
||||
if (IsArrowCharacter(s[startSeg])) {
|
||||
xEnd = x + widthArrow;
|
||||
offsetMain = xEnd;
|
||||
bool upArrow = s[startSeg] == '\001';
|
||||
rcClient.left = x;
|
||||
rcClient.right = xEnd;
|
||||
rcClient.right = rcClient.left + widthArrow;
|
||||
if (draw) {
|
||||
const int halfWidth = widthArrow / 2 - 3;
|
||||
const int centreX = x + widthArrow / 2 - 1;
|
||||
const int centreX = rcClient.left + widthArrow / 2 - 1;
|
||||
const int centreY = (rcClient.top + rcClient.bottom) / 2;
|
||||
surface->FillRectangle(rcClient, colourBG.allocated);
|
||||
PRectangle rcClientInner(rcClient.left+1, rcClient.top+1, rcClient.right-2, rcClient.bottom-1);
|
||||
PRectangle rcClientInner(rcClient.left + 1, rcClient.top + 1,
|
||||
rcClient.right - 2, rcClient.bottom - 1);
|
||||
surface->FillRectangle(rcClientInner, colourUnSel.allocated);
|
||||
|
||||
if (s[startSeg] == '\001') {
|
||||
// Up arrow
|
||||
if (upArrow) { // Up arrow
|
||||
Point pts[] = {
|
||||
Point(centreX - halfWidth, centreY + halfWidth / 2),
|
||||
Point(centreX + halfWidth, centreY + halfWidth / 2),
|
||||
@ -94,8 +119,7 @@ void CallTip::DrawChunk(Surface *surface, int &x, const char *s,
|
||||
};
|
||||
surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
|
||||
colourBG.allocated, colourBG.allocated);
|
||||
} else {
|
||||
// Down arrow
|
||||
} else { // Down arrow
|
||||
Point pts[] = {
|
||||
Point(centreX - halfWidth, centreY - halfWidth / 2),
|
||||
Point(centreX + halfWidth, centreY - halfWidth / 2),
|
||||
@ -105,20 +129,23 @@ void CallTip::DrawChunk(Surface *surface, int &x, const char *s,
|
||||
colourBG.allocated, colourBG.allocated);
|
||||
}
|
||||
}
|
||||
if (s[startSeg] == '\001') {
|
||||
xEnd = rcClient.right;
|
||||
offsetMain = xEnd;
|
||||
if (upArrow) {
|
||||
rectUp = rcClient;
|
||||
} else if (s[startSeg] == '\002') {
|
||||
} else {
|
||||
rectDown = rcClient;
|
||||
}
|
||||
} else if (IsTabCharacter(s[startSeg])) {
|
||||
xEnd = NextTabPos(x);
|
||||
} else {
|
||||
xEnd = x + surface->WidthText(font, s+startSeg, endSeg - startSeg);
|
||||
xEnd = x + surface->WidthText(font, s + startSeg, endSeg - startSeg);
|
||||
if (draw) {
|
||||
rcClient.left = x;
|
||||
rcClient.right = xEnd;
|
||||
surface->DrawTextNoClip(rcClient, font, ytext,
|
||||
surface->DrawTextTransparent(rcClient, font, ytext,
|
||||
s+startSeg, endSeg - startSeg,
|
||||
highlight ? colourSel.allocated : colourUnSel.allocated,
|
||||
colourBG.allocated);
|
||||
highlight ? colourSel.allocated : colourUnSel.allocated);
|
||||
}
|
||||
}
|
||||
x = xEnd;
|
||||
@ -160,7 +187,7 @@ int CallTip::PaintContents(Surface *surfaceWindow, bool draw) {
|
||||
thisEndHighlight -= chunkOffset;
|
||||
rcClient.top = ytext - ascent - 1;
|
||||
|
||||
int x = 5;
|
||||
int x = insetX; // start each line at this inset
|
||||
|
||||
DrawChunk(surfaceWindow, x, chunkVal, 0, thisStartHighlight,
|
||||
ytext, rcClient, false, draw);
|
||||
@ -187,7 +214,7 @@ void CallTip::PaintCT(Surface *surfaceWindow) {
|
||||
|
||||
surfaceWindow->FillRectangle(rcClient, colourBG.allocated);
|
||||
|
||||
offsetMain = 5;
|
||||
offsetMain = insetX; // initial alignment assuming no arrows
|
||||
PaintContents(surfaceWindow, true);
|
||||
|
||||
// Draw a raised border around the edges of the window
|
||||
@ -238,14 +265,17 @@ PRectangle CallTip::CallTipStart(int pos, Point pt, const char *defn,
|
||||
const char *look = val;
|
||||
rectUp = PRectangle(0,0,0,0);
|
||||
rectDown = PRectangle(0,0,0,0);
|
||||
offsetMain = 5;
|
||||
int width = PaintContents(surfaceMeasure, false) + 5;
|
||||
offsetMain = insetX; // changed to right edge of any arrows
|
||||
int width = PaintContents(surfaceMeasure, false) + insetX;
|
||||
while ((newline = strchr(look, '\n')) != NULL) {
|
||||
look = newline + 1;
|
||||
numLines++;
|
||||
}
|
||||
lineHeight = surfaceMeasure->Height(font);
|
||||
// Extra line for border and an empty line at top and bottom
|
||||
|
||||
// Extra line for border and an empty line at top and bottom. The returned
|
||||
// rectangle is aligned to the right edge of the last arrow encountered in
|
||||
// the tip text, else to the tip text left edge.
|
||||
int height = lineHeight * numLines - surfaceMeasure->InternalLeading(font) + 2 + 2;
|
||||
delete surfaceMeasure;
|
||||
return PRectangle(pt.x - offsetMain, pt.y + 1, pt.x + width - offsetMain, pt.y + 1 + height);
|
||||
@ -268,3 +298,17 @@ void CallTip::SetHighlight(int start, int end) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set the tab size (sizes > 0 enable the use of tabs). This also enables the
|
||||
// use of the STYLE_CALLTIP.
|
||||
void CallTip::SetTabSize(int tabSz) {
|
||||
tabSize = tabSz;
|
||||
useStyleCallTip = true;
|
||||
}
|
||||
|
||||
// It might be better to have two access functions for this and to use
|
||||
// them for all settings of colours.
|
||||
void CallTip::SetForeBack(const ColourPair &fore, const ColourPair &back) {
|
||||
colourBG = back;
|
||||
colourUnSel = fore;
|
||||
}
|
||||
|
@ -11,14 +11,17 @@
|
||||
/**
|
||||
*/
|
||||
class CallTip {
|
||||
int startHighlight;
|
||||
int endHighlight;
|
||||
int startHighlight; // character offset to start and...
|
||||
int endHighlight; // ...end of highlighted text
|
||||
char *val;
|
||||
Font font;
|
||||
PRectangle rectUp;
|
||||
PRectangle rectDown;
|
||||
int lineHeight;
|
||||
int offsetMain;
|
||||
PRectangle rectUp; // rectangle of last up angle in the tip
|
||||
PRectangle rectDown; // rectangle of last down arrow in the tip
|
||||
int lineHeight; // vertical line spacing
|
||||
int offsetMain; // The alignment point of the call tip
|
||||
int tabSize; // Tab size in pixels, <=0 no TAB expand
|
||||
bool useStyleCallTip; // if true, STYLE_CALLTIP should be used
|
||||
|
||||
// Private so CallTip objects can not be copied
|
||||
CallTip(const CallTip &) {}
|
||||
CallTip &operator=(const CallTip &) { return *this; }
|
||||
@ -26,6 +29,8 @@ class CallTip {
|
||||
int posStart, int posEnd, int ytext, PRectangle rcClient,
|
||||
bool highlight, bool draw);
|
||||
int PaintContents(Surface *surfaceWindow, bool draw);
|
||||
bool IsTabCharacter(char c);
|
||||
int NextTabPos(int x);
|
||||
|
||||
public:
|
||||
Window wCallTip;
|
||||
@ -60,6 +65,15 @@ public:
|
||||
/// Set a range of characters to be displayed in a highlight style.
|
||||
/// Commonly used to highlight the current parameter.
|
||||
void SetHighlight(int start, int end);
|
||||
|
||||
/// Set the tab size in pixels for the call tip. 0 or -ve means no tab expand.
|
||||
void SetTabSize(int tabSz);
|
||||
|
||||
/// Used to determine which STYLE_xxxx to use for call tip information
|
||||
bool UseStyleCallTip() const { return useStyleCallTip;}
|
||||
|
||||
// Modify foreground and background colours
|
||||
void SetForeBack(const ColourPair &fore, const ColourPair &back);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
43
scintilla/CharClassify.cxx
Normal file
43
scintilla/CharClassify.cxx
Normal file
@ -0,0 +1,43 @@
|
||||
// Scintilla source code edit control
|
||||
/** @file CharClassify.cxx
|
||||
** Character classifications used by Document and RESearch.
|
||||
**/
|
||||
// Copyright 2006 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "CharClassify.h"
|
||||
|
||||
// Shut up annoying Visual C++ warnings:
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable: 4514)
|
||||
#endif
|
||||
|
||||
CharClassify::CharClassify() {
|
||||
SetDefaultCharClasses(true);
|
||||
}
|
||||
|
||||
void CharClassify::SetDefaultCharClasses(bool includeWordClass) {
|
||||
// Initialize all char classes to default values
|
||||
for (int ch = 0; ch < 256; ch++) {
|
||||
if (ch == '\r' || ch == '\n')
|
||||
charClass[ch] = ccNewLine;
|
||||
else if (ch < 0x20 || ch == ' ')
|
||||
charClass[ch] = ccSpace;
|
||||
else if (includeWordClass && (ch >= 0x80 || isalnum(ch) || ch == '_'))
|
||||
charClass[ch] = ccWord;
|
||||
else
|
||||
charClass[ch] = ccPunctuation;
|
||||
}
|
||||
}
|
||||
|
||||
void CharClassify::SetCharClasses(const unsigned char *chars, cc newCharClass) {
|
||||
// Apply the newCharClass to the specifed chars
|
||||
if (chars) {
|
||||
while (*chars) {
|
||||
charClass[*chars] = static_cast<unsigned char>(newCharClass);
|
||||
chars++;
|
||||
}
|
||||
}
|
||||
}
|
25
scintilla/CharClassify.h
Normal file
25
scintilla/CharClassify.h
Normal file
@ -0,0 +1,25 @@
|
||||
// Scintilla source code edit control
|
||||
/** @file CharClassify.h
|
||||
** Character classifications used by Document and RESearch.
|
||||
**/
|
||||
// Copyright 2006 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#ifndef CHARCLASSIFY_H
|
||||
#define CHARCLASSIFY_H
|
||||
|
||||
class CharClassify {
|
||||
public:
|
||||
CharClassify();
|
||||
|
||||
enum cc { ccSpace, ccNewLine, ccWord, ccPunctuation };
|
||||
void SetDefaultCharClasses(bool includeWordClass);
|
||||
void SetCharClasses(const unsigned char *chars, cc newCharClass);
|
||||
cc GetClass(unsigned char ch) const { return static_cast<cc>(charClass[ch]);}
|
||||
bool IsWord(unsigned char ch) const { return static_cast<cc>(charClass[ch]) == ccWord;}
|
||||
|
||||
private:
|
||||
enum { maxChar=256 };
|
||||
unsigned char charClass[maxChar]; // not type cc to save space
|
||||
};
|
||||
#endif
|
@ -280,4 +280,10 @@ void ContractionState::ShowAll() {
|
||||
delete []lines;
|
||||
lines = 0;
|
||||
size = 0;
|
||||
|
||||
delete []docLines;
|
||||
docLines = 0;
|
||||
sizeDocLines = 0;
|
||||
|
||||
linesInDisplay = linesInDoc;
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "Scintilla.h"
|
||||
#include "SVector.h"
|
||||
#include "CellBuffer.h"
|
||||
#include "CharClassify.h"
|
||||
#include "Document.h"
|
||||
#include "RESearch.h"
|
||||
|
||||
@ -50,7 +51,6 @@ Document::Document() {
|
||||
stylingBits = 5;
|
||||
stylingBitsMask = 0x1F;
|
||||
stylingMask = 0;
|
||||
SetDefaultCharClasses(true);
|
||||
endStyled = 0;
|
||||
styleClock = 0;
|
||||
enteredCount = 0;
|
||||
@ -836,10 +836,10 @@ int Document::ParaDown(int pos) {
|
||||
return LineEnd(line-1);
|
||||
}
|
||||
|
||||
Document::charClassification Document::WordCharClass(unsigned char ch) {
|
||||
CharClassify::cc Document::WordCharClass(unsigned char ch) {
|
||||
if ((SC_CP_UTF8 == dbcsCodePage) && (ch >= 0x80))
|
||||
return ccWord;
|
||||
return charClass[ch];
|
||||
return CharClassify::ccWord;
|
||||
return charClass.GetClass(ch);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -847,7 +847,7 @@ Document::charClassification Document::WordCharClass(unsigned char ch) {
|
||||
* Finds the start of word at pos when delta < 0 or the end of the word when delta >= 0.
|
||||
*/
|
||||
int Document::ExtendWordSelect(int pos, int delta, bool onlyWordCharacters) {
|
||||
charClassification ccStart = ccWord;
|
||||
CharClassify::cc ccStart = CharClassify::ccWord;
|
||||
if (delta < 0) {
|
||||
if (!onlyWordCharacters)
|
||||
ccStart = WordCharClass(cb.CharAt(pos-1));
|
||||
@ -871,19 +871,19 @@ int Document::ExtendWordSelect(int pos, int delta, bool onlyWordCharacters) {
|
||||
*/
|
||||
int Document::NextWordStart(int pos, int delta) {
|
||||
if (delta < 0) {
|
||||
while (pos > 0 && (WordCharClass(cb.CharAt(pos - 1)) == ccSpace))
|
||||
while (pos > 0 && (WordCharClass(cb.CharAt(pos - 1)) == CharClassify::ccSpace))
|
||||
pos--;
|
||||
if (pos > 0) {
|
||||
charClassification ccStart = WordCharClass(cb.CharAt(pos-1));
|
||||
CharClassify::cc ccStart = WordCharClass(cb.CharAt(pos-1));
|
||||
while (pos > 0 && (WordCharClass(cb.CharAt(pos - 1)) == ccStart)) {
|
||||
pos--;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
charClassification ccStart = WordCharClass(cb.CharAt(pos));
|
||||
CharClassify::cc ccStart = WordCharClass(cb.CharAt(pos));
|
||||
while (pos < (Length()) && (WordCharClass(cb.CharAt(pos)) == ccStart))
|
||||
pos++;
|
||||
while (pos < (Length()) && (WordCharClass(cb.CharAt(pos)) == ccSpace))
|
||||
while (pos < (Length()) && (WordCharClass(cb.CharAt(pos)) == CharClassify::ccSpace))
|
||||
pos++;
|
||||
}
|
||||
return pos;
|
||||
@ -899,22 +899,22 @@ int Document::NextWordStart(int pos, int delta) {
|
||||
int Document::NextWordEnd(int pos, int delta) {
|
||||
if (delta < 0) {
|
||||
if (pos > 0) {
|
||||
charClassification ccStart = WordCharClass(cb.CharAt(pos-1));
|
||||
if (ccStart != ccSpace) {
|
||||
CharClassify::cc ccStart = WordCharClass(cb.CharAt(pos-1));
|
||||
if (ccStart != CharClassify::ccSpace) {
|
||||
while (pos > 0 && WordCharClass(cb.CharAt(pos - 1)) == ccStart) {
|
||||
pos--;
|
||||
}
|
||||
}
|
||||
while (pos > 0 && WordCharClass(cb.CharAt(pos - 1)) == ccSpace) {
|
||||
while (pos > 0 && WordCharClass(cb.CharAt(pos - 1)) == CharClassify::ccSpace) {
|
||||
pos--;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while (pos < Length() && WordCharClass(cb.CharAt(pos)) == ccSpace) {
|
||||
while (pos < Length() && WordCharClass(cb.CharAt(pos)) == CharClassify::ccSpace) {
|
||||
pos++;
|
||||
}
|
||||
if (pos < Length()) {
|
||||
charClassification ccStart = WordCharClass(cb.CharAt(pos));
|
||||
CharClassify::cc ccStart = WordCharClass(cb.CharAt(pos));
|
||||
while (pos < Length() && WordCharClass(cb.CharAt(pos)) == ccStart) {
|
||||
pos++;
|
||||
}
|
||||
@ -929,8 +929,8 @@ int Document::NextWordEnd(int pos, int delta) {
|
||||
*/
|
||||
bool Document::IsWordStartAt(int pos) {
|
||||
if (pos > 0) {
|
||||
charClassification ccPos = WordCharClass(CharAt(pos));
|
||||
return (ccPos == ccWord || ccPos == ccPunctuation) &&
|
||||
CharClassify::cc ccPos = WordCharClass(CharAt(pos));
|
||||
return (ccPos == CharClassify::ccWord || ccPos == CharClassify::ccPunctuation) &&
|
||||
(ccPos != WordCharClass(CharAt(pos - 1)));
|
||||
}
|
||||
return true;
|
||||
@ -942,8 +942,8 @@ bool Document::IsWordStartAt(int pos) {
|
||||
*/
|
||||
bool Document::IsWordEndAt(int pos) {
|
||||
if (pos < Length()) {
|
||||
charClassification ccPrev = WordCharClass(CharAt(pos-1));
|
||||
return (ccPrev == ccWord || ccPrev == ccPunctuation) &&
|
||||
CharClassify::cc ccPrev = WordCharClass(CharAt(pos-1));
|
||||
return (ccPrev == CharClassify::ccWord || ccPrev == CharClassify::ccPunctuation) &&
|
||||
(ccPrev != WordCharClass(CharAt(pos)));
|
||||
}
|
||||
return true;
|
||||
@ -1004,7 +1004,7 @@ long Document::FindText(int minPos, int maxPos, const char *s,
|
||||
int *length) {
|
||||
if (regExp) {
|
||||
if (!pre)
|
||||
pre = new RESearch();
|
||||
pre = new RESearch(&charClass);
|
||||
if (!pre)
|
||||
return -1;
|
||||
|
||||
@ -1266,27 +1266,11 @@ void Document::ChangeCase(Range r, bool makeUpperCase) {
|
||||
}
|
||||
|
||||
void Document::SetDefaultCharClasses(bool includeWordClass) {
|
||||
// Initialize all char classes to default values
|
||||
for (int ch = 0; ch < 256; ch++) {
|
||||
if (ch == '\r' || ch == '\n')
|
||||
charClass[ch] = ccNewLine;
|
||||
else if (ch < 0x20 || ch == ' ')
|
||||
charClass[ch] = ccSpace;
|
||||
else if (includeWordClass && (ch >= 0x80 || isalnum(ch) || ch == '_'))
|
||||
charClass[ch] = ccWord;
|
||||
else
|
||||
charClass[ch] = ccPunctuation;
|
||||
}
|
||||
charClass.SetDefaultCharClasses(includeWordClass);
|
||||
}
|
||||
|
||||
void Document::SetCharClasses(const unsigned char *chars, charClassification newCharClass) {
|
||||
// Apply the newCharClass to the specifed chars
|
||||
if (chars) {
|
||||
while (*chars) {
|
||||
charClass[*chars] = newCharClass;
|
||||
chars++;
|
||||
}
|
||||
}
|
||||
void Document::SetCharClasses(const unsigned char *chars, CharClassify::cc newCharClass) {
|
||||
charClass.SetCharClasses(chars, newCharClass);
|
||||
}
|
||||
|
||||
void Document::SetStylingBits(int bits) {
|
||||
@ -1430,7 +1414,7 @@ void Document::NotifyModified(DocModification mh) {
|
||||
}
|
||||
|
||||
bool Document::IsWordPartSeparator(char ch) {
|
||||
return (WordCharClass(ch) == ccWord) && IsPunctuation(ch);
|
||||
return (WordCharClass(ch) == CharClassify::ccWord) && IsPunctuation(ch);
|
||||
}
|
||||
|
||||
int Document::WordPartLeft(int pos) {
|
||||
|
@ -93,7 +93,7 @@ public:
|
||||
private:
|
||||
int refCount;
|
||||
CellBuffer cb;
|
||||
charClassification charClass[256];
|
||||
CharClassify charClass;
|
||||
char stylingMask;
|
||||
int endStyled;
|
||||
int styleClock;
|
||||
@ -207,7 +207,7 @@ public:
|
||||
void ChangeCase(Range r, bool makeUpperCase);
|
||||
|
||||
void SetDefaultCharClasses(bool includeWordClass);
|
||||
void SetCharClasses(const unsigned char *chars, charClassification newCharClass);
|
||||
void SetCharClasses(const unsigned char *chars, CharClassify::cc newCharClass);
|
||||
void SetStylingBits(int bits);
|
||||
void StartStyling(int position, char mask);
|
||||
bool SetStyleFor(int length, char style);
|
||||
@ -239,7 +239,7 @@ public:
|
||||
private:
|
||||
void CheckReadOnly();
|
||||
|
||||
charClassification WordCharClass(unsigned char ch);
|
||||
CharClassify::cc WordCharClass(unsigned char ch);
|
||||
bool IsWordStartAt(int pos);
|
||||
bool IsWordEndAt(int pos);
|
||||
bool IsWordAt(int start, int end);
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "DocumentAccessor.h"
|
||||
#include "CellBuffer.h"
|
||||
#include "Scintilla.h"
|
||||
#include "CharClassify.h"
|
||||
#include "Document.h"
|
||||
|
||||
DocumentAccessor::~DocumentAccessor() {
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "LineMarker.h"
|
||||
#include "Style.h"
|
||||
#include "ViewStyle.h"
|
||||
#include "CharClassify.h"
|
||||
#include "Document.h"
|
||||
#include "Editor.h"
|
||||
|
||||
@ -810,6 +811,9 @@ int Editor::PositionFromLocationClose(Point pt) {
|
||||
return pdoc->MovePositionOutsideChar(i + posLineStart, 1);
|
||||
}
|
||||
}
|
||||
if (pt.x < (ll->positions[lineEnd] - subLineStart)) {
|
||||
return pdoc->MovePositionOutsideChar(lineEnd + posLineStart, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1673,6 +1677,7 @@ void Editor::LinesSplit(int pixelWidth) {
|
||||
targetEnd += static_cast<int>(strlen(eol));
|
||||
}
|
||||
}
|
||||
lineEnd = pdoc->LineFromPosition(targetEnd);
|
||||
}
|
||||
pdoc->EndUndoAction();
|
||||
}
|
||||
@ -2290,7 +2295,7 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
|
||||
// the color for the highest numbered one is used.
|
||||
bool overrideBackground = false;
|
||||
ColourAllocated background;
|
||||
if (caret.active && vsDraw.showCaretLineBackground && ll->containsCaret) {
|
||||
if (caret.active && vsDraw.showCaretLineBackground && (vsDraw.caretLineAlpha == SC_ALPHA_NOALPHA) && ll->containsCaret) {
|
||||
overrideBackground = true;
|
||||
background = vsDraw.caretLineBackground.allocated;
|
||||
}
|
||||
@ -2648,6 +2653,13 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
|
||||
rcSegment.right = rcSegment.left + 1;
|
||||
surface->FillRectangle(rcSegment, vsDraw.edgecolour.allocated);
|
||||
}
|
||||
|
||||
if (caret.active && vsDraw.showCaretLineBackground && (vsDraw.caretLineAlpha != SC_ALPHA_NOALPHA) && ll->containsCaret) {
|
||||
rcSegment.left = xStart;
|
||||
rcSegment.right = rcLine.right - 1;
|
||||
surface->AlphaRectangle(rcSegment, 0, vsDraw.caretLineBackground.allocated, vsDraw.caretLineAlpha,
|
||||
vsDraw.caretLineBackground.allocated, vsDraw.caretLineAlpha, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::RefreshPixMaps(Surface *surfaceWindow) {
|
||||
@ -2721,7 +2733,6 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
|
||||
// paintingAllText, rcArea.left, rcArea.top, rcArea.right, rcArea.bottom);
|
||||
|
||||
RefreshStyleData();
|
||||
|
||||
RefreshPixMaps(surfaceWindow);
|
||||
|
||||
PRectangle rcClient = GetClientRectangle();
|
||||
@ -2752,6 +2763,8 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
|
||||
if (needUpdateUI) {
|
||||
NotifyUpdateUI();
|
||||
needUpdateUI = false;
|
||||
RefreshStyleData();
|
||||
RefreshPixMaps(surfaceWindow);
|
||||
}
|
||||
|
||||
// Call priority lines wrap on a window of lines which are likely
|
||||
@ -4849,7 +4862,7 @@ void Editor::CopyRangeToClipboard(int start, int end) {
|
||||
|
||||
void Editor::CopyText(int length, const char *text) {
|
||||
SelectionText selectedText;
|
||||
selectedText.Copy(text, length,
|
||||
selectedText.Copy(text, length + 1,
|
||||
pdoc->dbcsCodePage, vs.styles[STYLE_DEFAULT].characterSet, false);
|
||||
CopyToClipboard(selectedText);
|
||||
}
|
||||
@ -6038,14 +6051,14 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
|
||||
pdoc->SetDefaultCharClasses(false);
|
||||
if (lParam == 0)
|
||||
return 0;
|
||||
pdoc->SetCharClasses(reinterpret_cast<unsigned char *>(lParam), Document::ccWord);
|
||||
pdoc->SetCharClasses(reinterpret_cast<unsigned char *>(lParam), CharClassify::ccWord);
|
||||
}
|
||||
break;
|
||||
|
||||
case SCI_SETWHITESPACECHARS: {
|
||||
if (lParam == 0)
|
||||
return 0;
|
||||
pdoc->SetCharClasses(reinterpret_cast<unsigned char *>(lParam), Document::ccSpace);
|
||||
pdoc->SetCharClasses(reinterpret_cast<unsigned char *>(lParam), CharClassify::ccSpace);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -6717,6 +6730,12 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
|
||||
vs.caretLineBackground.desired = wParam;
|
||||
InvalidateStyleRedraw();
|
||||
break;
|
||||
case SCI_GETCARETLINEBACKALPHA:
|
||||
return vs.caretLineAlpha;
|
||||
case SCI_SETCARETLINEBACKALPHA:
|
||||
vs.caretLineAlpha = wParam;
|
||||
InvalidateStyleRedraw();
|
||||
break;
|
||||
|
||||
// Folding messages
|
||||
|
||||
|
@ -12,6 +12,8 @@
|
||||
|
||||
#include "Platform.h"
|
||||
|
||||
#include "Scintilla.h"
|
||||
|
||||
#include "SciLexer.h"
|
||||
#include "PropSet.h"
|
||||
#include "Accessor.h"
|
||||
@ -116,16 +118,16 @@ LexerLibrary::LexerLibrary(const char* ModuleName) {
|
||||
if (lib->IsValid()) {
|
||||
m_sModuleName = ModuleName;
|
||||
//Cannot use reinterpret_cast because: ANSI C++ forbids casting between pointers to functions and objects
|
||||
GetLexerCountFn GetLexerCount = (GetLexerCountFn)lib->FindFunction("GetLexerCount");
|
||||
GetLexerCountFn GetLexerCount = (GetLexerCountFn)(sptr_t)lib->FindFunction("GetLexerCount");
|
||||
|
||||
if (GetLexerCount) {
|
||||
ExternalLexerModule *lex;
|
||||
LexerMinder *lm;
|
||||
|
||||
// Find functions in the DLL
|
||||
GetLexerNameFn GetLexerName = (GetLexerNameFn)lib->FindFunction("GetLexerName");
|
||||
ExtLexerFunction Lexer = (ExtLexerFunction)lib->FindFunction("Lex");
|
||||
ExtFoldFunction Folder = (ExtFoldFunction)lib->FindFunction("Fold");
|
||||
GetLexerNameFn GetLexerName = (GetLexerNameFn)(sptr_t)lib->FindFunction("GetLexerName");
|
||||
ExtLexerFunction Lexer = (ExtLexerFunction)(sptr_t)lib->FindFunction("Lex");
|
||||
ExtFoldFunction Folder = (ExtFoldFunction)(sptr_t)lib->FindFunction("Fold");
|
||||
|
||||
// Assign a buffer for the lexer name.
|
||||
char lexname[100];
|
||||
|
@ -63,6 +63,12 @@ void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &r
|
||||
surface->LineTo(rc.right, rcLine.top+1);
|
||||
surface->LineTo(rc.left, rcLine.top+1);
|
||||
surface->LineTo(rc.left, ymid+1);
|
||||
} else if (style == INDIC_ROUNDBOX) {
|
||||
PRectangle rcBox = rcLine;
|
||||
rcBox.top = rcLine.top + 1;
|
||||
rcBox.left = rc.left;
|
||||
rcBox.right = rc.right;
|
||||
surface->AlphaRectangle(rcBox, 1, fore.allocated, 30, fore.allocated, 50, 0);
|
||||
} else { // Either INDIC_PLAIN or unknown
|
||||
surface->MoveTo(rc.left, ymid);
|
||||
surface->LineTo(rc.right, ymid);
|
||||
|
@ -160,7 +160,6 @@ int Scintilla_LinkLexers() {
|
||||
LINK_LEXER(lmCss);
|
||||
LINK_LEXER(lmCPP);
|
||||
LINK_LEXER(lmCPPNoCase);
|
||||
LINK_LEXER(lmTCL);
|
||||
LINK_LEXER(lmPerl);
|
||||
LINK_LEXER(lmSQL);
|
||||
|
||||
|
@ -459,4 +459,3 @@ static void ColouriseCppDocInsensitive(unsigned int startPos, int length, int in
|
||||
|
||||
LexerModule lmCPP(SCLEX_CPP, ColouriseCppDocSensitive, "cpp", FoldCppDoc, cppWordLists);
|
||||
LexerModule lmCPPNoCase(SCLEX_CPPNOCASE, ColouriseCppDocInsensitive, "cppnocase", FoldCppDoc, cppWordLists);
|
||||
LexerModule lmTCL(SCLEX_TCL, ColouriseCppDocSensitive, "tcl", FoldCppDoc, cppWordLists);
|
||||
|
@ -149,7 +149,13 @@ static inline bool isStringState(int state) {
|
||||
case SCE_HB_STRING:
|
||||
case SCE_HBA_STRING:
|
||||
case SCE_HP_STRING:
|
||||
case SCE_HP_CHARACTER:
|
||||
case SCE_HP_TRIPLE:
|
||||
case SCE_HP_TRIPLEDOUBLE:
|
||||
case SCE_HPA_STRING:
|
||||
case SCE_HPA_CHARACTER:
|
||||
case SCE_HPA_TRIPLE:
|
||||
case SCE_HPA_TRIPLEDOUBLE:
|
||||
case SCE_HPHP_HSTRING:
|
||||
case SCE_HPHP_SIMPLESTRING:
|
||||
case SCE_HPHP_HSTRING_VARIABLE:
|
||||
@ -163,6 +169,19 @@ static inline bool isStringState(int state) {
|
||||
return bResult;
|
||||
}
|
||||
|
||||
static inline bool stateAllowsTermination(int state) {
|
||||
bool allowTermination = !isStringState(state);
|
||||
if (allowTermination) {
|
||||
switch (state) {
|
||||
case SCE_HPHP_COMMENT:
|
||||
case SCE_HP_COMMENTLINE:
|
||||
case SCE_HPA_COMMENTLINE:
|
||||
allowTermination = false;
|
||||
}
|
||||
}
|
||||
return allowTermination;
|
||||
}
|
||||
|
||||
// not really well done, since it's only comments that should lex the %> and <%
|
||||
static inline bool isCommentASPState(int state) {
|
||||
bool bResult;
|
||||
@ -763,9 +782,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
|
||||
else if ((
|
||||
((inScriptType == eNonHtmlPreProc)
|
||||
|| (inScriptType == eNonHtmlScriptPreProc)) && (
|
||||
((scriptLanguage == eScriptPHP) && (ch == '?') && !isPHPStringState(state) && (state != SCE_HPHP_COMMENT)) ||
|
||||
((scriptLanguage != eScriptNone) && !isStringState(state) &&
|
||||
((ch == '%') || (ch == '?')))
|
||||
((scriptLanguage != eScriptNone) && stateAllowsTermination(state) && ((ch == '%') || (ch == '?')))
|
||||
) && (chNext == '>')) ||
|
||||
((scriptLanguage == eScriptSGML) && (ch == '>') && (state != SCE_H_SGML_COMMENT))) {
|
||||
if (state == SCE_H_ASPAT) {
|
||||
|
@ -41,7 +41,7 @@ static bool IsBOperator(char ch) {
|
||||
|
||||
// Tests for BATCH Separators
|
||||
static bool IsBSeparator(char ch) {
|
||||
return (ch == ':') || (ch == '\\') || (ch == '.') || (ch == ';') ||
|
||||
return (ch == '\\') || (ch == '.') || (ch == ';') ||
|
||||
(ch == '\"') || (ch == '\'') || (ch == '/') || (ch == ')');
|
||||
}
|
||||
|
||||
@ -50,7 +50,7 @@ static void ColouriseBatchLine(
|
||||
unsigned int lengthLine,
|
||||
unsigned int startLine,
|
||||
unsigned int endPos,
|
||||
WordList &keywords,
|
||||
WordList *keywordlists[],
|
||||
Accessor &styler) {
|
||||
|
||||
unsigned int offset = 0; // Line Buffer Offset
|
||||
@ -59,7 +59,9 @@ static void ColouriseBatchLine(
|
||||
char wordBuffer[81]; // Word Buffer - large to catch long paths
|
||||
unsigned int wbl; // Word Buffer Length
|
||||
unsigned int wbo; // Word Buffer Offset - also Special Keyword Buffer Length
|
||||
bool forFound = false; // No Local Variable without FOR statement
|
||||
WordList &keywords = *keywordlists[0]; // Internal Commands
|
||||
WordList &keywords2 = *keywordlists[1]; // External Commands (optional)
|
||||
|
||||
// CHOICE, ECHO, GOTO, PROMPT and SET have Default Text that may contain Regular Keywords
|
||||
// Toggling Regular Keyword Checking off improves readability
|
||||
// Other Regular Keywords and External Commands / Programs might also benefit from toggling
|
||||
@ -174,7 +176,13 @@ static void ColouriseBatchLine(
|
||||
// Reset Offset to re-process remainder of word
|
||||
offset -= (wbl - 1);
|
||||
// Colorize External Command / Program
|
||||
styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
|
||||
if (!keywords2) {
|
||||
styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
|
||||
} else if (keywords2.InList(wordBuffer)) {
|
||||
styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
|
||||
} else {
|
||||
styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
|
||||
}
|
||||
// Reset External Command / Program Location
|
||||
cmdLoc = offset;
|
||||
} else {
|
||||
@ -186,10 +194,6 @@ static void ColouriseBatchLine(
|
||||
// Check for Regular Keyword in list
|
||||
} else if ((keywords.InList(wordBuffer)) &&
|
||||
(continueProcessing)) {
|
||||
// Local Variables do not exist if no FOR statement
|
||||
if (CompareCaseInsensitive(wordBuffer, "for") == 0) {
|
||||
forFound = true;
|
||||
}
|
||||
// ECHO, GOTO, PROMPT and SET require no further Regular Keyword Checking
|
||||
if ((CompareCaseInsensitive(wordBuffer, "echo") == 0) ||
|
||||
(CompareCaseInsensitive(wordBuffer, "goto") == 0) ||
|
||||
@ -261,8 +265,8 @@ static void ColouriseBatchLine(
|
||||
styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_WORD);
|
||||
// Reset Offset to re-process remainder of word
|
||||
offset -= (wbl - wbo);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check for External Command / Program or Default Text
|
||||
if (!sKeywordFound) {
|
||||
wbo = 0;
|
||||
@ -306,8 +310,14 @@ static void ColouriseBatchLine(
|
||||
}
|
||||
}
|
||||
}
|
||||
// Colorize External command / program
|
||||
styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
|
||||
// Colorize External Command / Program
|
||||
if (!keywords2) {
|
||||
styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
|
||||
} else if (keywords2.InList(wordBuffer)) {
|
||||
styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
|
||||
} else {
|
||||
styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
|
||||
}
|
||||
// No need to Reset Offset
|
||||
// Check for Default Text
|
||||
} else {
|
||||
@ -354,13 +364,13 @@ static void ColouriseBatchLine(
|
||||
// Check for External Command / Program
|
||||
if (cmdLoc == offset - wbl) {
|
||||
cmdLoc = offset - (wbl - wbo);
|
||||
}
|
||||
}
|
||||
// Colorize Environment Variable
|
||||
styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER);
|
||||
// Reset Offset to re-process remainder of word
|
||||
offset -= (wbl - wbo);
|
||||
// Check for Local Variable (%%a)
|
||||
} else if ((forFound) &&
|
||||
} else if (
|
||||
(wordBuffer[1] == '%') &&
|
||||
(wordBuffer[2] != '%') &&
|
||||
(!IsBOperator(wordBuffer[2])) &&
|
||||
@ -447,7 +457,6 @@ static void ColouriseBatchDoc(
|
||||
Accessor &styler) {
|
||||
|
||||
char lineBuffer[1024];
|
||||
WordList &keywords = *keywordlists[0];
|
||||
|
||||
styler.StartAt(startPos);
|
||||
styler.StartSegment(startPos);
|
||||
@ -458,14 +467,14 @@ static void ColouriseBatchDoc(
|
||||
if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
|
||||
// End of line (or of line buffer) met, colourise it
|
||||
lineBuffer[linePos] = '\0';
|
||||
ColouriseBatchLine(lineBuffer, linePos, startLine, i, keywords, styler);
|
||||
ColouriseBatchLine(lineBuffer, linePos, startLine, i, keywordlists, styler);
|
||||
linePos = 0;
|
||||
startLine = i + 1;
|
||||
}
|
||||
}
|
||||
if (linePos > 0) { // Last line does not have ending characters
|
||||
ColouriseBatchLine(lineBuffer, linePos, startLine, startPos + length - 1,
|
||||
keywords, styler);
|
||||
keywordlists, styler);
|
||||
}
|
||||
}
|
||||
|
||||
@ -593,9 +602,9 @@ static void ColourisePropsLine(
|
||||
while ((i < lengthLine) && (lineBuffer[i] != '='))
|
||||
i++;
|
||||
if ((i < lengthLine) && (lineBuffer[i] == '=')) {
|
||||
styler.ColourTo(startLine + i - 1, SCE_PROPS_DEFAULT);
|
||||
styler.ColourTo(startLine + i, 3);
|
||||
styler.ColourTo(endPos, SCE_PROPS_DEFVAL);
|
||||
styler.ColourTo(startLine + i - 1, SCE_PROPS_KEY);
|
||||
styler.ColourTo(startLine + i, SCE_PROPS_ASSIGNMENT);
|
||||
styler.ColourTo(endPos, SCE_PROPS_DEFAULT);
|
||||
} else {
|
||||
styler.ColourTo(endPos, SCE_PROPS_DEFAULT);
|
||||
}
|
||||
@ -1103,7 +1112,8 @@ static void ColouriseLatexDoc(unsigned int startPos, int length, int initStyle,
|
||||
}
|
||||
|
||||
static const char * const batchWordListDesc[] = {
|
||||
"Keywords",
|
||||
"Internal Commands",
|
||||
"External Commands",
|
||||
0
|
||||
};
|
||||
|
||||
|
@ -109,6 +109,7 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
|
||||
}
|
||||
|
||||
WordList &keywords = *keywordlists[0];
|
||||
WordList &keywords2 = *keywordlists[1];
|
||||
|
||||
const int whingeLevel = styler.GetPropertyInt("tab.timmy.whinge.level");
|
||||
|
||||
@ -186,6 +187,8 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
|
||||
style = SCE_P_CLASSNAME;
|
||||
} else if (kwLast == kwDef) {
|
||||
style = SCE_P_DEFNAME;
|
||||
} else if (keywords2.InList(s)) {
|
||||
style = SCE_P_WORD2;
|
||||
}
|
||||
sc.ChangeState(style);
|
||||
sc.SetState(SCE_P_DEFAULT);
|
||||
@ -198,9 +201,7 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
|
||||
kwLast = kwImport;
|
||||
else
|
||||
kwLast = kwOther;
|
||||
} else if (style == SCE_P_CLASSNAME) {
|
||||
kwLast = kwOther;
|
||||
} else if (style == SCE_P_DEFNAME) {
|
||||
} else {
|
||||
kwLast = kwOther;
|
||||
}
|
||||
}
|
||||
@ -208,6 +209,12 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
|
||||
if (sc.ch == '\r' || sc.ch == '\n') {
|
||||
sc.SetState(SCE_P_DEFAULT);
|
||||
}
|
||||
} else if (sc.state == SCE_P_DECORATOR) {
|
||||
if (sc.ch == '\r' || sc.ch == '\n') {
|
||||
sc.SetState(SCE_P_DEFAULT);
|
||||
} else if (sc.ch == '#') {
|
||||
sc.SetState((sc.chNext == '#') ? SCE_P_COMMENTBLOCK : SCE_P_COMMENTLINE);
|
||||
}
|
||||
} else if ((sc.state == SCE_P_STRING) || (sc.state == SCE_P_CHARACTER)) {
|
||||
if (sc.ch == '\\') {
|
||||
if ((sc.chNext == '\r') && (sc.GetRelative(2) == '\n')) {
|
||||
@ -262,6 +269,8 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
|
||||
sc.SetState(SCE_P_OPERATOR);
|
||||
} else if (sc.ch == '#') {
|
||||
sc.SetState(sc.chNext == '#' ? SCE_P_COMMENTBLOCK : SCE_P_COMMENTLINE);
|
||||
} else if (sc.ch == '@') {
|
||||
sc.SetState(SCE_P_DECORATOR);
|
||||
} else if (IsPyStringStart(sc.ch, sc.chNext, sc.GetRelative(2))) {
|
||||
unsigned int nextIndex = 0;
|
||||
sc.SetState(GetPyStringState(styler, sc.currentPos, &nextIndex));
|
||||
@ -432,6 +441,7 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse
|
||||
|
||||
static const char * const pythonWordListDesc[] = {
|
||||
"Keywords",
|
||||
"Highlighted identifiers",
|
||||
0
|
||||
};
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
// Scintilla source code edit control
|
||||
/** @file LexSQL.cxx
|
||||
** Lexer for SQL.
|
||||
** Lexer for SQL, including PL/SQL and SQL*Plus.
|
||||
**/
|
||||
// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
|
||||
// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#include <stdlib.h>
|
||||
@ -15,293 +15,218 @@
|
||||
|
||||
#include "PropSet.h"
|
||||
#include "Accessor.h"
|
||||
#include "StyleContext.h"
|
||||
#include "KeyWords.h"
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
|
||||
static inline bool IsASpace(unsigned int ch) {
|
||||
return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
|
||||
static inline bool IsAWordChar(int ch) {
|
||||
return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
|
||||
}
|
||||
|
||||
static bool MatchIgnoreCaseSubstring(const char *s, Accessor &styler, unsigned int startPos) {
|
||||
char ch = styler.SafeGetCharAt(startPos);
|
||||
bool isSubword = false;
|
||||
if (tolower(ch) != *s)
|
||||
return false;
|
||||
s++;
|
||||
if (*s == '~')
|
||||
{
|
||||
isSubword = true;
|
||||
s++;
|
||||
}
|
||||
int n;
|
||||
for (n = 1; *s; n++) {
|
||||
if (*s == '~')
|
||||
{
|
||||
isSubword = true;
|
||||
s++;
|
||||
}
|
||||
if (isSubword && IsASpace(styler.SafeGetCharAt(startPos + n)))
|
||||
return true;
|
||||
if (*s != tolower((styler.SafeGetCharAt(startPos + n))))
|
||||
return false;
|
||||
s++;
|
||||
}
|
||||
return (IsASpace(styler.SafeGetCharAt(startPos + n))
|
||||
|| styler.SafeGetCharAt(startPos + n) == ';');
|
||||
static inline bool IsAWordStart(int ch) {
|
||||
return (ch < 0x80) && (isalpha(ch) || ch == '_');
|
||||
}
|
||||
|
||||
static void getCurrent(unsigned int start,
|
||||
unsigned int end,
|
||||
Accessor &styler,
|
||||
char *s,
|
||||
unsigned int len) {
|
||||
for (unsigned int i = 0; i < end - start + 1 && i < len; i++) {
|
||||
s[i] = static_cast<char>(tolower(styler[start + i]));
|
||||
s[i + 1] = '\0';
|
||||
}
|
||||
static inline bool IsADoxygenChar(int ch) {
|
||||
return (islower(ch) || ch == '$' || ch == '@' ||
|
||||
ch == '\\' || ch == '&' || ch == '<' ||
|
||||
ch == '>' || ch == '#' || ch == '{' ||
|
||||
ch == '}' || ch == '[' || ch == ']');
|
||||
}
|
||||
|
||||
static void classifyWordSQL(unsigned int start, unsigned int end, WordList *keywordlists[], Accessor &styler) {
|
||||
char s[100];
|
||||
bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');
|
||||
for (unsigned int i = 0; i < end - start + 1 && i < 80; i++) {
|
||||
s[i] = static_cast<char>(tolower(styler[start + i]));
|
||||
s[i + 1] = '\0';
|
||||
}
|
||||
|
||||
WordList &keywords1 = *keywordlists[0];
|
||||
WordList &keywords2 = *keywordlists[1];
|
||||
// WordList &kw_pldoc = *keywordlists[2];
|
||||
WordList &kw_sqlplus = *keywordlists[3];
|
||||
WordList &kw_user1 = *keywordlists[4];
|
||||
WordList &kw_user2 = *keywordlists[5];
|
||||
WordList &kw_user3 = *keywordlists[6];
|
||||
WordList &kw_user4 = *keywordlists[7];
|
||||
|
||||
char chAttr = SCE_SQL_IDENTIFIER;
|
||||
if (wordIsNumber)
|
||||
chAttr = SCE_SQL_NUMBER;
|
||||
else if (keywords1.InList(s))
|
||||
chAttr = SCE_SQL_WORD;
|
||||
else if (keywords2.InList(s))
|
||||
chAttr = SCE_SQL_WORD2;
|
||||
else if (kw_sqlplus.InListAbbreviated(s, '~'))
|
||||
chAttr = SCE_SQL_SQLPLUS;
|
||||
else if (kw_user1.InList(s))
|
||||
chAttr = SCE_SQL_USER1;
|
||||
else if (kw_user2.InList(s))
|
||||
chAttr = SCE_SQL_USER2;
|
||||
else if (kw_user3.InList(s))
|
||||
chAttr = SCE_SQL_USER3;
|
||||
else if (kw_user4.InList(s))
|
||||
chAttr = SCE_SQL_USER4;
|
||||
|
||||
styler.ColourTo(end, chAttr);
|
||||
static inline bool IsANumberChar(int ch) {
|
||||
// Not exactly following number definition (several dots are seen as OK, etc.)
|
||||
// but probably enough in most cases.
|
||||
return (ch < 0x80) &&
|
||||
(isdigit(ch) || toupper(ch) == 'E' ||
|
||||
ch == '.' || ch == '-' || ch == '+');
|
||||
}
|
||||
|
||||
static void ColouriseSQLDoc(unsigned int startPos, int length,
|
||||
int initStyle, WordList *keywordlists[], Accessor &styler) {
|
||||
static void ColouriseSQLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
|
||||
Accessor &styler) {
|
||||
|
||||
WordList &keywords1 = *keywordlists[0];
|
||||
WordList &keywords2 = *keywordlists[1];
|
||||
WordList &kw_pldoc = *keywordlists[2];
|
||||
styler.StartAt(startPos);
|
||||
WordList &kw_sqlplus = *keywordlists[3];
|
||||
WordList &kw_user1 = *keywordlists[4];
|
||||
WordList &kw_user2 = *keywordlists[5];
|
||||
WordList &kw_user3 = *keywordlists[6];
|
||||
WordList &kw_user4 = *keywordlists[7];
|
||||
|
||||
StyleContext sc(startPos, length, initStyle, styler);
|
||||
|
||||
bool fold = styler.GetPropertyInt("fold") != 0;
|
||||
bool sqlBackslashEscapes = styler.GetPropertyInt("sql.backslash.escapes", 0) != 0;
|
||||
bool sqlBackticksIdentifier = styler.GetPropertyInt("lexer.sql.backticks.identifier", 0) != 0;
|
||||
int styleBeforeDCKeyword = SCE_SQL_DEFAULT;
|
||||
bool fold = styler.GetPropertyInt("fold") != 0;
|
||||
int lineCurrent = styler.GetLine(startPos);
|
||||
int spaceFlags = 0;
|
||||
|
||||
int state = initStyle;
|
||||
char chPrev = ' ';
|
||||
char chNext = styler[startPos];
|
||||
styler.StartSegment(startPos);
|
||||
unsigned int lengthDoc = startPos + length;
|
||||
for (unsigned int i = startPos; i < lengthDoc; i++) {
|
||||
char ch = chNext;
|
||||
chNext = styler.SafeGetCharAt(i + 1);
|
||||
|
||||
if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
|
||||
for (; sc.More(); sc.Forward()) {
|
||||
// Fold based on indentation
|
||||
if (sc.atLineStart) {
|
||||
int spaceFlags = 0;
|
||||
int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags);
|
||||
int lev = indentCurrent;
|
||||
int level = indentCurrent;
|
||||
if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
|
||||
// Only non whitespace lines can be headers
|
||||
int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags);
|
||||
if (indentCurrent < (indentNext & ~SC_FOLDLEVELWHITEFLAG)) {
|
||||
lev |= SC_FOLDLEVELHEADERFLAG;
|
||||
level |= SC_FOLDLEVELHEADERFLAG;
|
||||
}
|
||||
}
|
||||
if (fold) {
|
||||
styler.SetLevel(lineCurrent, lev);
|
||||
styler.SetLevel(lineCurrent, level);
|
||||
}
|
||||
}
|
||||
|
||||
if (styler.IsLeadByte(ch)) {
|
||||
chNext = styler.SafeGetCharAt(i + 2);
|
||||
chPrev = ' ';
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (state == SCE_SQL_DEFAULT) {
|
||||
if (MatchIgnoreCaseSubstring("rem~ark", styler, i)) {
|
||||
styler.ColourTo(i - 1, state);
|
||||
state = SCE_SQL_SQLPLUS_COMMENT;
|
||||
} else if (MatchIgnoreCaseSubstring("pro~mpt", styler, i)) {
|
||||
styler.ColourTo(i - 1, state);
|
||||
state = SCE_SQL_SQLPLUS_PROMPT;
|
||||
} else if (iswordstart(ch)) {
|
||||
styler.ColourTo(i - 1, state);
|
||||
state = SCE_SQL_WORD;
|
||||
} else if (ch == '/' && chNext == '*') {
|
||||
styler.ColourTo(i - 1, state);
|
||||
if ((styler.SafeGetCharAt(i + 2)) == '*') { // Support of Doxygen doc. style
|
||||
state = SCE_SQL_COMMENTDOC;
|
||||
// Determine if the current state should terminate.
|
||||
switch (sc.state) {
|
||||
case SCE_SQL_OPERATOR:
|
||||
sc.SetState(SCE_SQL_DEFAULT);
|
||||
break;
|
||||
case SCE_SQL_NUMBER:
|
||||
// We stop the number definition on non-numerical non-dot non-eE non-sign char
|
||||
if (!IsANumberChar(sc.ch)) {
|
||||
sc.SetState(SCE_SQL_DEFAULT);
|
||||
}
|
||||
break;
|
||||
case SCE_SQL_IDENTIFIER:
|
||||
if (!IsAWordChar(sc.ch)) {
|
||||
int nextState = SCE_SQL_DEFAULT;
|
||||
char s[1000];
|
||||
sc.GetCurrentLowered(s, sizeof(s));
|
||||
if (keywords1.InList(s)) {
|
||||
sc.ChangeState(SCE_SQL_WORD);
|
||||
} else if (keywords2.InList(s)) {
|
||||
sc.ChangeState(SCE_SQL_WORD2);
|
||||
} else if (kw_sqlplus.InListAbbreviated(s, '~')) {
|
||||
sc.ChangeState(SCE_SQL_SQLPLUS);
|
||||
if (strncmp(s, "rem", 3) == 0) {
|
||||
nextState = SCE_SQL_SQLPLUS_COMMENT;
|
||||
} else if (strncmp(s, "pro", 3) == 0) {
|
||||
nextState = SCE_SQL_SQLPLUS_PROMPT;
|
||||
}
|
||||
} else if (kw_user1.InList(s)) {
|
||||
sc.ChangeState(SCE_SQL_USER1);
|
||||
} else if (kw_user2.InList(s)) {
|
||||
sc.ChangeState(SCE_SQL_USER2);
|
||||
} else if (kw_user3.InList(s)) {
|
||||
sc.ChangeState(SCE_SQL_USER3);
|
||||
} else if (kw_user4.InList(s)) {
|
||||
sc.ChangeState(SCE_SQL_USER4);
|
||||
}
|
||||
sc.SetState(nextState);
|
||||
}
|
||||
break;
|
||||
case SCE_SQL_QUOTEDIDENTIFIER:
|
||||
if (sc.ch == 0x60) {
|
||||
if (sc.chNext == 0x60) {
|
||||
sc.Forward(); // Ignore it
|
||||
} else {
|
||||
state = SCE_SQL_COMMENT;
|
||||
}
|
||||
} else if (ch == '-' && chNext == '-') {
|
||||
styler.ColourTo(i - 1, state);
|
||||
state = SCE_SQL_COMMENTLINE;
|
||||
} else if (ch == '#') {
|
||||
styler.ColourTo(i - 1, state);
|
||||
state = SCE_SQL_COMMENTLINEDOC;
|
||||
} else if (ch == '\'') {
|
||||
styler.ColourTo(i - 1, state);
|
||||
state = SCE_SQL_CHARACTER;
|
||||
} else if (ch == '"') {
|
||||
styler.ColourTo(i - 1, state);
|
||||
state = SCE_SQL_STRING;
|
||||
} else if (isoperator(ch)) {
|
||||
styler.ColourTo(i - 1, state);
|
||||
styler.ColourTo(i, SCE_SQL_OPERATOR);
|
||||
}
|
||||
} else if (state == SCE_SQL_WORD) {
|
||||
if (!iswordchar(ch)) {
|
||||
classifyWordSQL(styler.GetStartSegment(), i - 1, keywordlists, styler);
|
||||
state = SCE_SQL_DEFAULT;
|
||||
if (ch == '/' && chNext == '*') {
|
||||
if ((styler.SafeGetCharAt(i + 2)) == '*') { // Support of Doxygen doc. style
|
||||
state = SCE_SQL_COMMENTDOC;
|
||||
} else {
|
||||
state = SCE_SQL_COMMENT;
|
||||
}
|
||||
} else if (ch == '-' && chNext == '-') {
|
||||
state = SCE_SQL_COMMENTLINE;
|
||||
} else if (ch == '#') {
|
||||
state = SCE_SQL_COMMENTLINEDOC;
|
||||
} else if (ch == '\'') {
|
||||
state = SCE_SQL_CHARACTER;
|
||||
} else if (ch == '"') {
|
||||
state = SCE_SQL_STRING;
|
||||
} else if (isoperator(ch)) {
|
||||
styler.ColourTo(i, SCE_SQL_OPERATOR);
|
||||
sc.ForwardSetState(SCE_SQL_DEFAULT);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (state == SCE_SQL_COMMENT) {
|
||||
if (ch == '/' && chPrev == '*') {
|
||||
if (((i > (styler.GetStartSegment() + 2)) || ((initStyle == SCE_C_COMMENT) &&
|
||||
(styler.GetStartSegment() == startPos)))) {
|
||||
styler.ColourTo(i, state);
|
||||
state = SCE_SQL_DEFAULT;
|
||||
}
|
||||
}
|
||||
} else if (state == SCE_SQL_COMMENTDOC) {
|
||||
if (ch == '/' && chPrev == '*') {
|
||||
if (((i > (styler.GetStartSegment() + 2)) || ((initStyle == SCE_SQL_COMMENTDOC) &&
|
||||
(styler.GetStartSegment() == startPos)))) {
|
||||
styler.ColourTo(i, state);
|
||||
state = SCE_SQL_DEFAULT;
|
||||
}
|
||||
} else if (ch == '@') {
|
||||
// Verify that we have the conditions to mark a comment-doc-keyword
|
||||
if ((IsASpace(chPrev) || chPrev == '*') && (!IsASpace(chNext))) {
|
||||
styler.ColourTo(i - 1, state);
|
||||
state = SCE_SQL_COMMENTDOCKEYWORD;
|
||||
}
|
||||
}
|
||||
} else if (state == SCE_SQL_COMMENTLINE || state == SCE_SQL_COMMENTLINEDOC || state == SCE_SQL_SQLPLUS_COMMENT) {
|
||||
if (ch == '\r' || ch == '\n') {
|
||||
styler.ColourTo(i - 1, state);
|
||||
state = SCE_SQL_DEFAULT;
|
||||
}
|
||||
} else if (state == SCE_SQL_COMMENTDOCKEYWORD) {
|
||||
if (ch == '/' && chPrev == '*') {
|
||||
styler.ColourTo(i - 1, SCE_SQL_COMMENTDOCKEYWORDERROR);
|
||||
state = SCE_SQL_DEFAULT;
|
||||
} else if (!iswordchar(ch)) {
|
||||
char s[100];
|
||||
getCurrent(styler.GetStartSegment(), i - 1, styler, s, 30);
|
||||
if (!kw_pldoc.InList(s + 1)) {
|
||||
state = SCE_SQL_COMMENTDOCKEYWORDERROR;
|
||||
}
|
||||
styler.ColourTo(i - 1, state);
|
||||
state = SCE_SQL_COMMENTDOC;
|
||||
}
|
||||
} else if (state == SCE_SQL_SQLPLUS_PROMPT) {
|
||||
if (ch == '\r' || ch == '\n') {
|
||||
styler.ColourTo(i - 1, state);
|
||||
state = SCE_SQL_DEFAULT;
|
||||
}
|
||||
} else if (state == SCE_SQL_CHARACTER) {
|
||||
if (sqlBackslashEscapes && ch == '\\') {
|
||||
i++;
|
||||
ch = chNext;
|
||||
chNext = styler.SafeGetCharAt(i + 1);
|
||||
} else if (ch == '\'') {
|
||||
if (chNext == '\'') {
|
||||
i++;
|
||||
} else {
|
||||
styler.ColourTo(i, state);
|
||||
state = SCE_SQL_DEFAULT;
|
||||
i++;
|
||||
}
|
||||
ch = chNext;
|
||||
chNext = styler.SafeGetCharAt(i + 1);
|
||||
}
|
||||
} else if (state == SCE_SQL_STRING) {
|
||||
if (ch == '"') {
|
||||
if (chNext == '"') {
|
||||
i++;
|
||||
} else {
|
||||
styler.ColourTo(i, state);
|
||||
state = SCE_SQL_DEFAULT;
|
||||
i++;
|
||||
}
|
||||
ch = chNext;
|
||||
chNext = styler.SafeGetCharAt(i + 1);
|
||||
break;
|
||||
case SCE_SQL_COMMENT:
|
||||
if (sc.Match('*', '/')) {
|
||||
sc.Forward();
|
||||
sc.ForwardSetState(SCE_SQL_DEFAULT);
|
||||
}
|
||||
break;
|
||||
case SCE_SQL_COMMENTDOC:
|
||||
if (sc.Match('*', '/')) {
|
||||
sc.Forward();
|
||||
sc.ForwardSetState(SCE_SQL_DEFAULT);
|
||||
} else if (sc.ch == '@' || sc.ch == '\\') { // Doxygen support
|
||||
// Verify that we have the conditions to mark a comment-doc-keyword
|
||||
if ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) {
|
||||
styleBeforeDCKeyword = SCE_SQL_COMMENTDOC;
|
||||
sc.SetState(SCE_SQL_COMMENTDOCKEYWORD);
|
||||
}
|
||||
}
|
||||
if (state == SCE_SQL_DEFAULT) { // One of the above succeeded
|
||||
if (ch == '/' && chNext == '*') {
|
||||
if ((styler.SafeGetCharAt(i + 2)) == '*') { // Support of Doxygen doc. style
|
||||
state = SCE_SQL_COMMENTDOC;
|
||||
} else {
|
||||
state = SCE_SQL_COMMENT;
|
||||
}
|
||||
} else if (ch == '-' && chNext == '-') {
|
||||
state = SCE_SQL_COMMENTLINE;
|
||||
} else if (ch == '#') {
|
||||
state = SCE_SQL_COMMENTLINEDOC;
|
||||
} else if (MatchIgnoreCaseSubstring("rem~ark", styler, i)) {
|
||||
state = SCE_SQL_SQLPLUS_COMMENT;
|
||||
} else if (MatchIgnoreCaseSubstring("pro~mpt", styler, i)) {
|
||||
state = SCE_SQL_SQLPLUS_PROMPT;
|
||||
} else if (ch == '\'') {
|
||||
state = SCE_SQL_CHARACTER;
|
||||
} else if (ch == '"') {
|
||||
state = SCE_SQL_STRING;
|
||||
} else if (iswordstart(ch)) {
|
||||
state = SCE_SQL_WORD;
|
||||
} else if (isoperator(ch)) {
|
||||
styler.ColourTo(i, SCE_SQL_OPERATOR);
|
||||
break;
|
||||
case SCE_SQL_COMMENTLINE:
|
||||
case SCE_SQL_COMMENTLINEDOC:
|
||||
case SCE_SQL_SQLPLUS_COMMENT:
|
||||
case SCE_SQL_SQLPLUS_PROMPT:
|
||||
if (sc.atLineStart) {
|
||||
sc.SetState(SCE_SQL_DEFAULT);
|
||||
}
|
||||
break;
|
||||
case SCE_SQL_COMMENTDOCKEYWORD:
|
||||
if ((styleBeforeDCKeyword == SCE_SQL_COMMENTDOC) && sc.Match('*', '/')) {
|
||||
sc.ChangeState(SCE_SQL_COMMENTDOCKEYWORDERROR);
|
||||
sc.Forward();
|
||||
sc.ForwardSetState(SCE_SQL_DEFAULT);
|
||||
} else if (!IsADoxygenChar(sc.ch)) {
|
||||
char s[100];
|
||||
sc.GetCurrentLowered(s, sizeof(s));
|
||||
if (!isspace(sc.ch) || !kw_pldoc.InList(s + 1)) {
|
||||
sc.ChangeState(SCE_SQL_COMMENTDOCKEYWORDERROR);
|
||||
}
|
||||
sc.SetState(styleBeforeDCKeyword);
|
||||
}
|
||||
break;
|
||||
case SCE_SQL_CHARACTER:
|
||||
if (sqlBackslashEscapes && sc.ch == '\\') {
|
||||
sc.Forward();
|
||||
} else if (sc.ch == '\'') {
|
||||
if (sc.chNext == '\"') {
|
||||
sc.Forward();
|
||||
} else {
|
||||
sc.ForwardSetState(SCE_SQL_DEFAULT);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SCE_SQL_STRING:
|
||||
if (sc.ch == '\\') {
|
||||
// Escape sequence
|
||||
sc.Forward();
|
||||
} else if (sc.ch == '\"') {
|
||||
if (sc.chNext == '\"') {
|
||||
sc.Forward();
|
||||
} else {
|
||||
sc.ForwardSetState(SCE_SQL_DEFAULT);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Determine if a new state should be entered.
|
||||
if (sc.state == SCE_SQL_DEFAULT) {
|
||||
if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
|
||||
sc.SetState(SCE_SQL_NUMBER);
|
||||
} else if (IsAWordStart(sc.ch)) {
|
||||
sc.SetState(SCE_SQL_IDENTIFIER);
|
||||
} else if (sc.ch == 0x60 && sqlBackticksIdentifier) {
|
||||
sc.SetState(SCE_SQL_QUOTEDIDENTIFIER);
|
||||
} else if (sc.Match('/', '*')) {
|
||||
if (sc.Match("/**") || sc.Match("/*!")) { // Support of Doxygen doc. style
|
||||
sc.SetState(SCE_SQL_COMMENTDOC);
|
||||
} else {
|
||||
sc.SetState(SCE_SQL_COMMENT);
|
||||
}
|
||||
sc.Forward(); // Eat the * so it isn't used for the end of the comment
|
||||
} else if (sc.Match('-', '-')) {
|
||||
// MySQL requires a space or control char after --
|
||||
// http://dev.mysql.com/doc/mysql/en/ansi-diff-comments.html
|
||||
// Perhaps we should enforce that with proper property:
|
||||
//~ } else if (sc.Match("-- ")) {
|
||||
sc.SetState(SCE_SQL_COMMENTLINE);
|
||||
} else if (sc.ch == '#') {
|
||||
sc.SetState(SCE_SQL_COMMENTLINEDOC);
|
||||
} else if (sc.ch == '\'') {
|
||||
sc.SetState(SCE_SQL_CHARACTER);
|
||||
} else if (sc.ch == '\"') {
|
||||
sc.SetState(SCE_SQL_STRING);
|
||||
} else if (isoperator(static_cast<char>(sc.ch))) {
|
||||
sc.SetState(SCE_SQL_OPERATOR);
|
||||
}
|
||||
}
|
||||
chPrev = ch;
|
||||
}
|
||||
styler.ColourTo(lengthDoc - 1, state);
|
||||
sc.Complete();
|
||||
}
|
||||
|
||||
static bool IsStreamCommentStyle(int style) {
|
||||
@ -312,18 +237,18 @@ static bool IsStreamCommentStyle(int style) {
|
||||
}
|
||||
|
||||
// Store both the current line's fold level and the next lines in the
|
||||
// level store to make it easy to pick up with each increment
|
||||
// and to make it possible to fiddle the current level for "} else {".
|
||||
// level store to make it easy to pick up with each increment.
|
||||
static void FoldSQLDoc(unsigned int startPos, int length, int initStyle,
|
||||
WordList *[], Accessor &styler) {
|
||||
WordList *[], Accessor &styler) {
|
||||
bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
|
||||
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
|
||||
unsigned int endPos = startPos + length;
|
||||
int visibleChars = 0;
|
||||
int lineCurrent = styler.GetLine(startPos);
|
||||
int levelCurrent = SC_FOLDLEVELBASE;
|
||||
if (lineCurrent > 0)
|
||||
levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
|
||||
if (lineCurrent > 0) {
|
||||
levelCurrent = styler.LevelAt(lineCurrent - 1) >> 16;
|
||||
}
|
||||
int levelNext = levelCurrent;
|
||||
char chNext = styler[startPos];
|
||||
int styleNext = styler.StyleAt(startPos);
|
||||
@ -345,34 +270,58 @@ static void FoldSQLDoc(unsigned int startPos, int length, int initStyle,
|
||||
}
|
||||
}
|
||||
if (foldComment && (style == SCE_SQL_COMMENTLINE)) {
|
||||
// MySQL needs -- comments to be followed by space or control char
|
||||
if ((ch == '-') && (chNext == '-')) {
|
||||
char chNext2 = styler.SafeGetCharAt(i + 2);
|
||||
if (chNext2 == '{') {
|
||||
char chNext3 = styler.SafeGetCharAt(i + 3);
|
||||
if (chNext2 == '{' || chNext3 == '{') {
|
||||
levelNext++;
|
||||
} else if (chNext2 == '}') {
|
||||
} else if (chNext2 == '}' || chNext3 == '}') {
|
||||
levelNext--;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (style == SCE_SQL_WORD) {
|
||||
if (MatchIgnoreCaseSubstring("elsif", styler, i)) {
|
||||
// ignore elsif
|
||||
i += 4;
|
||||
} else if (MatchIgnoreCaseSubstring("if", styler, i)
|
||||
|| MatchIgnoreCaseSubstring("loop", styler, i)){
|
||||
if (endFound){
|
||||
// ignore
|
||||
endFound = false;
|
||||
} else {
|
||||
levelNext++;
|
||||
}
|
||||
} else if (MatchIgnoreCaseSubstring("begin", styler, i)){
|
||||
if (style == SCE_SQL_OPERATOR) {
|
||||
if (ch == '(') {
|
||||
levelNext++;
|
||||
} else if (MatchIgnoreCaseSubstring("end", styler, i)) {
|
||||
} else if (ch == ')') {
|
||||
levelNext--;
|
||||
}
|
||||
}
|
||||
// If new keyword (cannot trigger on elseif or nullif, does less tests)
|
||||
if (style == SCE_SQL_WORD && stylePrev != SCE_SQL_WORD) {
|
||||
const int MAX_KW_LEN = 6; // Maximum length of folding keywords
|
||||
char s[MAX_KW_LEN + 2];
|
||||
unsigned int j = 0;
|
||||
for (; j < MAX_KW_LEN + 1; j++) {
|
||||
if (!iswordchar(styler[i + j])) {
|
||||
break;
|
||||
}
|
||||
s[j] = static_cast<char>(tolower(styler[i + j]));
|
||||
}
|
||||
if (j == MAX_KW_LEN + 1) {
|
||||
// Keyword too long, don't test it
|
||||
s[0] = '\0';
|
||||
} else {
|
||||
s[j] = '\0';
|
||||
}
|
||||
if (strcmp(s, "if") == 0 || strcmp(s, "loop") == 0) {
|
||||
if (endFound) {
|
||||
// ignore
|
||||
endFound = false;
|
||||
} else {
|
||||
levelNext++;
|
||||
}
|
||||
} else if (strcmp(s, "begin") == 0) {
|
||||
levelNext++;
|
||||
} else if (strcmp(s, "end") == 0 ||
|
||||
// DROP TABLE IF EXISTS or CREATE TABLE IF NOT EXISTS
|
||||
strcmp(s, "exists") == 0) {
|
||||
endFound = true;
|
||||
levelNext--;
|
||||
if (levelNext < SC_FOLDLEVELBASE)
|
||||
if (levelNext < SC_FOLDLEVELBASE) {
|
||||
levelNext = SC_FOLDLEVELBASE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (atEOL) {
|
||||
@ -390,8 +339,9 @@ static void FoldSQLDoc(unsigned int startPos, int length, int initStyle,
|
||||
visibleChars = 0;
|
||||
endFound = false;
|
||||
}
|
||||
if (!isspacechar(ch))
|
||||
if (!isspacechar(ch)) {
|
||||
visibleChars++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,7 @@ LexSQL.cxx
|
||||
SRCS= \
|
||||
CallTip.cxx \
|
||||
CellBuffer.cxx \
|
||||
CharClassify.cxx \
|
||||
ContractionState.cxx \
|
||||
DocumentAccessor.cxx \
|
||||
Document.cxx \
|
||||
|
@ -192,10 +192,14 @@ Palette::Palette() {
|
||||
allowRealization = false;
|
||||
allocatedPalette = 0;
|
||||
allocatedLen = 0;
|
||||
size = 100;
|
||||
entries = new ColourPair[size];
|
||||
}
|
||||
|
||||
Palette::~Palette() {
|
||||
Release();
|
||||
delete []entries;
|
||||
entries = 0;
|
||||
}
|
||||
|
||||
void Palette::Release() {
|
||||
@ -203,6 +207,9 @@ void Palette::Release() {
|
||||
delete [](reinterpret_cast<GdkColor *>(allocatedPalette));
|
||||
allocatedPalette = 0;
|
||||
allocatedLen = 0;
|
||||
delete []entries;
|
||||
size = 100;
|
||||
entries = new ColourPair[size];
|
||||
}
|
||||
|
||||
// This method either adds a colour to the list of wanted colours (want==true)
|
||||
@ -210,18 +217,27 @@ void Palette::Release() {
|
||||
// This is one method to make it easier to keep the code for wanting and retrieving in sync.
|
||||
void Palette::WantFind(ColourPair &cp, bool want) {
|
||||
if (want) {
|
||||
for (int i = 0; i < used; i++) {
|
||||
for (int i=0; i < used; i++) {
|
||||
if (entries[i].desired == cp.desired)
|
||||
return;
|
||||
}
|
||||
|
||||
if (used < numEntries) {
|
||||
entries[used].desired = cp.desired;
|
||||
entries[used].allocated.Set(cp.desired.AsLong());
|
||||
used++;
|
||||
if (used >= size) {
|
||||
int sizeNew = size * 2;
|
||||
ColourPair *entriesNew = new ColourPair[sizeNew];
|
||||
for (int j=0; j<size; j++) {
|
||||
entriesNew[j] = entries[j];
|
||||
}
|
||||
delete []entries;
|
||||
entries = entriesNew;
|
||||
size = sizeNew;
|
||||
}
|
||||
|
||||
entries[used].desired = cp.desired;
|
||||
entries[used].allocated.Set(cp.desired.AsLong());
|
||||
used++;
|
||||
} else {
|
||||
for (int i = 0; i < used; i++) {
|
||||
for (int i=0; i < used; i++) {
|
||||
if (entries[i].desired == cp.desired) {
|
||||
cp.allocated = entries[i].allocated;
|
||||
return;
|
||||
@ -697,6 +713,8 @@ public:
|
||||
void FillRectangle(PRectangle rc, ColourAllocated back);
|
||||
void FillRectangle(PRectangle rc, Surface &surfacePattern);
|
||||
void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back);
|
||||
void AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated fill, int alphaFill,
|
||||
ColourAllocated outline, int alphaOutline, int flags);
|
||||
void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back);
|
||||
void Copy(PRectangle rc, Point from, Surface &surfaceSource);
|
||||
|
||||
@ -998,6 +1016,88 @@ void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAl
|
||||
}
|
||||
}
|
||||
|
||||
// Plot a point into a guint32 buffer symetrically to all 4 qudrants
|
||||
static void AllFour(guint32 *pixels, int stride, int width, int height, int x, int y, guint32 val) {
|
||||
pixels[y*stride+x] = val;
|
||||
pixels[y*stride+width-1-x] = val;
|
||||
pixels[(height-1-y)*stride+x] = val;
|
||||
pixels[(height-1-y)*stride+width-1-x] = val;
|
||||
}
|
||||
|
||||
static unsigned int GetRValue(unsigned int co) {
|
||||
return (co >> 16) & 0xff;
|
||||
}
|
||||
|
||||
static unsigned int GetGValue(unsigned int co) {
|
||||
return (co >> 8) & 0xff;
|
||||
}
|
||||
|
||||
static unsigned int GetBValue(unsigned int co) {
|
||||
return co & 0xff;
|
||||
}
|
||||
|
||||
#if GTK_MAJOR_VERSION < 2
|
||||
void SurfaceImpl::AlphaRectangle(PRectangle rc, int , ColourAllocated , int , ColourAllocated outline, int , int ) {
|
||||
if (gc && drawable) {
|
||||
// Can't use GdkPixbuf on GTK+ 1.x, so draw an outline rather than use alpha.
|
||||
PenColour(outline);
|
||||
gdk_draw_rectangle(drawable, gc, 0,
|
||||
rc.left, rc.top,
|
||||
rc.right - rc.left - 1, rc.bottom - rc.top - 1);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated fill, int alphaFill,
|
||||
ColourAllocated outline, int alphaOutline, int flags) {
|
||||
if (gc && drawable) {
|
||||
int width = rc.Width();
|
||||
int height = rc.Height();
|
||||
// Ensure not distorted too much by corners when small
|
||||
cornerSize = Platform::Minimum(cornerSize, (Platform::Minimum(width, height) / 2) - 2);
|
||||
// Make a 32 bit deep pixbuf with alpha
|
||||
GdkPixbuf *pixalpha = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, width, height);
|
||||
|
||||
guint8 pixVal[4] = {0};
|
||||
guint32 valEmpty = *(reinterpret_cast<guint32 *>(pixVal));
|
||||
pixVal[0] = GetRValue(fill.AsLong());
|
||||
pixVal[1] = GetGValue(fill.AsLong());
|
||||
pixVal[2] = GetBValue(fill.AsLong());
|
||||
pixVal[3] = alphaFill;
|
||||
guint32 valFill = *(reinterpret_cast<guint32 *>(pixVal));
|
||||
pixVal[0] = GetRValue(outline.AsLong());
|
||||
pixVal[1] = GetGValue(outline.AsLong());
|
||||
pixVal[2] = GetBValue(outline.AsLong());
|
||||
pixVal[3] = alphaOutline;
|
||||
guint32 valOutline = *(reinterpret_cast<guint32 *>(pixVal));
|
||||
guint32 *pixels = reinterpret_cast<guint32 *>(gdk_pixbuf_get_pixels(pixalpha));
|
||||
int stride = gdk_pixbuf_get_rowstride(pixalpha) / 4;
|
||||
for (int y=0; y<height; y++) {
|
||||
for (int x=0; x<width; x++) {
|
||||
if ((x==0) || (x==width-1) || (y == 0) || (y == height-1)) {
|
||||
pixels[y*stride+x] = valOutline;
|
||||
} else {
|
||||
pixels[y*stride+x] = valFill;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int c=0;c<cornerSize; c++) {
|
||||
for (int x=0;x<c+1; x++) {
|
||||
AllFour(pixels, stride, width, height, x, c-x, valEmpty);
|
||||
}
|
||||
}
|
||||
for (int x=1;x<cornerSize; x++) {
|
||||
AllFour(pixels, stride, width, height, x, cornerSize-x, valOutline);
|
||||
}
|
||||
|
||||
// Draw with alpha
|
||||
gdk_draw_pixbuf(drawable, gc, pixalpha,
|
||||
0,0, rc.left,rc.top, width,height, GDK_RGB_DITHER_NORMAL, 0, 0);
|
||||
|
||||
g_object_unref(pixalpha);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void SurfaceImpl::Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
|
||||
PenColour(back);
|
||||
gdk_draw_arc(drawable, gc, 1,
|
||||
@ -2367,7 +2467,7 @@ void Menu::Show(Point pt, Window &) {
|
||||
pt.y = screenHeight - requisition.height;
|
||||
}
|
||||
#if GTK_MAJOR_VERSION >= 2
|
||||
gtk_item_factory_popup(factory, pt.x - 4, pt.y - 4, 3,
|
||||
gtk_item_factory_popup(factory, pt.x - 4, pt.y - 4, 3,
|
||||
gtk_get_current_event_time());
|
||||
#else
|
||||
gtk_item_factory_popup(factory, pt.x - 4, pt.y - 4, 3, 0);
|
||||
|
@ -4,7 +4,7 @@
|
||||
**/
|
||||
|
||||
/*
|
||||
* regex - Regular expression pattern matching and replacement
|
||||
* regex - Regular expression pattern matching and replacement
|
||||
*
|
||||
* By: Ozan S. Yigit (oz)
|
||||
* Dept. of Computer Science
|
||||
@ -15,7 +15,7 @@
|
||||
* Removed all use of register.
|
||||
* Converted to modern function prototypes.
|
||||
* Put all global/static variables into an object so this code can be
|
||||
* used from multiple threads etc.
|
||||
* used from multiple threads, etc.
|
||||
*
|
||||
* These routines are the PUBLIC DOMAIN equivalents of regex
|
||||
* routines as found in 4.nBSD UN*X, with minor extensions.
|
||||
@ -30,64 +30,62 @@
|
||||
* Modification history removed.
|
||||
*
|
||||
* Interfaces:
|
||||
* RESearch::Compile: compile a regular expression into a NFA.
|
||||
* RESearch::Compile: compile a regular expression into a NFA.
|
||||
*
|
||||
* char *RESearch::Compile(s)
|
||||
* char *s;
|
||||
* const char *RESearch::Compile(const char *pat, int length,
|
||||
* bool caseSensitive, bool posix)
|
||||
*
|
||||
* RESearch::Execute: execute the NFA to match a pattern.
|
||||
* Returns a short error string if they fail.
|
||||
*
|
||||
* int RESearch::Execute(s)
|
||||
* char *s;
|
||||
* RESearch::Execute: execute the NFA to match a pattern.
|
||||
*
|
||||
* RESearch::ModifyWord change RESearch::Execute's understanding of what a "word"
|
||||
* looks like (for \< and \>) by adding into the
|
||||
* hidden word-syntax table.
|
||||
* int RESearch::Execute(characterIndexer &ci, int lp, int endp)
|
||||
*
|
||||
* void RESearch::ModifyWord(s)
|
||||
* char *s;
|
||||
* RESearch::Substitute: substitute the matched portions in a new string.
|
||||
*
|
||||
* RESearch::Substitute: substitute the matched portions in a new string.
|
||||
* int RESearch::Substitute(CharacterIndexer &ci, char *src, char *dst)
|
||||
*
|
||||
* int RESearch::Substitute(src, dst)
|
||||
* char *src;
|
||||
* char *dst;
|
||||
* re_fail: failure routine for RESearch::Execute. (no longer used)
|
||||
*
|
||||
* re_fail: failure routine for RESearch::Execute.
|
||||
*
|
||||
* void re_fail(msg, op)
|
||||
* char *msg;
|
||||
* char op;
|
||||
* void re_fail(char *msg, char op)
|
||||
*
|
||||
* Regular Expressions:
|
||||
*
|
||||
* [1] char matches itself, unless it is a special
|
||||
* character (metachar): . \ [ ] * + ^ $
|
||||
* and ( ) if posix option.
|
||||
*
|
||||
* [2] . matches any character.
|
||||
*
|
||||
* [3] \ matches the character following it, except
|
||||
* when followed by a left or right round bracket,
|
||||
* a digit 1 to 9 or a left or right angle bracket.
|
||||
* (see [7], [8] and [9])
|
||||
* It is used as an escape character for all
|
||||
* other meta-characters, and itself. When used
|
||||
* in a set ([4]), it is treated as an ordinary
|
||||
* character.
|
||||
* [3] \ matches the character following it, except:
|
||||
* - \a, \b, \f, \n, \t, \v match the
|
||||
* corresponding C escape char;
|
||||
* - if not in posix mode, when followed by a
|
||||
* left or right round bracket (see [7]);
|
||||
* - when followed by a digit 1 to 9 (see [8]);
|
||||
* - when followed by a left or right angle bracket
|
||||
* (see [9]).
|
||||
* It is used as an escape character for all
|
||||
* other meta-characters, and itself. When used
|
||||
* in a set ([4]), it is treated as an ordinary
|
||||
* character (except for escape chars).
|
||||
*
|
||||
* [4] [set] matches one of the characters in the set.
|
||||
* If the first character in the set is "^",
|
||||
* it matches a character NOT in the set, i.e.
|
||||
* complements the set. A shorthand S-E is
|
||||
* used to specify a set of characters S upto
|
||||
* E, inclusive. The special characters "]" and
|
||||
* "-" have no special meaning if they appear
|
||||
* as the first chars in the set.
|
||||
* complements the set. A shorthand S-E (start-end)
|
||||
* is used to specify a set of characters S upto
|
||||
* E, inclusive. The special characters "]" and
|
||||
* "-" have no special meaning if they appear
|
||||
* as the first chars in the set. To include both,
|
||||
* put - first: [-]A-Z]:
|
||||
* [-]|] matches these 2 chars,
|
||||
* []-|] matches from ] to | chars.
|
||||
* examples: match:
|
||||
*
|
||||
* [a-z] any lowercase alpha
|
||||
*
|
||||
* [^]-] any char except ] and -
|
||||
* [^-]] any char except - and ]
|
||||
*
|
||||
* [^A-Z] any char except uppercase
|
||||
* alpha
|
||||
@ -101,81 +99,87 @@
|
||||
* [6] + same as [5], except it matches one or more.
|
||||
*
|
||||
* [7] a regular expression in the form [1] to [10], enclosed
|
||||
* as \(form\) matches what form matches. The enclosure
|
||||
* creates a set of tags, used for [8] and for
|
||||
* pattern substution. The tagged forms are numbered
|
||||
* starting from 1.
|
||||
* as \(form\) (or (form) with posix flag) matches what
|
||||
* form matches. The enclosure creates a set of tags,
|
||||
* used for [8] and for pattern substitution.
|
||||
* The tagged forms are numbered starting from 1.
|
||||
*
|
||||
* [8] a \ followed by a digit 1 to 9 matches whatever a
|
||||
* previously tagged regular expression ([7]) matched.
|
||||
*
|
||||
* [9] \< a regular expression starting with a \< construct
|
||||
* \> and/or ending with a \> construct, restricts the
|
||||
* pattern matching to the beginning of a word, and/or
|
||||
* the end of a word. A word is defined to be a character
|
||||
* string beginning and/or ending with the characters
|
||||
* A-Z a-z 0-9 and _. It must also be preceded and/or
|
||||
* followed by any character outside those mentioned.
|
||||
* [9] \< a regular expression starting with a \< construct
|
||||
* \> and/or ending with a \> construct, restricts the
|
||||
* pattern matching to the beginning of a word, and/or
|
||||
* the end of a word. A word is defined to be a character
|
||||
* string beginning and/or ending with the characters
|
||||
* A-Z a-z 0-9 and _. It must also be preceded and/or
|
||||
* followed by any character outside those mentioned.
|
||||
*
|
||||
* [10] a composite regular expression xy where x and y
|
||||
* are in the form [1] to [10] matches the longest
|
||||
* match of x followed by a match for y.
|
||||
*
|
||||
* [11] ^ a regular expression starting with a ^ character
|
||||
* $ and/or ending with a $ character, restricts the
|
||||
* [11] ^ a regular expression starting with a ^ character
|
||||
* $ and/or ending with a $ character, restricts the
|
||||
* pattern matching to the beginning of the line,
|
||||
* or the end of line. [anchors] Elsewhere in the
|
||||
* pattern, ^ and $ are treated as ordinary characters.
|
||||
* pattern, ^ and $ are treated as ordinary characters.
|
||||
*
|
||||
*
|
||||
* Acknowledgements:
|
||||
*
|
||||
* HCR's Hugh Redelmeier has been most helpful in various
|
||||
* stages of development. He convinced me to include BOW
|
||||
* and EOW constructs, originally invented by Rob Pike at
|
||||
* the University of Toronto.
|
||||
* HCR's Hugh Redelmeier has been most helpful in various
|
||||
* stages of development. He convinced me to include BOW
|
||||
* and EOW constructs, originally invented by Rob Pike at
|
||||
* the University of Toronto.
|
||||
*
|
||||
* References:
|
||||
* Software tools Kernighan & Plauger
|
||||
* Software tools Kernighan & Plauger
|
||||
* Software tools in Pascal Kernighan & Plauger
|
||||
* Grep [rsx-11 C dist] David Conroy
|
||||
* ed - text editor Un*x Programmer's Manual
|
||||
* Advanced editing on Un*x B. W. Kernighan
|
||||
* RegExp routines Henry Spencer
|
||||
* ed - text editor Un*x Programmer's Manual
|
||||
* Advanced editing on Un*x B. W. Kernighan
|
||||
* RegExp routines Henry Spencer
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* This implementation uses a bit-set representation for character
|
||||
* classes for speed and compactness. Each character is represented
|
||||
* by one bit in a 128-bit block. Thus, CCL always takes a
|
||||
* constant 16 bytes in the internal nfa, and RESearch::Execute does a single
|
||||
* by one bit in a 256-bit block. Thus, CCL always takes a
|
||||
* constant 32 bytes in the internal nfa, and RESearch::Execute does a single
|
||||
* bit comparison to locate the character in the set.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* pattern: foo*.*
|
||||
* compile: CHR f CHR o CLO CHR o END CLO ANY END END
|
||||
* matches: fo foo fooo foobar fobar foxx ...
|
||||
* pattern: foo*.*
|
||||
* compile: CHR f CHR o CLO CHR o END CLO ANY END END
|
||||
* matches: fo foo fooo foobar fobar foxx ...
|
||||
*
|
||||
* pattern: fo[ob]a[rz]
|
||||
* compile: CHR f CHR o CCL bitset CHR a CCL bitset END
|
||||
* matches: fobar fooar fobaz fooaz
|
||||
* pattern: fo[ob]a[rz]
|
||||
* compile: CHR f CHR o CCL bitset CHR a CCL bitset END
|
||||
* matches: fobar fooar fobaz fooaz
|
||||
*
|
||||
* pattern: foo\\+
|
||||
* compile: CHR f CHR o CHR o CHR \ CLO CHR \ END END
|
||||
* matches: foo\ foo\\ foo\\\ ...
|
||||
* pattern: foo\\+
|
||||
* compile: CHR f CHR o CHR o CHR \ CLO CHR \ END END
|
||||
* matches: foo\ foo\\ foo\\\ ...
|
||||
*
|
||||
* pattern: \(foo\)[1-3]\1 (same as foo[1-3]foo)
|
||||
* compile: BOT 1 CHR f CHR o CHR o EOT 1 CCL bitset REF 1 END
|
||||
* matches: foo1foo foo2foo foo3foo
|
||||
* pattern: \(foo\)[1-3]\1 (same as foo[1-3]foo)
|
||||
* compile: BOT 1 CHR f CHR o CHR o EOT 1 CCL bitset REF 1 END
|
||||
* matches: foo1foo foo2foo foo3foo
|
||||
*
|
||||
* pattern: \(fo.*\)-\1
|
||||
* compile: BOT 1 CHR f CHR o CLO ANY END EOT 1 CHR - REF 1 END
|
||||
* matches: foo-foo fo-fo fob-fob foobar-foobar ...
|
||||
* pattern: \(fo.*\)-\1
|
||||
* compile: BOT 1 CHR f CHR o CLO ANY END EOT 1 CHR - REF 1 END
|
||||
* matches: foo-foo fo-fo fob-fob foobar-foobar ...
|
||||
*/
|
||||
|
||||
#include "CharClassify.h"
|
||||
#include "RESearch.h"
|
||||
|
||||
// Shut up annoying Visual C++ warnings:
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable: 4514)
|
||||
#endif
|
||||
|
||||
#define OKP 1
|
||||
#define NOP 0
|
||||
|
||||
@ -186,8 +190,8 @@
|
||||
#define EOL 5
|
||||
#define BOT 6
|
||||
#define EOT 7
|
||||
#define BOW 8
|
||||
#define EOW 9
|
||||
#define BOW 8
|
||||
#define EOW 9
|
||||
#define REF 10
|
||||
#define CLO 11
|
||||
|
||||
@ -197,16 +201,22 @@
|
||||
* The following defines are not meant to be changeable.
|
||||
* They are for readability only.
|
||||
*/
|
||||
#define BLKIND 0370
|
||||
#define BITIND 07
|
||||
|
||||
#define ASCIIB 0177
|
||||
#define BLKIND 0370
|
||||
#define BITIND 07
|
||||
|
||||
const char bitarr[] = {1,2,4,8,16,32,64,'\200'};
|
||||
|
||||
#define badpat(x) (*nfa = END, x)
|
||||
|
||||
RESearch::RESearch() {
|
||||
/*
|
||||
* Character classification table for word boundary operators BOW
|
||||
* and EOW is passed in by the creator of this object (Scintilla
|
||||
* Document). The Document default state is that word chars are:
|
||||
* 0-9,a-z, A-Z and _
|
||||
*/
|
||||
|
||||
RESearch::RESearch(CharClassify *charClassTable) {
|
||||
charClass = charClassTable;
|
||||
Init();
|
||||
}
|
||||
|
||||
@ -215,7 +225,7 @@ RESearch::~RESearch() {
|
||||
}
|
||||
|
||||
void RESearch::Init() {
|
||||
sta = NOP; /* status of lastpat */
|
||||
sta = NOP; /* status of lastpat */
|
||||
bol = 0;
|
||||
for (int i=0; i<MAXTAG; i++)
|
||||
pat[i] = 0;
|
||||
@ -285,15 +295,15 @@ const char escapeValue(char ch) {
|
||||
|
||||
const char *RESearch::Compile(const char *pat, int length, bool caseSensitive, bool posix) {
|
||||
char *mp=nfa; /* nfa pointer */
|
||||
char *lp; /* saved pointer.. */
|
||||
char *sp=nfa; /* another one.. */
|
||||
char *mpMax = mp + MAXNFA - BITBLK - 10;
|
||||
char *lp; /* saved pointer */
|
||||
char *sp=nfa; /* another one */
|
||||
char *mpMax = mp + MAXNFA - BITBLK - 10;
|
||||
|
||||
int tagi = 0; /* tag stack index */
|
||||
int tagc = 1; /* actual tag count */
|
||||
|
||||
int n;
|
||||
char mask; /* xor mask -CCL/NCL */
|
||||
char mask; /* xor mask -CCL/NCL */
|
||||
int c1, c2;
|
||||
|
||||
if (!pat || !length)
|
||||
@ -303,18 +313,18 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive, b
|
||||
return badpat("No previous regular expression");
|
||||
sta = NOP;
|
||||
|
||||
const char *p=pat; /* pattern pointer */
|
||||
const char *p=pat; /* pattern pointer */
|
||||
for (int i=0; i<length; i++, p++) {
|
||||
if (mp > mpMax)
|
||||
return badpat("Pattern too long");
|
||||
lp = mp;
|
||||
switch(*p) {
|
||||
|
||||
case '.': /* match any char.. */
|
||||
case '.': /* match any char */
|
||||
*mp++ = ANY;
|
||||
break;
|
||||
|
||||
case '^': /* match beginning.. */
|
||||
case '^': /* match beginning */
|
||||
if (p == pat)
|
||||
*mp++ = BOL;
|
||||
else {
|
||||
@ -323,7 +333,7 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive, b
|
||||
}
|
||||
break;
|
||||
|
||||
case '$': /* match endofline.. */
|
||||
case '$': /* match endofline */
|
||||
if (!*(p+1))
|
||||
*mp++ = EOL;
|
||||
else {
|
||||
@ -332,7 +342,7 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive, b
|
||||
}
|
||||
break;
|
||||
|
||||
case '[': /* match char class..*/
|
||||
case '[': /* match char class */
|
||||
*mp++ = CCL;
|
||||
|
||||
i++;
|
||||
@ -343,7 +353,7 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive, b
|
||||
} else
|
||||
mask = 0;
|
||||
|
||||
if (*p == '-') { /* real dash */
|
||||
if (*p == '-') { /* real dash */
|
||||
i++;
|
||||
ChSet(*p++);
|
||||
}
|
||||
@ -384,12 +394,12 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive, b
|
||||
|
||||
break;
|
||||
|
||||
case '*': /* match 0 or more.. */
|
||||
case '+': /* match 1 or more.. */
|
||||
case '*': /* match 0 or more... */
|
||||
case '+': /* match 1 or more... */
|
||||
if (p == pat)
|
||||
return badpat("Empty closure");
|
||||
lp = sp; /* previous opcode */
|
||||
if (*lp == CLO) /* equivalence.. */
|
||||
if (*lp == CLO) /* equivalence... */
|
||||
break;
|
||||
switch(*lp) {
|
||||
|
||||
@ -417,7 +427,7 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive, b
|
||||
mp = sp;
|
||||
break;
|
||||
|
||||
case '\\': /* tags, backrefs .. */
|
||||
case '\\': /* tags, backrefs... */
|
||||
i++;
|
||||
switch(*++p) {
|
||||
|
||||
@ -483,7 +493,7 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive, b
|
||||
}
|
||||
break;
|
||||
|
||||
default : /* an ordinary char */
|
||||
default : /* an ordinary char */
|
||||
if (posix && *p == '(') {
|
||||
if (tagc < MAXTAG) {
|
||||
tagstk[++tagi] = tagc;
|
||||
@ -524,23 +534,23 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive, b
|
||||
|
||||
/*
|
||||
* RESearch::Execute:
|
||||
* execute nfa to find a match.
|
||||
* execute nfa to find a match.
|
||||
*
|
||||
* special cases: (nfa[0])
|
||||
* BOL
|
||||
* Match only once, starting from the
|
||||
* beginning.
|
||||
* CHR
|
||||
* First locate the character without
|
||||
* calling PMatch, and if found, call
|
||||
* PMatch for the remaining string.
|
||||
* END
|
||||
* RESearch::Compile failed, poor luser did not
|
||||
* check for it. Fail fast.
|
||||
* special cases: (nfa[0])
|
||||
* BOL
|
||||
* Match only once, starting from the
|
||||
* beginning.
|
||||
* CHR
|
||||
* First locate the character without
|
||||
* calling PMatch, and if found, call
|
||||
* PMatch for the remaining string.
|
||||
* END
|
||||
* RESearch::Compile failed, poor luser did not
|
||||
* check for it. Fail fast.
|
||||
*
|
||||
* If a match is found, bopat[0] and eopat[0] are set
|
||||
* to the beginning and the end of the matched fragment,
|
||||
* respectively.
|
||||
* If a match is found, bopat[0] and eopat[0] are set
|
||||
* to the beginning and the end of the matched fragment,
|
||||
* respectively.
|
||||
*
|
||||
*/
|
||||
|
||||
@ -571,7 +581,7 @@ int RESearch::Execute(CharacterIndexer &ci, int lp, int endp) {
|
||||
c = *(ap+1);
|
||||
while ((lp < endp) && (ci.CharAt(lp) != c))
|
||||
lp++;
|
||||
if (lp >= endp) /* if EOS, fail, else fall thru. */
|
||||
if (lp >= endp) /* if EOS, fail, else fall thru. */
|
||||
return 0;
|
||||
default: /* regular matching all the way. */
|
||||
while (lp < endp) {
|
||||
@ -595,78 +605,50 @@ int RESearch::Execute(CharacterIndexer &ci, int lp, int endp) {
|
||||
/*
|
||||
* PMatch: internal routine for the hard part
|
||||
*
|
||||
* This code is partly snarfed from an early grep written by
|
||||
* David Conroy. The backref and tag stuff, and various other
|
||||
* innovations are by oz.
|
||||
* This code is partly snarfed from an early grep written by
|
||||
* David Conroy. The backref and tag stuff, and various other
|
||||
* innovations are by oz.
|
||||
*
|
||||
* special case optimizations: (nfa[n], nfa[n+1])
|
||||
* CLO ANY
|
||||
* We KNOW .* will match everything upto the
|
||||
* end of line. Thus, directly go to the end of
|
||||
* line, without recursive PMatch calls. As in
|
||||
* the other closure cases, the remaining pattern
|
||||
* must be matched by moving backwards on the
|
||||
* string recursively, to find a match for xy
|
||||
* (x is ".*" and y is the remaining pattern)
|
||||
* where the match satisfies the LONGEST match for
|
||||
* x followed by a match for y.
|
||||
* CLO CHR
|
||||
* We can again scan the string forward for the
|
||||
* single char and at the point of failure, we
|
||||
* execute the remaining nfa recursively, same as
|
||||
* above.
|
||||
*
|
||||
* At the end of a successful match, bopat[n] and eopat[n]
|
||||
* are set to the beginning and end of subpatterns matched
|
||||
* by tagged expressions (n = 1 to 9).
|
||||
* special case optimizations: (nfa[n], nfa[n+1])
|
||||
* CLO ANY
|
||||
* We KNOW .* will match everything upto the
|
||||
* end of line. Thus, directly go to the end of
|
||||
* line, without recursive PMatch calls. As in
|
||||
* the other closure cases, the remaining pattern
|
||||
* must be matched by moving backwards on the
|
||||
* string recursively, to find a match for xy
|
||||
* (x is ".*" and y is the remaining pattern)
|
||||
* where the match satisfies the LONGEST match for
|
||||
* x followed by a match for y.
|
||||
* CLO CHR
|
||||
* We can again scan the string forward for the
|
||||
* single char and at the point of failure, we
|
||||
* execute the remaining nfa recursively, same as
|
||||
* above.
|
||||
*
|
||||
* At the end of a successful match, bopat[n] and eopat[n]
|
||||
* are set to the beginning and end of subpatterns matched
|
||||
* by tagged expressions (n = 1 to 9).
|
||||
*/
|
||||
|
||||
extern void re_fail(char *,char);
|
||||
|
||||
/*
|
||||
* character classification table for word boundary operators BOW
|
||||
* and EOW. the reason for not using ctype macros is that we can
|
||||
* let the user add into our own table. see RESearch::ModifyWord. This table
|
||||
* is not in the bitset form, since we may wish to extend it in the
|
||||
* future for other character classifications.
|
||||
*
|
||||
* TRUE for 0-9 A-Z a-z _
|
||||
*/
|
||||
static char chrtyp[MAXCHR] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
|
||||
0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 0, 0, 0, 0, 1, 0, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
#define inascii(x) (0177&(x))
|
||||
#define iswordc(x) chrtyp[inascii(x)]
|
||||
#define isinset(x,y) ((x)[((y)&BLKIND)>>3] & bitarr[(y)&BITIND])
|
||||
#define isinset(x,y) ((x)[((y)&BLKIND)>>3] & bitarr[(y)&BITIND])
|
||||
|
||||
/*
|
||||
* skip values for CLO XXX to skip past the closure
|
||||
*/
|
||||
|
||||
#define ANYSKIP 2 /* [CLO] ANY END ... */
|
||||
#define CHRSKIP 3 /* [CLO] CHR chr END ... */
|
||||
#define CCLSKIP 34 /* [CLO] CCL 32bytes END ... */
|
||||
#define ANYSKIP 2 /* [CLO] ANY END */
|
||||
#define CHRSKIP 3 /* [CLO] CHR chr END */
|
||||
#define CCLSKIP 34 /* [CLO] CCL 32 bytes END */
|
||||
|
||||
int RESearch::PMatch(CharacterIndexer &ci, int lp, int endp, char *ap) {
|
||||
int op, c, n;
|
||||
int e; /* extra pointer for CLO */
|
||||
int bp; /* beginning of subpat.. */
|
||||
int ep; /* ending of subpat.. */
|
||||
int are; /* to save the line ptr. */
|
||||
int e; /* extra pointer for CLO */
|
||||
int bp; /* beginning of subpat... */
|
||||
int ep; /* ending of subpat... */
|
||||
int are; /* to save the line ptr. */
|
||||
|
||||
while ((op = *ap++) != END)
|
||||
switch(op) {
|
||||
@ -756,44 +738,15 @@ int RESearch::PMatch(CharacterIndexer &ci, int lp, int endp, char *ap) {
|
||||
return lp;
|
||||
}
|
||||
|
||||
/*
|
||||
* RESearch::ModifyWord:
|
||||
* add new characters into the word table to change RESearch::Execute's
|
||||
* understanding of what a word should look like. Note that we
|
||||
* only accept additions into the word definition.
|
||||
*
|
||||
* If the string parameter is 0 or null string, the table is
|
||||
* reset back to the default containing A-Z a-z 0-9 _. [We use
|
||||
* the compact bitset representation for the default table]
|
||||
*/
|
||||
|
||||
static char deftab[16] = {
|
||||
0, 0, 0, 0, 0, 0, '\377', 003, '\376', '\377', '\377', '\207',
|
||||
'\376', '\377', '\377', 007
|
||||
};
|
||||
|
||||
void RESearch::ModifyWord(char *s) {
|
||||
int i;
|
||||
|
||||
if (!s || !*s) {
|
||||
for (i = 0; i < MAXCHR; i++)
|
||||
if (!isinset(deftab,i))
|
||||
iswordc(i) = 0;
|
||||
}
|
||||
else
|
||||
while(*s)
|
||||
iswordc(*s++) = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* RESearch::Substitute:
|
||||
* substitute the matched portions of the src in dst.
|
||||
* substitute the matched portions of the src in dst.
|
||||
*
|
||||
* & substitute the entire matched pattern.
|
||||
* & substitute the entire matched pattern.
|
||||
*
|
||||
* \digit substitute a subpattern, with the given tag number.
|
||||
* Tags are numbered from 1 to 9. If the particular
|
||||
* tagged subpattern does not exist, null is substituted.
|
||||
* \digit substitute a subpattern, with the given tag number.
|
||||
* Tags are numbered from 1 to 9. If the particular
|
||||
* tagged subpattern does not exist, null is substituted.
|
||||
*/
|
||||
int RESearch::Substitute(CharacterIndexer &ci, char *src, char *dst) {
|
||||
char c;
|
||||
|
@ -18,7 +18,7 @@
|
||||
#define BITBLK MAXCHR/CHRBIT
|
||||
|
||||
class CharacterIndexer {
|
||||
public:
|
||||
public:
|
||||
virtual char CharAt(int index)=0;
|
||||
virtual ~CharacterIndexer() {
|
||||
}
|
||||
@ -27,16 +27,11 @@ public:
|
||||
class RESearch {
|
||||
|
||||
public:
|
||||
RESearch();
|
||||
RESearch(CharClassify *charClassTable);
|
||||
~RESearch();
|
||||
void Init();
|
||||
void Clear();
|
||||
bool GrabMatches(CharacterIndexer &ci);
|
||||
void ChSet(char c);
|
||||
void ChSetWithCase(char c, bool caseSensitive);
|
||||
const char *Compile(const char *pat, int length, bool caseSensitive, bool posix);
|
||||
int Execute(CharacterIndexer &ci, int lp, int endp);
|
||||
void ModifyWord(char *s);
|
||||
int Substitute(CharacterIndexer &ci, char *src, char *dst);
|
||||
|
||||
enum {MAXTAG=10};
|
||||
@ -48,15 +43,23 @@ public:
|
||||
char *pat[MAXTAG];
|
||||
|
||||
private:
|
||||
void Init();
|
||||
void Clear();
|
||||
void ChSet(char c);
|
||||
void ChSetWithCase(char c, bool caseSensitive);
|
||||
|
||||
int PMatch(CharacterIndexer &ci, int lp, int endp, char *ap);
|
||||
|
||||
int bol;
|
||||
int tagstk[MAXTAG]; /* subpat tag stack..*/
|
||||
char nfa[MAXNFA]; /* automaton.. */
|
||||
int tagstk[MAXTAG]; /* subpat tag stack */
|
||||
char nfa[MAXNFA]; /* automaton */
|
||||
int sta;
|
||||
char bittab[BITBLK]; /* bit table for CCL */
|
||||
/* pre-set bits... */
|
||||
char bittab[BITBLK]; /* bit table for CCL pre-set bits */
|
||||
int failure;
|
||||
CharClassify *charClass;
|
||||
bool iswordc(unsigned char x) {
|
||||
return charClass->IsWord(x);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "Style.h"
|
||||
#include "ViewStyle.h"
|
||||
#include "AutoComplete.h"
|
||||
#include "CharClassify.h"
|
||||
#include "Document.h"
|
||||
#include "Editor.h"
|
||||
#include "ScintillaBase.h"
|
||||
@ -368,12 +369,19 @@ int ScintillaBase::AutoCompleteGetCurrent() {
|
||||
void ScintillaBase::CallTipShow(Point pt, const char *defn) {
|
||||
AutoCompleteCancel();
|
||||
pt.y += vs.lineHeight;
|
||||
// If container knows about STYLE_CALLTIP then use it in place of the
|
||||
// STYLE_DEFAULT for the face name, size and character set. Also use it
|
||||
// for the foreground and background colour.
|
||||
int ctStyle = ct.UseStyleCallTip() ? STYLE_CALLTIP : STYLE_DEFAULT;
|
||||
if (ct.UseStyleCallTip()) {
|
||||
ct.SetForeBack(vs.styles[STYLE_CALLTIP].fore, vs.styles[STYLE_CALLTIP].back);
|
||||
}
|
||||
PRectangle rc = ct.CallTipStart(currentPos, pt,
|
||||
defn,
|
||||
vs.styles[STYLE_DEFAULT].fontName,
|
||||
vs.styles[STYLE_DEFAULT].sizeZoomed,
|
||||
vs.styles[ctStyle].fontName,
|
||||
vs.styles[ctStyle].sizeZoomed,
|
||||
CodePage(),
|
||||
vs.styles[STYLE_DEFAULT].characterSet,
|
||||
vs.styles[ctStyle].characterSet,
|
||||
wMain);
|
||||
// If the call-tip window would be out of the client
|
||||
// space, adjust so it displays above the text.
|
||||
@ -624,11 +632,13 @@ sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPara
|
||||
|
||||
case SCI_CALLTIPSETBACK:
|
||||
ct.colourBG = ColourDesired(wParam);
|
||||
vs.styles[STYLE_CALLTIP].fore = ct.colourBG;
|
||||
InvalidateStyleRedraw();
|
||||
break;
|
||||
|
||||
case SCI_CALLTIPSETFORE:
|
||||
ct.colourUnSel = ColourDesired(wParam);
|
||||
vs.styles[STYLE_CALLTIP].fore = ct.colourUnSel;
|
||||
InvalidateStyleRedraw();
|
||||
break;
|
||||
|
||||
@ -637,6 +647,11 @@ sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPara
|
||||
InvalidateStyleRedraw();
|
||||
break;
|
||||
|
||||
case SCI_CALLTIPUSESTYLE:
|
||||
ct.SetTabSize((int)wParam);
|
||||
InvalidateStyleRedraw();
|
||||
break;
|
||||
|
||||
case SCI_USEPOPUP:
|
||||
displayPopupMenu = wParam != 0;
|
||||
break;
|
||||
@ -701,6 +716,8 @@ sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPara
|
||||
SetLexerLanguage(reinterpret_cast<const char *>(lParam));
|
||||
break;
|
||||
|
||||
case SCI_GETSTYLEBITSNEEDED:
|
||||
return lexCurrent ? lexCurrent->GetStyleBitsNeeded() : 5;
|
||||
#endif
|
||||
|
||||
default:
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "Style.h"
|
||||
#include "AutoComplete.h"
|
||||
#include "ViewStyle.h"
|
||||
#include "CharClassify.h"
|
||||
#include "Document.h"
|
||||
#include "Editor.h"
|
||||
#include "SString.h"
|
||||
@ -1664,31 +1665,29 @@ void ScintillaGTK::Resize(int width, int height) {
|
||||
verticalScrollBarHeight = 0;
|
||||
|
||||
GtkAllocation alloc;
|
||||
alloc.x = 0;
|
||||
if (showSBHorizontal) {
|
||||
gtk_widget_show(GTK_WIDGET(PWidget(scrollbarh)));
|
||||
alloc.x = 0;
|
||||
alloc.y = height - scrollBarHeight;
|
||||
alloc.width = Platform::Maximum(1, width - scrollBarWidth) + 1;
|
||||
alloc.height = horizontalScrollBarHeight;
|
||||
gtk_widget_size_allocate(GTK_WIDGET(PWidget(scrollbarh)), &alloc);
|
||||
} else {
|
||||
alloc.y = -scrollBarHeight;
|
||||
alloc.width = 0;
|
||||
alloc.height = 0;
|
||||
gtk_widget_hide(GTK_WIDGET(PWidget(scrollbarh)));
|
||||
}
|
||||
gtk_widget_size_allocate(GTK_WIDGET(PWidget(scrollbarh)), &alloc);
|
||||
|
||||
alloc.y = 0;
|
||||
if (verticalScrollBarVisible) {
|
||||
gtk_widget_show(GTK_WIDGET(PWidget(scrollbarv)));
|
||||
alloc.x = width - scrollBarWidth;
|
||||
alloc.y = 0;
|
||||
alloc.width = scrollBarWidth;
|
||||
alloc.height = Platform::Maximum(1, height - scrollBarHeight) + 1;
|
||||
if (!showSBHorizontal)
|
||||
alloc.height += scrollBarWidth-1;
|
||||
gtk_widget_size_allocate(GTK_WIDGET(PWidget(scrollbarv)), &alloc);
|
||||
} else {
|
||||
alloc.x = -scrollBarWidth;
|
||||
alloc.width = 0;
|
||||
alloc.height = 0;
|
||||
gtk_widget_hide(GTK_WIDGET(PWidget(scrollbarv)));
|
||||
}
|
||||
gtk_widget_size_allocate(GTK_WIDGET(PWidget(scrollbarv)), &alloc);
|
||||
if (GTK_WIDGET_MAPPED(PWidget(wMain))) {
|
||||
ChangeSize();
|
||||
}
|
||||
@ -1698,7 +1697,9 @@ void ScintillaGTK::Resize(int width, int height) {
|
||||
alloc.width = Platform::Maximum(1, width - scrollBarWidth);
|
||||
alloc.height = Platform::Maximum(1, height - scrollBarHeight);
|
||||
if (!showSBHorizontal)
|
||||
alloc.height += scrollBarWidth;
|
||||
alloc.height += scrollBarHeight;
|
||||
if (!verticalScrollBarVisible)
|
||||
alloc.width += scrollBarWidth;
|
||||
gtk_widget_size_allocate(GTK_WIDGET(PWidget(wText)), &alloc);
|
||||
}
|
||||
|
||||
|
@ -95,6 +95,7 @@ ViewStyle::ViewStyle(const ViewStyle &source) {
|
||||
caretcolour.desired = source.caretcolour.desired;
|
||||
showCaretLineBackground = source.showCaretLineBackground;
|
||||
caretLineBackground.desired = source.caretLineBackground.desired;
|
||||
caretLineAlpha = source.caretLineAlpha;
|
||||
edgecolour.desired = source.edgecolour.desired;
|
||||
edgeState = source.edgeState;
|
||||
caretWidth = source.caretWidth;
|
||||
@ -157,6 +158,7 @@ void ViewStyle::Init() {
|
||||
caretcolour.desired = ColourDesired(0, 0, 0);
|
||||
showCaretLineBackground = false;
|
||||
caretLineBackground.desired = ColourDesired(0xff, 0xff, 0);
|
||||
caretLineAlpha = SC_ALPHA_NOALPHA;
|
||||
edgecolour.desired = ColourDesired(0xc0, 0xc0, 0xc0);
|
||||
edgeState = EDGE_NONE;
|
||||
caretWidth = 1;
|
||||
@ -278,6 +280,10 @@ void ViewStyle::ClearStyles() {
|
||||
}
|
||||
}
|
||||
styles[STYLE_LINENUMBER].back.desired = Platform::Chrome();
|
||||
|
||||
// Set call tip fore/back to match the values previously set for call tips
|
||||
styles[STYLE_CALLTIP].back.desired = ColourDesired(0xff, 0xff, 0xff);
|
||||
styles[STYLE_CALLTIP].fore.desired = ColourDesired(0x80, 0x80, 0x80);
|
||||
}
|
||||
|
||||
void ViewStyle::SetStyleFontName(int styleIndex, const char *name) {
|
||||
|
@ -85,6 +85,7 @@ public:
|
||||
ColourPair caretcolour;
|
||||
bool showCaretLineBackground;
|
||||
ColourPair caretLineBackground;
|
||||
int caretLineAlpha;
|
||||
ColourPair edgecolour;
|
||||
int edgeState;
|
||||
int caretWidth;
|
||||
|
@ -236,12 +236,15 @@ class Window; // Forward declaration for Palette
|
||||
*/
|
||||
class Palette {
|
||||
int used;
|
||||
enum {numEntries = 100};
|
||||
ColourPair entries[numEntries];
|
||||
int size;
|
||||
ColourPair *entries;
|
||||
#if PLAT_GTK
|
||||
void *allocatedPalette; // GdkColor *
|
||||
int allocatedLen;
|
||||
#endif
|
||||
// Private so Palette objects can not be copied
|
||||
Palette(const Palette &) {}
|
||||
Palette &operator=(const Palette &) { return *this; }
|
||||
public:
|
||||
#if PLAT_WIN
|
||||
void *hpal;
|
||||
@ -319,6 +322,8 @@ public:
|
||||
virtual void FillRectangle(PRectangle rc, ColourAllocated back)=0;
|
||||
virtual void FillRectangle(PRectangle rc, Surface &surfacePattern)=0;
|
||||
virtual void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back)=0;
|
||||
virtual void AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated fill, int alphaFill,
|
||||
ColourAllocated outline, int alphaOutline, int flags)=0;
|
||||
virtual void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back)=0;
|
||||
virtual void Copy(PRectangle rc, Point from, Surface &surfaceSource)=0;
|
||||
|
||||
|
@ -88,7 +88,9 @@
|
||||
#define SCLEX_FLAGSHIP 73
|
||||
#define SCLEX_CSOUND 74
|
||||
#define SCLEX_FREEBASIC 75
|
||||
#define SCLEX_OMS 75
|
||||
#define SCLEX_INNOSETUP 76
|
||||
#define SCLEX_OPAL 77
|
||||
#define SCLEX_OMS 78
|
||||
#define SCLEX_AUTOMATIC 1000
|
||||
#define SCE_P_DEFAULT 0
|
||||
#define SCE_P_COMMENTLINE 1
|
||||
@ -126,6 +128,26 @@
|
||||
#define SCE_C_COMMENTDOCKEYWORD 17
|
||||
#define SCE_C_COMMENTDOCKEYWORDERROR 18
|
||||
#define SCE_C_GLOBALCLASS 19
|
||||
#define SCE_TCL_DEFAULT 0
|
||||
#define SCE_TCL_COMMENT 1
|
||||
#define SCE_TCL_COMMENTLINE 2
|
||||
#define SCE_TCL_NUMBER 3
|
||||
#define SCE_TCL_WORD_IN_QUOTE 4
|
||||
#define SCE_TCL_IN_QUOTE 5
|
||||
#define SCE_TCL_OPERATOR 6
|
||||
#define SCE_TCL_IDENTIFIER 7
|
||||
#define SCE_TCL_SUBSTITUTION 8
|
||||
#define SCE_TCL_SUB_BRACE 9
|
||||
#define SCE_TCL_MODIFIER 10
|
||||
#define SCE_TCL_EXPAND 11
|
||||
#define SCE_TCL_WORD 12
|
||||
#define SCE_TCL_WORD2 13
|
||||
#define SCE_TCL_WORD3 14
|
||||
#define SCE_TCL_WORD4 15
|
||||
#define SCE_TCL_WORD5 16
|
||||
#define SCE_TCL_WORD6 17
|
||||
#define SCE_TCL_WORD7 18
|
||||
#define SCE_TCL_WORD8 19
|
||||
#define SCE_H_DEFAULT 0
|
||||
#define SCE_H_TAG 1
|
||||
#define SCE_H_TAGUNKNOWN 2
|
||||
@ -327,6 +349,7 @@
|
||||
#define SCE_PROPS_SECTION 2
|
||||
#define SCE_PROPS_ASSIGNMENT 3
|
||||
#define SCE_PROPS_DEFVAL 4
|
||||
#define SCE_PROPS_KEY 5
|
||||
#define SCE_L_DEFAULT 0
|
||||
#define SCE_L_COMMAND 1
|
||||
#define SCE_L_TAG 2
|
||||
@ -1009,6 +1032,29 @@
|
||||
#define SCE_CSOUND_IRATE_VAR 13
|
||||
#define SCE_CSOUND_GLOBAL_VAR 14
|
||||
#define SCE_CSOUND_STRINGEOL 15
|
||||
#define SCE_INNO_DEFAULT 0
|
||||
#define SCE_INNO_COMMENT 1
|
||||
#define SCE_INNO_KEYWORD 2
|
||||
#define SCE_INNO_PARAMETER 3
|
||||
#define SCE_INNO_SECTION 4
|
||||
#define SCE_INNO_PREPROC 5
|
||||
#define SCE_INNO_PREPROC_INLINE 6
|
||||
#define SCE_INNO_COMMENT_PASCAL 7
|
||||
#define SCE_INNO_KEYWORD_PASCAL 8
|
||||
#define SCE_INNO_KEYWORD_USER 9
|
||||
#define SCE_INNO_STRING_DOUBLE 10
|
||||
#define SCE_INNO_STRING_SINGLE 11
|
||||
#define SCE_INNO_IDENTIFIER 12
|
||||
#define SCE_OPAL_SPACE 0
|
||||
#define SCE_OPAL_COMMENT_BLOCK 1
|
||||
#define SCE_OPAL_COMMENT_LINE 2
|
||||
#define SCE_OPAL_INTEGER 3
|
||||
#define SCE_OPAL_KEYWORD 4
|
||||
#define SCE_OPAL_SORT 5
|
||||
#define SCE_OPAL_STRING 6
|
||||
#define SCE_OPAL_PAR 7
|
||||
#define SCE_OPAL_BOOL_CONST 8
|
||||
#define SCE_OPAL_DEFAULT 32
|
||||
#define SCLEX_ASP 29
|
||||
#define SCLEX_PHP 30
|
||||
//--Autogenerated -- end of section automatically generated from Scintilla.iface
|
||||
|
@ -154,6 +154,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
||||
#define STYLE_BRACEBAD 35
|
||||
#define STYLE_CONTROLCHAR 36
|
||||
#define STYLE_INDENTGUIDE 37
|
||||
#define STYLE_CALLTIP 38
|
||||
#define STYLE_LASTPREDEFINED 39
|
||||
#define STYLE_MAX 127
|
||||
#define SC_CHARSET_ANSI 0
|
||||
@ -214,6 +215,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
||||
#define INDIC_STRIKE 4
|
||||
#define INDIC_HIDDEN 5
|
||||
#define INDIC_BOX 6
|
||||
#define INDIC_ROUNDBOX 7
|
||||
#define INDIC0_MASK 0x20
|
||||
#define INDIC1_MASK 0x40
|
||||
#define INDIC2_MASK 0x80
|
||||
@ -358,6 +360,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
||||
#define SCI_CALLTIPSETBACK 2205
|
||||
#define SCI_CALLTIPSETFORE 2206
|
||||
#define SCI_CALLTIPSETFOREHLT 2207
|
||||
#define SCI_CALLTIPUSESTYLE 2212
|
||||
#define SCI_VISIBLEFROMDOCLINE 2220
|
||||
#define SCI_DOCLINEFROMVISIBLE 2221
|
||||
#define SCI_WRAPCOUNT 2235
|
||||
@ -607,6 +610,11 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
||||
#define SCI_SETPASTECONVERTENDINGS 2467
|
||||
#define SCI_GETPASTECONVERTENDINGS 2468
|
||||
#define SCI_SELECTIONDUPLICATE 2469
|
||||
#define SC_ALPHA_TRANSPARENT 0
|
||||
#define SC_ALPHA_OPAQUE 255
|
||||
#define SC_ALPHA_NOALPHA 256
|
||||
#define SCI_SETCARETLINEBACKALPHA 2470
|
||||
#define SCI_GETCARETLINEBACKALPHA 2471
|
||||
#define SCI_STARTRECORD 3001
|
||||
#define SCI_STOPRECORD 3002
|
||||
#define SCI_SETLEXER 4001
|
||||
|
@ -344,8 +344,8 @@ set void SetMarginSensitiveN=2246(int margin, bool sensitive)
|
||||
# Retrieve the mouse click sensitivity of a margin.
|
||||
get bool GetMarginSensitiveN=2247(int margin,)
|
||||
|
||||
# Styles in range 32..37 are predefined for parts of the UI and are not used as normal styles.
|
||||
# Styles 38 and 39 are for future use.
|
||||
# Styles in range 32..38 are predefined for parts of the UI and are not used as normal styles.
|
||||
# Style 39 is for future use.
|
||||
enu StylesCommon=STYLE_
|
||||
val STYLE_DEFAULT=32
|
||||
val STYLE_LINENUMBER=33
|
||||
@ -353,6 +353,7 @@ val STYLE_BRACELIGHT=34
|
||||
val STYLE_BRACEBAD=35
|
||||
val STYLE_CONTROLCHAR=36
|
||||
val STYLE_INDENTGUIDE=37
|
||||
val STYLE_CALLTIP=38
|
||||
val STYLE_LASTPREDEFINED=39
|
||||
val STYLE_MAX=127
|
||||
|
||||
@ -474,6 +475,7 @@ val INDIC_DIAGONAL=3
|
||||
val INDIC_STRIKE=4
|
||||
val INDIC_HIDDEN=5
|
||||
val INDIC_BOX=6
|
||||
val INDIC_ROUNDBOX=7
|
||||
val INDIC0_MASK=0x20
|
||||
val INDIC1_MASK=0x40
|
||||
val INDIC2_MASK=0x80
|
||||
@ -919,6 +921,9 @@ set void CallTipSetFore=2206(colour fore,)
|
||||
# Set the foreground colour for the highlighted part of the call tip.
|
||||
set void CallTipSetForeHlt=2207(colour fore,)
|
||||
|
||||
# Enable use of STYLE_CALLTIP and set call tip tab size in pixels.
|
||||
set void CallTipUseStyle=2212(int tabSize,)
|
||||
|
||||
# Find the display line of a document line taking hidden lines into account.
|
||||
fun int VisibleFromDocLine=2220(int line,)
|
||||
|
||||
@ -1446,7 +1451,6 @@ get int GetXOffset=2398(,)
|
||||
fun void ChooseCaretX=2399(,)
|
||||
|
||||
# Set the focus to this Scintilla widget.
|
||||
# GTK+ Specific.
|
||||
fun void GrabFocus=2400(,)
|
||||
|
||||
enu CaretPolicy = CARET_
|
||||
@ -1641,6 +1645,16 @@ get bool GetPasteConvertEndings=2468(,)
|
||||
# Duplicate the selection. If selection empty duplicate the line containing the caret.
|
||||
fun void SelectionDuplicate=2469(,)
|
||||
|
||||
val SC_ALPHA_TRANSPARENT=0
|
||||
val SC_ALPHA_OPAQUE=255
|
||||
val SC_ALPHA_NOALPHA=256
|
||||
|
||||
# Set background alpha of the caret line.
|
||||
set void SetCaretLineBackAlpha=2470(int alpha,)
|
||||
|
||||
# Get the background alpha of the caret line.
|
||||
get int GetCaretLineBackAlpha=2471(,)
|
||||
|
||||
# Start notifying the container of all key presses and commands.
|
||||
fun void StartRecord=3001(,)
|
||||
|
||||
@ -1819,6 +1833,8 @@ val SCLEX_SMALLTALK=72
|
||||
val SCLEX_FLAGSHIP=73
|
||||
val SCLEX_CSOUND=74
|
||||
val SCLEX_FREEBASIC=75
|
||||
val SCLEX_INNOSETUP=76
|
||||
val SCLEX_OPAL=77
|
||||
|
||||
# When a lexer specifies its language as SCLEX_AUTOMATIC it receives a
|
||||
# value assigned in sequence from SCLEX_AUTOMATIC+1.
|
||||
@ -1844,7 +1860,6 @@ val SCE_P_DECORATOR=15
|
||||
# Lexical states for SCLEX_CPP
|
||||
lex Cpp=SCLEX_CPP SCE_C_
|
||||
lex Pascal=SCLEX_PASCAL SCE_C_
|
||||
lex TCL=SCLEX_TCL SCE_C_
|
||||
lex BullAnt=SCLEX_BULLANT SCE_C_
|
||||
val SCE_C_DEFAULT=0
|
||||
val SCE_C_COMMENT=1
|
||||
@ -1866,6 +1881,28 @@ val SCE_C_WORD2=16
|
||||
val SCE_C_COMMENTDOCKEYWORD=17
|
||||
val SCE_C_COMMENTDOCKEYWORDERROR=18
|
||||
val SCE_C_GLOBALCLASS=19
|
||||
# Lexical states for SCLEX_TCL
|
||||
lex TCL=SCLEX_TCL SCE_TCL_
|
||||
val SCE_TCL_DEFAULT=0
|
||||
val SCE_TCL_COMMENT=1
|
||||
val SCE_TCL_COMMENTLINE=2
|
||||
val SCE_TCL_NUMBER=3
|
||||
val SCE_TCL_WORD_IN_QUOTE=4
|
||||
val SCE_TCL_IN_QUOTE=5
|
||||
val SCE_TCL_OPERATOR=6
|
||||
val SCE_TCL_IDENTIFIER=7
|
||||
val SCE_TCL_SUBSTITUTION=8
|
||||
val SCE_TCL_SUB_BRACE=9
|
||||
val SCE_TCL_MODIFIER=10
|
||||
val SCE_TCL_EXPAND=11
|
||||
val SCE_TCL_WORD=12
|
||||
val SCE_TCL_WORD2=13
|
||||
val SCE_TCL_WORD3=14
|
||||
val SCE_TCL_WORD4=15
|
||||
val SCE_TCL_WORD5=16
|
||||
val SCE_TCL_WORD6=17
|
||||
val SCE_TCL_WORD7=18
|
||||
val SCE_TCL_WORD8=19
|
||||
# Lexical states for SCLEX_HTML, SCLEX_XML
|
||||
lex HTML=SCLEX_HTML SCE_H
|
||||
lex XML=SCLEX_XML SCE_H
|
||||
@ -2094,6 +2131,7 @@ val SCE_PROPS_COMMENT=1
|
||||
val SCE_PROPS_SECTION=2
|
||||
val SCE_PROPS_ASSIGNMENT=3
|
||||
val SCE_PROPS_DEFVAL=4
|
||||
val SCE_PROPS_KEY=5
|
||||
# Lexical states for SCLEX_LATEX
|
||||
lex LaTeX=SCLEX_LATEX SCE_L_
|
||||
val SCE_L_DEFAULT=0
|
||||
@ -2877,6 +2915,33 @@ val SCE_CSOUND_KRATE_VAR=12
|
||||
val SCE_CSOUND_IRATE_VAR=13
|
||||
val SCE_CSOUND_GLOBAL_VAR=14
|
||||
val SCE_CSOUND_STRINGEOL=15
|
||||
# Lexical states for SCLEX_INNOSETUP
|
||||
lex Inno=SCLEX_INNOSETUP SCE_INNO_
|
||||
val SCE_INNO_DEFAULT=0
|
||||
val SCE_INNO_COMMENT=1
|
||||
val SCE_INNO_KEYWORD=2
|
||||
val SCE_INNO_PARAMETER=3
|
||||
val SCE_INNO_SECTION=4
|
||||
val SCE_INNO_PREPROC=5
|
||||
val SCE_INNO_PREPROC_INLINE=6
|
||||
val SCE_INNO_COMMENT_PASCAL=7
|
||||
val SCE_INNO_KEYWORD_PASCAL=8
|
||||
val SCE_INNO_KEYWORD_USER=9
|
||||
val SCE_INNO_STRING_DOUBLE=10
|
||||
val SCE_INNO_STRING_SINGLE=11
|
||||
val SCE_INNO_IDENTIFIER=12
|
||||
# Lexical states for SCLEX_OPAL
|
||||
lex Opal=SCLEX_OPAL SCE_OPAL_
|
||||
val SCE_OPAL_SPACE=0
|
||||
val SCE_OPAL_COMMENT_BLOCK=1
|
||||
val SCE_OPAL_COMMENT_LINE=2
|
||||
val SCE_OPAL_INTEGER=3
|
||||
val SCE_OPAL_KEYWORD=4
|
||||
val SCE_OPAL_SORT=5
|
||||
val SCE_OPAL_STRING=6
|
||||
val SCE_OPAL_PAR=7
|
||||
val SCE_OPAL_BOOL_CONST=8
|
||||
val SCE_OPAL_DEFAULT=32
|
||||
|
||||
# Events
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user