updated Scintilla to version 1.67

git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@135 ea778897-0a13-0410-b9d1-a72fbfd435f5
This commit is contained in:
Enrico Tröger 2006-01-16 15:10:45 +00:00
parent 18b1d12497
commit 45c8bed2c6
18 changed files with 450 additions and 248 deletions

View File

@ -465,7 +465,7 @@ void UndoHistory::AppendAction(actionType at, int position, char *data, int leng
} else if (currentAction == savePoint) {
currentAction++;
} else if ((at == insertAction) &&
(position != (actPrevious.position + actPrevious.lenData*2))) {
(position != (actPrevious.position + actPrevious.lenData))) {
// Insertions must be immediately after to coalesce
currentAction++;
} else if (!actions[currentAction].mayCoalesce) {
@ -473,7 +473,7 @@ void UndoHistory::AppendAction(actionType at, int position, char *data, int leng
currentAction++;
} else if (at == removeAction) {
if ((lengthData == 1) || (lengthData == 2)){
if ((position + lengthData * 2) == actPrevious.position) {
if ((position + lengthData) == actPrevious.position) {
; // Backspace -> OK
} else if (position == actPrevious.position) {
; // Delete -> OK
@ -725,7 +725,7 @@ const char *CellBuffer::InsertString(int position, char *s, int insertLength) {
for (int i = 0; i < insertLength / 2; i++) {
data[i] = s[i * 2];
}
uh.AppendAction(insertAction, position, data, insertLength / 2);
uh.AppendAction(insertAction, position / 2, data, insertLength / 2);
}
BasicInsertString(position, s, insertLength);
@ -733,13 +733,6 @@ const char *CellBuffer::InsertString(int position, char *s, int insertLength) {
return data;
}
void CellBuffer::InsertCharStyle(int position, char ch, char style) {
char s[2];
s[0] = ch;
s[1] = style;
InsertString(position*2, s, 2);
}
bool CellBuffer::SetStyleAt(int position, char style, char mask) {
style &= mask;
char curVal = ByteAt(position * 2 + 1);
@ -769,6 +762,7 @@ bool CellBuffer::SetStyleFor(int position, int lengthStyle, char style, char mas
const char *CellBuffer::DeleteChars(int position, int deleteLength) {
// InsertString and DeleteChars are the bottleneck though which all changes occur
PLATFORM_ASSERT(deleteLength > 0);
char *data = 0;
if (!readOnly) {
if (collectingUndo) {
@ -777,7 +771,7 @@ const char *CellBuffer::DeleteChars(int position, int deleteLength) {
for (int i = 0; i < deleteLength / 2; i++) {
data[i] = ByteAt(position + i * 2);
}
uh.AppendAction(removeAction, position, data, deleteLength / 2);
uh.AppendAction(removeAction, position / 2, data, deleteLength / 2);
}
BasicDeleteChars(position, deleteLength);
@ -875,6 +869,7 @@ void CellBuffer::BasicInsertString(int position, char *s, int insertLength) {
//Platform::DebugPrintf("Inserting at %d for %d\n", position, insertLength);
if (insertLength == 0)
return ;
PLATFORM_ASSERT(insertLength > 0);
RoomFor(insertLength);
GapTo(position);
@ -1043,14 +1038,14 @@ const Action &CellBuffer::GetUndoStep() const {
void CellBuffer::PerformUndoStep() {
const Action &actionStep = uh.GetUndoStep();
if (actionStep.at == insertAction) {
BasicDeleteChars(actionStep.position, actionStep.lenData*2);
BasicDeleteChars(actionStep.position*2, actionStep.lenData*2);
} else if (actionStep.at == removeAction) {
char *styledData = new char[actionStep.lenData * 2];
for (int i = 0; i < actionStep.lenData; i++) {
styledData[i*2] = actionStep.data[i];
styledData[i*2 + 1] = 0;
}
BasicInsertString(actionStep.position, styledData, actionStep.lenData*2);
BasicInsertString(actionStep.position*2, styledData, actionStep.lenData*2);
delete []styledData;
}
uh.CompletedUndoStep();
@ -1076,10 +1071,10 @@ void CellBuffer::PerformRedoStep() {
styledData[i*2] = actionStep.data[i];
styledData[i*2 + 1] = 0;
}
BasicInsertString(actionStep.position, styledData, actionStep.lenData*2);
BasicInsertString(actionStep.position*2, styledData, actionStep.lenData*2);
delete []styledData;
} else if (actionStep.at == removeAction) {
BasicDeleteChars(actionStep.position, actionStep.lenData*2);
BasicDeleteChars(actionStep.position*2, actionStep.lenData*2);
}
uh.CompletedRedoStep();
}

View File

@ -191,7 +191,6 @@ public:
int LineStart(int line);
int LineFromPosition(int pos) { return lv.LineFromPosition(pos); }
const char *InsertString(int position, char *s, int insertLength);
void InsertCharStyle(int position, char ch, char style);
/// Setting styles for positions outside the range of the buffer is safe and has no effect.
/// @return true if the style of a character is changed.

View File

@ -104,25 +104,39 @@ void Document::SetSavePoint() {
int Document::AddMark(int line, int markerNum) {
int prev = cb.AddMark(line, markerNum);
DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line);
mh.line = line;
NotifyModified(mh);
return prev;
}
void Document::AddMarkSet(int line, int valueSet) {
unsigned int m = valueSet;
for (int i = 0; m; i++, m >>= 1)
if (m & 1)
cb.AddMark(line, i);
DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line);
mh.line = line;
NotifyModified(mh);
}
void Document::DeleteMark(int line, int markerNum) {
cb.DeleteMark(line, markerNum);
DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line);
mh.line = line;
NotifyModified(mh);
}
void Document::DeleteMarkFromHandle(int markerHandle) {
cb.DeleteMarkFromHandle(markerHandle);
DocModification mh(SC_MOD_CHANGEMARKER, 0, 0, 0, 0);
mh.line = -1;
NotifyModified(mh);
}
void Document::DeleteAllMarks(int markerNum) {
cb.DeleteAllMarks(markerNum);
DocModification mh(SC_MOD_CHANGEMARKER, 0, 0, 0, 0);
mh.line = -1;
NotifyModified(mh);
}
@ -437,7 +451,7 @@ int Document::Undo() {
SC_MOD_BEFOREDELETE | SC_PERFORMED_UNDO, action));
}
cb.PerformUndoStep();
int cellPosition = action.position / 2;
int cellPosition = action.position;
ModifiedAt(cellPosition);
newPos = cellPosition;
@ -492,8 +506,8 @@ int Document::Redo() {
SC_MOD_BEFOREDELETE | SC_PERFORMED_REDO, action));
}
cb.PerformRedoStep();
ModifiedAt(action.position / 2);
newPos = action.position / 2;
ModifiedAt(action.position);
newPos = action.position;
int modFlags = SC_PERFORMED_REDO;
if (action.at == insertAction) {
@ -513,7 +527,7 @@ int Document::Redo() {
modFlags |= SC_MULTILINEUNDOREDO;
}
NotifyModified(
DocModification(modFlags, action.position / 2, action.lenData,
DocModification(modFlags, action.position, action.lenData,
linesAdded, action.data));
}
@ -703,12 +717,15 @@ void Document::Indent(bool forwards, int lineBottom, int lineTop) {
// Dedent - suck white space off the front of the line to dedent by equivalent of a tab
for (int line = lineBottom; line >= lineTop; line--) {
int indentOfLine = GetLineIndentation(line);
if (forwards)
if (forwards) {
if (LineStart(line) < LineEnd(line)) {
SetLineIndentation(line, indentOfLine + IndentSize());
else
}
} else {
SetLineIndentation(line, indentOfLine - IndentSize());
}
}
}
// Convert line endings for a piece of text to a particular mode.
// Stop at len or when a NUL is found.
@ -1309,19 +1326,22 @@ bool Document::SetStyles(int length, char *styles) {
return false;
} else {
enteredCount++;
int prevEndStyled = endStyled;
bool didChange = false;
int lastChange = 0;
int startMod = 0;
int endMod = 0;
for (int iPos = 0; iPos < length; iPos++, endStyled++) {
PLATFORM_ASSERT(endStyled < Length());
if (cb.SetStyleAt(endStyled, styles[iPos], stylingMask)) {
if (!didChange) {
startMod = endStyled;
}
didChange = true;
lastChange = iPos;
endMod = endStyled;
}
}
if (didChange) {
DocModification mh(SC_MOD_CHANGESTYLE | SC_PERFORMED_USER,
prevEndStyled, lastChange);
startMod, endMod - startMod + 1);
NotifyModified(mh);
}
enteredCount--;
@ -1519,3 +1539,55 @@ int Document::ExtendStyleRange(int pos, int delta, bool singleLine) {
}
return pos;
}
static char BraceOpposite(char ch) {
switch (ch) {
case '(':
return ')';
case ')':
return '(';
case '[':
return ']';
case ']':
return '[';
case '{':
return '}';
case '}':
return '{';
case '<':
return '>';
case '>':
return '<';
default:
return '\0';
}
}
// TODO: should be able to extend styled region to find matching brace
int Document::BraceMatch(int position, int /*maxReStyle*/) {
char chBrace = CharAt(position);
char chSeek = BraceOpposite(chBrace);
if (chSeek == '\0')
return - 1;
char styBrace = static_cast<char>(StyleAt(position) & stylingBitsMask);
int direction = -1;
if (chBrace == '(' || chBrace == '[' || chBrace == '{' || chBrace == '<')
direction = 1;
int depth = 1;
position = position + direction;
while ((position >= 0) && (position < Length())) {
position = MovePositionOutsideChar(position, direction);
char chAtPos = CharAt(position);
char styAtPos = static_cast<char>(StyleAt(position) & stylingBitsMask);
if ((position > GetEndStyled()) || (styAtPos == styBrace)) {
if (chAtPos == chBrace)
depth++;
if (chAtPos == chSeek)
depth--;
if (depth == 0)
return position;
}
position = position + direction;
}
return - 1;
}

View File

@ -176,6 +176,7 @@ public:
char StyleAt(int position) { return cb.StyleAt(position); }
int GetMark(int line) { return cb.GetMark(line); }
int AddMark(int line, int markerNum);
void AddMarkSet(int line, int valueSet);
void DeleteMark(int line, int markerNum);
void DeleteMarkFromHandle(int markerHandle);
void DeleteAllMarks(int markerNum);
@ -233,6 +234,7 @@ public:
int ParaUp(int pos);
int ParaDown(int pos);
int IndentSize() { return actualIndentInChars; }
int BraceMatch(int position, int maxReStyle);
private:
void CheckReadOnly();
@ -276,7 +278,7 @@ public:
DocModification(int modificationType_, const Action &act, int linesAdded_=0) :
modificationType(modificationType_),
position(act.position / 2),
position(act.position),
length(act.lenData),
linesAdded(linesAdded_),
text(act.data),

View File

@ -85,6 +85,7 @@ LineLayout::LineLayout(int maxLineLength_) :
edgeColumn(0),
chars(0),
styles(0),
styleBitsSet(0),
indicators(0),
positions(0),
hsStart(0),
@ -188,7 +189,7 @@ void LineLayout::RestoreBracesHighlight(Range rangeLine, Position braces[]) {
LineLayoutCache::LineLayoutCache() :
level(0), length(0), size(0), cache(0),
allInvalidated(false), styleClock(-1) {
allInvalidated(false), styleClock(-1), useCount(0) {
Allocate(0);
}
@ -197,6 +198,7 @@ LineLayoutCache::~LineLayoutCache() {
}
void LineLayoutCache::Allocate(int length_) {
PLATFORM_ASSERT(cache == NULL);
allInvalidated = false;
length = length_;
size = length;
@ -211,6 +213,7 @@ void LineLayoutCache::Allocate(int length_) {
}
void LineLayoutCache::AllocateForLevel(int linesOnScreen, int linesInDoc) {
PLATFORM_ASSERT(useCount == 0);
int lengthForLevel = 0;
if (level == llcCaret) {
lengthForLevel = 1;
@ -221,23 +224,28 @@ void LineLayoutCache::AllocateForLevel(int linesOnScreen, int linesInDoc) {
}
if (lengthForLevel > size) {
Deallocate();
} else if (lengthForLevel < length) {
Allocate(lengthForLevel);
} else {
if (lengthForLevel < length) {
for (int i = lengthForLevel; i < length; i++) {
delete cache[i];
cache[i] = 0;
}
}
if (!cache) {
Allocate(lengthForLevel);
length = lengthForLevel;
}
PLATFORM_ASSERT(length == lengthForLevel);
PLATFORM_ASSERT(cache != NULL || length == 0);
}
void LineLayoutCache::Deallocate() {
PLATFORM_ASSERT(useCount == 0);
for (int i = 0; i < length; i++)
delete cache[i];
delete []cache;
cache = 0;
length = 0;
size = 0;
}
void LineLayoutCache::Invalidate(LineLayout::validLevel validity_) {
@ -275,14 +283,15 @@ LineLayout *LineLayoutCache::Retrieve(int lineNumber, int lineCaret, int maxChar
pos = 0;
} else if (level == llcPage) {
if (lineNumber == lineCaret) {
pos = length;
pos = 0;
} else {
pos = lineNumber % length;
pos = 1 + (lineNumber % (length - 1));
}
} else if (level == llcDocument) {
pos = lineNumber;
}
if (pos >= 0) {
PLATFORM_ASSERT(useCount == 0);
if (cache && (pos < length)) {
if (cache[pos]) {
if ((cache[pos]->lineNumber != lineNumber) ||
@ -298,6 +307,7 @@ LineLayout *LineLayoutCache::Retrieve(int lineNumber, int lineCaret, int maxChar
cache[pos]->lineNumber = lineNumber;
cache[pos]->inCache = true;
ret = cache[pos];
useCount++;
}
}
}
@ -315,6 +325,8 @@ void LineLayoutCache::Dispose(LineLayout *ll) {
if (ll) {
if (!ll->inCache) {
delete ll;
} else {
useCount--;
}
}
}
@ -424,6 +436,8 @@ Editor::Editor() {
wrapVisualStartIndent = 0;
actualWrapVisualStartIndent = 0;
convertPastes = true;
hsStart = -1;
hsEnd = -1;
@ -875,13 +889,19 @@ void Editor::Redraw() {
//wMain.InvalidateAll();
}
void Editor::RedrawSelMargin() {
void Editor::RedrawSelMargin(int line) {
if (!AbandonPaint()) {
if (vs.maskInLine) {
Redraw();
} else {
PRectangle rcSelMargin = GetClientRectangle();
rcSelMargin.right = vs.fixedColumnWidth;
if (line != -1) {
int position = pdoc->LineStart(line);
PRectangle rcLine = RectangleFromRange(position, position);
rcSelMargin.top = rcLine.top;
rcSelMargin.bottom = rcLine.bottom;
}
wMain.InvalidateRectangle(rcSelMargin);
}
}
@ -1910,39 +1930,41 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
posLineEnd = posLineStart + ll->maxLineLength;
}
if (ll->validity == LineLayout::llCheckTextAndStyle) {
int lineLength = 0;
for (int cid = posLineStart; cid < posLineEnd; cid++) {
char chDoc = pdoc->CharAt(cid);
if (vstyle.viewEOL || (!IsEOLChar(chDoc))) {
lineLength++;
int lineLength = posLineEnd - posLineStart;
if (!vstyle.viewEOL) {
int cid = posLineEnd - 1;
while ((cid > posLineStart) && IsEOLChar(pdoc->CharAt(cid))) {
cid--;
lineLength--;
}
}
if (lineLength == ll->numCharsInLine) {
int numCharsInLine = 0;
// See if chars, styles, indicators, are all the same
bool allSame = true;
const int styleMask = pdoc->stylingBitsMask;
// Check base line layout
for (int charInDoc = posLineStart; allSame && (charInDoc < posLineEnd); charInDoc++) {
char styleByte = 0;
int numCharsInLine = 0;
while (numCharsInLine < lineLength) {
int charInDoc = numCharsInLine + posLineStart;
char chDoc = pdoc->CharAt(charInDoc);
if (vstyle.viewEOL || (!IsEOLChar(chDoc))) {
char styleByte = pdoc->StyleAt(charInDoc);
styleByte = pdoc->StyleAt(charInDoc);
allSame = allSame &&
(ll->styles[numCharsInLine] == static_cast<char>(styleByte & styleMask));
(ll->styles[numCharsInLine] == static_cast<unsigned char>(styleByte & styleMask));
allSame = allSame &&
(ll->indicators[numCharsInLine] == static_cast<char>(styleByte & ~styleMask));
if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseUpper)
if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseMixed)
allSame = allSame &&
(ll->chars[numCharsInLine] == static_cast<char>(toupper(chDoc)));
(ll->chars[numCharsInLine] == chDoc);
else if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseLower)
allSame = allSame &&
(ll->chars[numCharsInLine] == static_cast<char>(tolower(chDoc)));
else
else // Style::caseUpper
allSame = allSame &&
(ll->chars[numCharsInLine] == chDoc);
(ll->chars[numCharsInLine] == static_cast<char>(toupper(chDoc)));
numCharsInLine++;
}
}
allSame = allSame && (ll->styles[numCharsInLine] == styleByte); // For eolFilled
if (allSame) {
ll->validity = LineLayout::llPositions;
} else {
@ -1967,10 +1989,12 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
char styleByte = 0;
int styleMask = pdoc->stylingBitsMask;
ll->styleBitsSet = 0;
// Fill base line layout
for (int charInDoc = posLineStart; charInDoc < posLineEnd; charInDoc++) {
char chDoc = pdoc->CharAt(charInDoc);
styleByte = pdoc->StyleAt(charInDoc);
ll->styleBitsSet |= styleByte;
if (vstyle.viewEOL || (!IsEOLChar(chDoc))) {
ll->chars[numCharsInLine] = chDoc;
ll->styles[numCharsInLine] = static_cast<char>(styleByte & styleMask);
@ -1997,6 +2021,7 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
bool lastSegItalics = false;
Font &ctrlCharsFont = vstyle.styles[STYLE_CONTROLCHAR].font;
int ctrlCharWidth[32] = {0};
bool isControlNext = IsControlCharacter(ll->chars[0]);
for (int charInLine = 0; charInLine < numCharsInLine; charInLine++) {
bool isControl = isControlNext;
@ -2010,9 +2035,13 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
ll->positions[charInLine + 1] = ((((startsegx + 2) /
tabWidth) + 1) * tabWidth) - startsegx;
} else if (controlCharSymbol < 32) {
if (ctrlCharWidth[ll->chars[charInLine]] == 0) {
const char *ctrlChar = ControlCharacterString(ll->chars[charInLine]);
// +3 For a blank on front and rounded edge each side:
ll->positions[charInLine + 1] = surface->WidthText(ctrlCharsFont, ctrlChar, istrlen(ctrlChar)) + 3;
ctrlCharWidth[ll->chars[charInLine]] =
surface->WidthText(ctrlCharsFont, ctrlChar, istrlen(ctrlChar)) + 3;
}
ll->positions[charInLine + 1] = ctrlCharWidth[ll->chars[charInLine]];
} else {
char cc[2] = { static_cast<char>(controlCharSymbol), '\0' };
surface->MeasureWidths(ctrlCharsFont, cc, 1,
@ -2401,6 +2430,8 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
}
}
}
} else if (rcSegment.left > rcLine.right) {
break;
}
startseg = i + 1;
}
@ -2563,6 +2594,8 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
rcUL.bottom = rcUL.top + 1;
surface->FillRectangle(rcUL, textFore);
}
} else if (rcSegment.left > rcLine.right) {
break;
}
startseg = i + 1;
}
@ -2571,6 +2604,10 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
// Draw indicators
// foreach indicator...
for (int indicnum = 0, mask = 1 << pdoc->stylingBits; mask < 0x100; indicnum++) {
if (!(mask & ll->styleBitsSet)) {
mask <<= 1;
continue;
}
int startPos = -1;
// foreach style pos in line...
for (int indicPos = lineStart; indicPos <= lineEnd; indicPos++) {
@ -2671,7 +2708,7 @@ void Editor::RefreshPixMaps(Surface *surfaceWindow) {
if (bufferedDraw) {
if (!pixmapLine->Initialised()) {
PRectangle rcClient = GetClientRectangle();
pixmapLine->InitPixMap(rcClient.Width(), rcClient.Height(),
pixmapLine->InitPixMap(rcClient.Width(), vs.lineHeight,
surfaceWindow, wMain.GetID());
pixmapSelMargin->InitPixMap(vs.fixedColumnWidth,
rcClient.Height(), surfaceWindow, wMain.GetID());
@ -2802,6 +2839,8 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
//ElapsedTime et;
if (lineDoc != lineDocPrevious) {
ll.Set(0);
// For rectangular selection this accesses the layout cache so should be after layout returned.
lineIterator.SetAt(lineDoc);
ll.Set(RetrieveLineLayout(lineDoc));
LayoutLine(lineDoc, surface, vs, ll, wrapWidth);
lineDocPrevious = lineDoc;
@ -2813,7 +2852,6 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
ll->selStart = SelectionStart();
ll->selEnd = SelectionEnd();
} else {
lineIterator.SetAt(lineDoc);
ll->selStart = lineIterator.startPos;
ll->selEnd = lineIterator.endPos;
}
@ -2962,6 +3000,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
visibleLine++;
//gdk_flush();
}
ll.Set(0);
//if (durPaint < 0.00000001)
// durPaint = 0.00000001;
@ -3741,8 +3780,13 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) {
}
if (mh.modificationType & SC_MOD_CHANGEMARKER) {
if (paintState == notPainting) {
if ((paintState == notPainting) || !PaintContainsMargin()) {
if (mh.modificationType & SC_MOD_CHANGEFOLD) {
// Fold changes can affect the drawing of following lines so redraw whole margin
RedrawSelMargin();
} else {
RedrawSelMargin(mh.line);
}
}
}
@ -3777,7 +3821,7 @@ void Editor::NotifyDeleted(Document *, void *) {
/* Do nothing */
}
void Editor::NotifyMacroRecord(unsigned int iMessage, unsigned long wParam, long lParam) {
void Editor::NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
// Enumerates all macroable messages
switch (iMessage) {
@ -3878,6 +3922,7 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, unsigned long wParam, long
case SCI_LINEENDRECTEXTEND:
case SCI_PAGEUPRECTEXTEND:
case SCI_PAGEDOWNRECTEXTEND:
case SCI_SELECTIONDUPLICATE:
break;
// Filter out all others like display changes. Also, newlines are redundant
@ -3991,15 +4036,26 @@ void Editor::LineTranspose() {
}
}
void Editor::LineDuplicate() {
void Editor::Duplicate(bool forLine) {
int start = SelectionStart();
int end = SelectionEnd();
if (start == end) {
forLine = true;
}
if (forLine) {
int line = pdoc->LineFromPosition(currentPos);
int start = pdoc->LineStart(line);
int end = pdoc->LineEnd(line);
char *thisLine = CopyRange(start, end);
start = pdoc->LineStart(line);
end = pdoc->LineEnd(line);
}
char *text = CopyRange(start, end);
if (forLine) {
const char *eol = StringFromEOLMode(pdoc->eolMode);
pdoc->InsertString(end, eol);
pdoc->InsertString(end + istrlen(eol), thisLine, end - start);
delete []thisLine;
pdoc->InsertString(end + istrlen(eol), text, end - start);
} else {
pdoc->InsertString(end, text, end - start);
}
delete []text;
}
void Editor::CancelModes() {
@ -4447,7 +4503,10 @@ int Editor::KeyCommand(unsigned int iMessage) {
LineTranspose();
break;
case SCI_LINEDUPLICATE:
LineDuplicate();
Duplicate(true);
break;
case SCI_SELECTIONDUPLICATE:
Duplicate(false);
break;
case SCI_LOWERCASE:
ChangeCaseOfSelection(false);
@ -5064,7 +5123,7 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b
NotifyHotSpotClicked(newPos, shift, ctrl, alt);
}
if (!shift) {
inDragDrop = PointInSelection(pt);
inDragDrop = PointInSelection(pt) && !SelectionEmpty();
}
if (inDragDrop) {
SetMouseCapture(false);
@ -5217,7 +5276,7 @@ void Editor::ButtonMove(Point pt) {
}
}
// Display regular (drag) cursor over selection
if (PointInSelection(pt)) {
if (PointInSelection(pt) && !SelectionEmpty()) {
DisplayCursor(Window::cursorArrow);
} else if (PointIsHotspot(pt)) {
DisplayCursor(Window::cursorHand);
@ -5349,16 +5408,14 @@ void Editor::SetFocusState(bool focusState) {
}
}
static bool IsIn(int a, int minimum, int maximum) {
return (a >= minimum) && (a <= maximum);
bool Editor::PaintContains(PRectangle rc) {
return rcPaint.Contains(rc);
}
static bool IsOverlap(int mina, int maxa, int minb, int maxb) {
return
IsIn(mina, minb, maxb) ||
IsIn(maxa, minb, maxb) ||
IsIn(minb, mina, maxa) ||
IsIn(maxb, mina, maxa);
bool Editor::PaintContainsMargin() {
PRectangle rcSelMargin = GetClientRectangle();
rcSelMargin.right = vs.fixedColumnWidth;
return PaintContains(rcSelMargin);
}
void Editor::CheckForChangeOutsidePaint(Range r) {
@ -5367,97 +5424,19 @@ void Editor::CheckForChangeOutsidePaint(Range r) {
if (!r.Valid())
return;
PRectangle rcRange = RectangleFromRange(r.start, r.end);
PRectangle rcText = GetTextRectangle();
// Determine number of lines displayed including a possible partially displayed last line
int linesDisplayed = (rcText.bottom - rcText.top - 1) / vs.lineHeight + 1;
int bottomLine = topLine + linesDisplayed - 1;
int lineRangeStart = cs.DisplayFromDoc(pdoc->LineFromPosition(r.start));
int lineRangeEnd = cs.DisplayFromDoc(pdoc->LineFromPosition(r.end));
if (!IsOverlap(topLine, bottomLine, lineRangeStart, lineRangeEnd)) {
//Platform::DebugPrintf("No overlap (%d-%d) with window(%d-%d)\n",
// lineRangeStart, lineRangeEnd, topLine, bottomLine);
return;
if (rcRange.top < rcText.top) {
rcRange.top = rcText.top;
}
if (rcRange.bottom > rcText.bottom) {
rcRange.bottom = rcText.bottom;
}
// Assert rcPaint contained within or equal to rcText
if (rcPaint.top > rcText.top) {
// does range intersect rcText.top .. rcPaint.top
int paintTopLine = ((rcPaint.top - rcText.top - 1) / vs.lineHeight) + topLine;
// paintTopLine is the top line of the paint rectangle or the line just above if that line is completely inside the paint rectangle
if (IsOverlap(topLine, paintTopLine, lineRangeStart, lineRangeEnd)) {
//Platform::DebugPrintf("Change (%d-%d) in top npv(%d-%d)\n",
// lineRangeStart, lineRangeEnd, topLine, paintTopLine);
if (!PaintContains(rcRange)) {
AbandonPaint();
return;
}
}
if (rcPaint.bottom < rcText.bottom) {
// does range intersect rcPaint.bottom .. rcText.bottom
int paintBottomLine = ((rcPaint.bottom - rcText.top - 1) / vs.lineHeight + 1) + topLine;
// paintTopLine is the bottom line of the paint rectangle or the line just below if that line is completely inside the paint rectangle
if (IsOverlap(paintBottomLine, bottomLine, lineRangeStart, lineRangeEnd)) {
//Platform::DebugPrintf("Change (%d-%d) in bottom npv(%d-%d)\n",
// lineRangeStart, lineRangeEnd, paintBottomLine, bottomLine);
AbandonPaint();
return;
}
}
}
}
char BraceOpposite(char ch) {
switch (ch) {
case '(':
return ')';
case ')':
return '(';
case '[':
return ']';
case ']':
return '[';
case '{':
return '}';
case '}':
return '{';
case '<':
return '>';
case '>':
return '<';
default:
return '\0';
}
}
// TODO: should be able to extend styled region to find matching brace
// TODO: may need to make DBCS safe
// so should be moved into Document
int Editor::BraceMatch(int position, int /*maxReStyle*/) {
char chBrace = pdoc->CharAt(position);
char chSeek = BraceOpposite(chBrace);
if (chSeek == '\0')
return - 1;
char styBrace = static_cast<char>(
pdoc->StyleAt(position) & pdoc->stylingBitsMask);
int direction = -1;
if (chBrace == '(' || chBrace == '[' || chBrace == '{' || chBrace == '<')
direction = 1;
int depth = 1;
position = position + direction;
while ((position >= 0) && (position < pdoc->Length())) {
char chAtPos = pdoc->CharAt(position);
char styAtPos = static_cast<char>(pdoc->StyleAt(position) & pdoc->stylingBitsMask);
if ((position > pdoc->GetEndStyled()) || (styAtPos == styBrace)) {
if (chAtPos == chBrace)
depth++;
if (chAtPos == chSeek)
depth--;
if (depth == 0)
return position;
}
position = position + direction;
}
return - 1;
}
void Editor::SetBraceHighlight(Position pos0, Position pos1, int matchStyle) {
@ -6206,6 +6185,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
if (lParam == 0) {
return 1 + lineEnd - lineStart;
}
PLATFORM_ASSERT(wParam > 0);
char *ptr = CharPtrFromSPtr(lParam);
unsigned int iPlace = 0;
for (unsigned int iChar = lineStart; iChar < lineEnd && iPlace < wParam - 1; iChar++) {
@ -6523,6 +6503,10 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
int markerID = pdoc->AddMark(wParam, lParam);
return markerID;
}
case SCI_MARKERADDSET:
if (lParam != 0)
pdoc->AddMarkSet(wParam, lParam);
break;
case SCI_MARKERDELETE:
pdoc->DeleteMark(wParam, lParam);
@ -7000,6 +6984,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
case SCI_LINEENDRECTEXTEND:
case SCI_PAGEUPRECTEXTEND:
case SCI_PAGEDOWNRECTEXTEND:
case SCI_SELECTIONDUPLICATE:
return KeyCommand(iMessage);
case SCI_BRACEHIGHLIGHT:
@ -7013,7 +6998,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
case SCI_BRACEMATCH:
// wParam is position of char to find brace for,
// lParam is maximum amount of text to restyle to find it
return BraceMatch(wParam, lParam);
return pdoc->BraceMatch(wParam, lParam);
case SCI_GETVIEWEOL:
return vs.viewEOL;
@ -7230,6 +7215,13 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
InvalidateStyleRedraw();
break;
case SCI_SETPASTECONVERTENDINGS:
convertPastes = wParam != 0;
break;
case SCI_GETPASTECONVERTENDINGS:
return convertPastes ? 1 : 0;
default:
return DefWndProc(iMessage, wParam, lParam);
}

View File

@ -64,6 +64,7 @@ public:
int edgeColumn;
char *chars;
unsigned char *styles;
int styleBitsSet;
char *indicators;
int *positions;
char bracePreviousStyles[2];
@ -105,6 +106,7 @@ class LineLayoutCache {
LineLayout **cache;
bool allInvalidated;
int styleClock;
int useCount;
void Allocate(int length_);
void AllocateForLevel(int linesOnScreen, int linesInDoc);
public:
@ -312,6 +314,8 @@ protected: // ScintillaBase subclass needs access to much of Editor
int wrapVisualStartIndent;
int actualWrapVisualStartIndent;
bool convertPastes;
Document *pdoc;
Editor();
@ -342,7 +346,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
bool AbandonPaint();
void RedrawRect(PRectangle rc);
void Redraw();
void RedrawSelMargin();
void RedrawSelMargin(int line=-1);
PRectangle RectangleFromRange(int start, int end);
void InvalidateRange(int start, int end);
@ -452,7 +456,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
void PageMove(int direction, selTypes sel=noSel, bool stuttered = false);
void ChangeCaseOfSelection(bool makeUpperCase);
void LineTranspose();
void LineDuplicate();
void Duplicate(bool forLine);
virtual void CancelModes();
void NewLine();
void CursorUpOrDown(int direction, selTypes sel=noSel);
@ -502,8 +506,9 @@ protected: // ScintillaBase subclass needs access to much of Editor
virtual bool HaveMouseCapture() = 0;
void SetFocusState(bool focusState);
virtual bool PaintContains(PRectangle rc);
bool PaintContainsMargin();
void CheckForChangeOutsidePaint(Range r);
int BraceMatch(int position, int maxReStyle);
void SetBraceHighlight(Position pos0, Position pos1, int matchStyle);
void SetDocPointer(Document *document);

View File

@ -140,7 +140,7 @@ const KeyToCommand KeyMap::MapDefault[] = {
{'L', SCI_CSHIFT, SCI_LINEDELETE},
{'T', SCI_CSHIFT, SCI_LINECOPY},
{'T', SCI_CTRL, SCI_LINETRANSPOSE},
{'D', SCI_CTRL, SCI_LINEDUPLICATE},
{'D', SCI_CTRL, SCI_SELECTIONDUPLICATE},
{'U', SCI_CTRL, SCI_LOWERCASE},
{'U', SCI_CSHIFT, SCI_UPPERCASE},
{0,0,0},

View File

@ -22,13 +22,17 @@
const LexerModule *LexerModule::base = 0;
int LexerModule::nextLanguage = SCLEX_AUTOMATIC+1;
LexerModule::LexerModule(int language_, LexerFunction fnLexer_,
const char *languageName_, LexerFunction fnFolder_,
const char * const wordListDescriptions_[]) :
LexerModule::LexerModule(int language_,
LexerFunction fnLexer_,
const char *languageName_,
LexerFunction fnFolder_,
const char * const wordListDescriptions_[],
int styleBits_) :
language(language_),
fnLexer(fnLexer_),
fnFolder(fnFolder_),
wordListDescriptions(wordListDescriptions_),
styleBits(styleBits_),
languageName(languageName_) {
next = base;
base = this;
@ -63,6 +67,10 @@ const char * LexerModule::GetWordListDescription(int index) const {
}
}
int LexerModule::GetStyleBitsNeeded() const {
return styleBits;
}
const LexerModule *LexerModule::Find(int language) {
const LexerModule *lm = base;
while (lm) {
@ -155,7 +163,6 @@ int Scintilla_LinkLexers() {
LINK_LEXER(lmSQL);
LINK_LEXER(lmTeX);
//--Autogenerated -- end of automatically generated section
return 1;

View File

@ -445,7 +445,7 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
HereDoc.Quoted = false;
HereDoc.DelimiterLength = 0;
HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
if (chNext == '\'') { // a quoted here-doc delimiter (' only)
if (chNext == '\'' || chNext == '\"') { // a quoted here-doc delimiter (' or ")
i++;
ch = chNext;
chNext = chNext2;
@ -454,8 +454,9 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
HereDoc.Indent = true;
HereDoc.State = 0;
} else if (isalpha(chNext) || chNext == '_' || chNext == '\\'
|| chNext == '-' || chNext == '+') {
|| chNext == '-' || chNext == '+' || chNext == '!') {
// an unquoted here-doc delimiter, no special handling
// TODO check what exactly bash considers part of the delim
} else if (chNext == '<') { // HERE string <<<
i++;
ch = chNext;
@ -489,7 +490,7 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
}
} else { // an unquoted here-doc delimiter
if (isalnum(ch) || ch == '_' || ch == '-' || ch == '+') {
if (isalnum(ch) || ch == '_' || ch == '-' || ch == '+' || ch == '!') {
HereDoc.Delimiter[HereDoc.DelimiterLength++] = ch;
HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
} else if (ch == '\\') {

View File

@ -36,10 +36,17 @@ static inline bool IsAWordStart(int ch) {
}
static inline bool IsADoxygenChar(int ch) {
return (islower(ch) || ch == '$' || ch == '@' ||
return (ch < 0x80 && islower(ch)) || ch == '$' || ch == '@' ||
ch == '\\' || ch == '&' || ch == '<' ||
ch == '>' || ch == '#' || ch == '{' ||
ch == '}' || ch == '[' || ch == ']');
ch == '}' || ch == '[' || ch == ']';
}
static bool IsSpaceEquiv(int state) {
return (state <= SCE_C_COMMENTDOC) ||
// including SCE_C_DEFAULT, SCE_C_COMMENT, SCE_C_COMMENTLINE
(state == SCE_C_COMMENTLINEDOC) || (state == SCE_C_COMMENTDOCKEYWORD) ||
(state == SCE_C_COMMENTDOCKEYWORDERROR);
}
static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
@ -56,6 +63,33 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
int visibleChars = 0;
bool lastWordWasUUID = false;
int styleBeforeDCKeyword = SCE_C_DEFAULT;
bool continuationLine = false;
if (initStyle == SCE_C_PREPROCESSOR) {
// Set continuationLine if last character of previous line is '\'
int lineCurrent = styler.GetLine(startPos);
if (lineCurrent > 0) {
int chBack = styler.SafeGetCharAt(startPos-1, 0);
int chBack2 = styler.SafeGetCharAt(startPos-2, 0);
int lineEndChar = '!';
if (chBack2 == '\r' && chBack == '\n') {
lineEndChar = styler.SafeGetCharAt(startPos-3, 0);
} else if (chBack == '\n' || chBack == '\r') {
lineEndChar = chBack2;
}
continuationLine = lineEndChar == '\\';
}
}
// look back to set chPrevNonWhite properly for better regex colouring
if (startPos > 0) {
int back = startPos;
while (--back && IsSpaceEquiv(styler.StyleAt(back)))
;
if (styler.StyleAt(back) == SCE_C_OPERATOR) {
chPrevNonWhite = styler.SafeGetCharAt(back);
}
}
StyleContext sc(startPos, length, initStyle, styler);
@ -69,7 +103,6 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
}
// Reset states to begining of colourise so no surprises
// if different sets of lines lexed.
chPrevNonWhite = ' ';
visibleChars = 0;
lastWordWasUUID = false;
}
@ -81,6 +114,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
if (sc.ch == '\r' && sc.chNext == '\n') {
sc.Forward();
}
continuationLine = true;
continue;
}
}
@ -116,7 +150,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
}
break;
case SCE_C_PREPROCESSOR:
if (sc.atLineStart) {
if (sc.atLineStart && !continuationLine) {
sc.SetState(SCE_C_DEFAULT);
} else if (stylingWithinPreprocessor) {
if (IsASpace(sc.ch)) {
@ -206,7 +240,10 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
if (sc.atLineStart) {
sc.SetState(SCE_C_DEFAULT);
} else if (sc.ch == '/') {
sc.ForwardSetState(SCE_C_DEFAULT);
sc.Forward();
while ((sc.ch < 0x80) && islower(sc.ch))
sc.Forward(); // gobble regex flags
sc.SetState(SCE_C_DEFAULT);
} else if (sc.ch == '\\') {
// Gobble up the quoted character
if (sc.chNext == '\\' || sc.chNext == '/') {
@ -287,10 +324,11 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
}
}
if (!IsASpace(sc.ch)) {
if (!IsASpace(sc.ch) && !IsSpaceEquiv(sc.state)) {
chPrevNonWhite = sc.ch;
visibleChars++;
}
continuationLine = false;
}
sc.Complete();
}

View File

@ -2,7 +2,7 @@
/** @file LexHTML.cxx
** Lexer for HTML.
**/
// Copyright 1998-2003 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>
@ -503,12 +503,28 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
char chPrev = ' ';
char ch = ' ';
char chPrevNonWhite = ' ';
// look back to set chPrevNonWhite properly for better regex colouring
if (scriptLanguage == eScriptJS && startPos > 0) {
int back = startPos;
int style = 0;
while (--back) {
style = styler.StyleAt(back);
if (style < SCE_HJ_DEFAULT || style > SCE_HJ_COMMENTDOC)
// includes SCE_HJ_COMMENT & SCE_HJ_COMMENTLINE
break;
}
if (style == SCE_HJ_SYMBOLS) {
chPrevNonWhite = styler.SafeGetCharAt(back);
}
}
styler.StartSegment(startPos);
const int lengthDoc = startPos + length;
for (int i = startPos; i < lengthDoc; i++) {
const char chPrev2 = chPrev;
chPrev = ch;
if (ch != ' ' && ch != '\t')
if (!isspacechar(ch) && state != SCE_HJ_COMMENT &&
state != SCE_HJ_COMMENTLINE && state != SCE_HJ_COMMENTDOC)
chPrevNonWhite = ch;
ch = styler[i];
char chNext = styler.SafeGetCharAt(i + 1);
@ -668,11 +684,9 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
inScriptType = eNonHtmlScriptPreProc;
else
inScriptType = eNonHtmlPreProc;
// fold whole script
if (foldHTMLPreprocessor){
// Fold whole script, but not if the XML first tag (all XML-like tags in this case)
if (foldHTMLPreprocessor && (scriptLanguage != eScriptXML)) {
levelCurrent++;
if (scriptLanguage == eScriptXML)
levelCurrent--; // no folding of the XML first tag (all XML-like tags in this case)
}
// should be better
ch = styler.SafeGetCharAt(i);
@ -751,7 +765,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
|| (inScriptType == eNonHtmlScriptPreProc)) && (
((scriptLanguage == eScriptPHP) && (ch == '?') && !isPHPStringState(state) && (state != SCE_HPHP_COMMENT)) ||
((scriptLanguage != eScriptNone) && !isStringState(state) &&
(ch == '%'))
((ch == '%') || (ch == '?')))
) && (chNext == '>')) ||
((scriptLanguage == eScriptSGML) && (ch == '>') && (state != SCE_H_SGML_COMMENT))) {
if (state == SCE_H_ASPAT) {
@ -796,10 +810,11 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
inScriptType = eNonHtmlScript;
else
inScriptType = eHtml;
scriptLanguage = eScriptNone;
// unfold all scripting languages
if (foldHTMLPreprocessor)
// Unfold all scripting languages, except for XML tag
if (foldHTMLPreprocessor && (scriptLanguage != eScriptXML)) {
levelCurrent--;
}
scriptLanguage = eScriptNone;
continue;
}
/////////////////////////////////////
@ -1237,12 +1252,14 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
if (ch == '/' && chPrev == '*') {
styler.ColourTo(i, StateToPrint);
state = SCE_HJ_DEFAULT;
ch = ' ';
}
break;
case SCE_HJ_COMMENTLINE:
if (ch == '\r' || ch == '\n') {
styler.ColourTo(i - 1, statePrintForState(SCE_HJ_COMMENTLINE, inScriptType));
state = SCE_HJ_DEFAULT;
ch = ' ';
}
break;
case SCE_HJ_DOUBLESTRING:
@ -1290,6 +1307,13 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
break;
case SCE_HJ_REGEX:
if (ch == '\r' || ch == '\n' || ch == '/') {
if (ch == '/') {
while (isascii(chNext) && islower(chNext)) { // gobble regex flags
i++;
ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
}
}
styler.ColourTo(i, StateToPrint);
state = SCE_HJ_DEFAULT;
} else if (ch == '\\') {
@ -1993,9 +2017,9 @@ static const char * const phpscriptWordListDesc[] = {
0,
};
LexerModule lmHTML(SCLEX_HTML, ColouriseHyperTextDoc, "hypertext", 0, htmlWordListDesc);
LexerModule lmXML(SCLEX_XML, ColouriseHyperTextDoc, "xml", 0, htmlWordListDesc);
LexerModule lmHTML(SCLEX_HTML, ColouriseHyperTextDoc, "hypertext", 0, htmlWordListDesc, 7);
LexerModule lmXML(SCLEX_XML, ColouriseHyperTextDoc, "xml", 0, htmlWordListDesc, 7);
// SCLEX_ASP and SCLEX_PHP should not be used in new code: use SCLEX_HTML instead.
LexerModule lmASP(SCLEX_ASP, ColouriseASPDoc, "asp", 0, htmlWordListDesc);
LexerModule lmPHP(SCLEX_PHP, ColourisePHPDoc, "php", 0, htmlWordListDesc);
LexerModule lmPHPSCRIPT(SCLEX_PHPSCRIPT, ColourisePHPScriptDoc, "phpscript", 0, phpscriptWordListDesc);
LexerModule lmASP(SCLEX_ASP, ColouriseASPDoc, "asp", 0, htmlWordListDesc, 7);
LexerModule lmPHP(SCLEX_PHP, ColourisePHPDoc, "php", 0, htmlWordListDesc, 7);
LexerModule lmPHPSCRIPT(SCLEX_PHPSCRIPT, ColourisePHPScriptDoc, "phpscript", 0, phpscriptWordListDesc, 7);

View File

@ -129,6 +129,8 @@ class ScintillaGTK : public ScintillaBase {
gint lastWheelMouseDirection;
gint wheelMouseIntensity;
GdkRegion *rgnUpdate;
// Private so ScintillaGTK objects can not be copied
ScintillaGTK(const ScintillaGTK &) : ScintillaBase() {}
ScintillaGTK &operator=(const ScintillaGTK &) { return * this; }
@ -153,6 +155,7 @@ private:
virtual bool SetIdle(bool on);
virtual void SetMouseCapture(bool on);
virtual bool HaveMouseCapture();
virtual bool PaintContains(PRectangle rc);
void FullPaint();
virtual PRectangle GetClientRectangle();
void SyncPaint(PRectangle rc);
@ -317,7 +320,8 @@ ScintillaGTK::ScintillaGTK(_ScintillaObject *sci_) :
#endif
#endif
lastWheelMouseDirection(0),
wheelMouseIntensity(0) {
wheelMouseIntensity(0),
rgnUpdate(0) {
sci = sci_;
wMain = GTK_WIDGET(sci);
@ -947,6 +951,22 @@ bool ScintillaGTK::HaveMouseCapture() {
return capturedMouse;
}
bool ScintillaGTK::PaintContains(PRectangle rc) {
bool contains = true;
if (paintState == painting) {
if (!rcPaint.Contains(rc)) {
contains = false;
} else if (rgnUpdate) {
GdkRectangle grc = {rc.left, rc.top,
rc.right - rc.left, rc.bottom - rc.top};
if (gdk_region_rect_in(rgnUpdate, &grc) != GDK_OVERLAP_RECTANGLE_IN) {
contains = false;
}
}
}
return contains;
}
// Redraw all of text area. This paint will not be abandoned.
void ScintillaGTK::FullPaint() {
#if GTK_MAJOR_VERSION < 2
@ -1340,10 +1360,10 @@ void ScintillaGTK::CreateCallTipWindow(PRectangle rc) {
gtk_drawing_area_size(GTK_DRAWING_AREA(PWidget(ct.wDraw)),
rc.Width(), rc.Height());
ct.wDraw.Show();
//ct.wCallTip.Show();
//gtk_widget_set_usize(PWidget(ct.wCallTip), rc.Width(), rc.Height());
if (PWidget(ct.wCallTip)->window) {
gdk_window_resize(PWidget(ct.wCallTip)->window, rc.Width(), rc.Height());
}
}
void ScintillaGTK::AddToPopUp(const char *label, int cmd, bool enabled) {
char fulllabel[200];
@ -2152,6 +2172,10 @@ gint ScintillaGTK::ExposeTextThis(GtkWidget * /*widget*/, GdkEventExpose *ose) {
rcPaint.right = ose->area.x + ose->area.width;
rcPaint.bottom = ose->area.y + ose->area.height;
PLATFORM_ASSERT(rgnUpdate == NULL);
#if GTK_MAJOR_VERSION >= 2
rgnUpdate = gdk_region_copy(ose->region);
#endif
PRectangle rcClient = GetClientRectangle();
paintingAllText = rcPaint.Contains(rcClient);
Surface *surfaceWindow = Surface::Allocate();
@ -2166,6 +2190,12 @@ gint ScintillaGTK::ExposeTextThis(GtkWidget * /*widget*/, GdkEventExpose *ose) {
FullPaint();
}
paintState = notPainting;
if (rgnUpdate) {
g_free(rgnUpdate);
}
rgnUpdate = 0;
return FALSE;
}
@ -2538,7 +2568,7 @@ GtkWidget* scintilla_new() {
return GTK_WIDGET(gtk_type_new(scintilla_get_type()));
}
void scintilla_set_id(ScintillaObject *sci, int id) {
void scintilla_set_id(ScintillaObject *sci, uptr_t id) {
ScintillaGTK *psci = reinterpret_cast<ScintillaGTK *>(sci->pscin);
psci->ctrlID = id;
}

View File

@ -104,7 +104,7 @@ public:
return currentPos - styler.GetStartSegment();
}
int GetRelative(int n) {
return styler.SafeGetCharAt(currentPos+n);
return static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+n));
}
bool Match(char ch0) {
return ch == ch0;
@ -134,7 +134,8 @@ public:
return false;
s++;
for (int n=2; *s; n++) {
if (*s != tolower((styler.SafeGetCharAt(currentPos+n))))
if (*s !=
tolower(static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+n))))
return false;
s++;
}

View File

@ -20,15 +20,19 @@ protected:
LexerFunction fnLexer;
LexerFunction fnFolder;
const char * const * wordListDescriptions;
int styleBits;
static const LexerModule *base;
static int nextLanguage;
public:
const char *languageName;
LexerModule(int language_, LexerFunction fnLexer_,
const char *languageName_=0, LexerFunction fnFolder_=0,
const char * const wordListDescriptions_[] = NULL);
LexerModule(int language_,
LexerFunction fnLexer_,
const char *languageName_=0,
LexerFunction fnFolder_=0,
const char * const wordListDescriptions_[] = NULL,
int styleBits_=5);
virtual ~LexerModule() {
}
int GetLanguage() const { return language; }
@ -37,6 +41,8 @@ public:
int GetNumWordLists() const;
const char *GetWordListDescription(int index) const;
int GetStyleBitsNeeded() const;
virtual void Lex(unsigned int startPos, int lengthDoc, int initStyle,
WordList *keywordlists[], Accessor &styler) const;
virtual void Fold(unsigned int startPos, int lengthDoc, int initStyle,

View File

@ -103,6 +103,8 @@
#define SCE_P_IDENTIFIER 11
#define SCE_P_COMMENTBLOCK 12
#define SCE_P_STRINGEOL 13
#define SCE_P_WORD2 14
#define SCE_P_DECORATOR 15
#define SCE_C_DEFAULT 0
#define SCE_C_COMMENT 1
#define SCE_C_COMMENTLINE 2
@ -851,15 +853,16 @@
#define SCE_CAML_TAGNAME 2
#define SCE_CAML_KEYWORD 3
#define SCE_CAML_KEYWORD2 4
#define SCE_CAML_LINENUM 5
#define SCE_CAML_OPERATOR 6
#define SCE_CAML_NUMBER 7
#define SCE_CAML_CHAR 8
#define SCE_CAML_STRING 9
#define SCE_CAML_COMMENT 10
#define SCE_CAML_COMMENT1 11
#define SCE_CAML_COMMENT2 12
#define SCE_CAML_COMMENT3 13
#define SCE_CAML_KEYWORD3 5
#define SCE_CAML_LINENUM 6
#define SCE_CAML_OPERATOR 7
#define SCE_CAML_NUMBER 8
#define SCE_CAML_CHAR 9
#define SCE_CAML_STRING 11
#define SCE_CAML_COMMENT 12
#define SCE_CAML_COMMENT1 13
#define SCE_CAML_COMMENT2 14
#define SCE_CAML_COMMENT3 15
#define SCE_HA_DEFAULT 0
#define SCE_HA_IDENTIFIER 1
#define SCE_HA_KEYWORD 2
@ -947,6 +950,7 @@
#define SCE_SQL_USER2 20
#define SCE_SQL_USER3 21
#define SCE_SQL_USER4 22
#define SCE_SQL_QUOTEDIDENTIFIER 23
#define SCE_ST_DEFAULT 0
#define SCE_ST_STRING 1
#define SCE_ST_NUMBER 2

View File

@ -137,6 +137,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_MARKERNEXT 2047
#define SCI_MARKERPREVIOUS 2048
#define SCI_MARKERDEFINEPIXMAP 2049
#define SCI_MARKERADDSET 2466
#define SC_MARGIN_SYMBOL 0
#define SC_MARGIN_NUMBER 1
#define SCI_SETMARGINTYPEN 2240
@ -603,6 +604,9 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_GETCARETSTICKY 2457
#define SCI_SETCARETSTICKY 2458
#define SCI_TOGGLECARETSTICKY 2459
#define SCI_SETPASTECONVERTENDINGS 2467
#define SCI_GETPASTECONVERTENDINGS 2468
#define SCI_SELECTIONDUPLICATE 2469
#define SCI_STARTRECORD 3001
#define SCI_STOPRECORD 3002
#define SCI_SETLEXER 4001
@ -616,6 +620,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_GETPROPERTY 4008
#define SCI_GETPROPERTYEXPANDED 4009
#define SCI_GETPROPERTYINT 4010
#define SCI_GETSTYLEBITSNEEDED 4011
#define SC_MOD_INSERTTEXT 0x1
#define SC_MOD_DELETETEXT 0x2
#define SC_MOD_CHANGESTYLE 0x4
@ -650,6 +655,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCK_ADD 310
#define SCK_SUBTRACT 311
#define SCK_DIVIDE 312
#define SCMOD_NORM 0
#define SCMOD_SHIFT 1
#define SCMOD_CTRL 2
#define SCMOD_ALT 4
@ -713,11 +719,11 @@ struct RangeToFormat {
#endif
struct NotifyHeader {
// hwndFrom is really an environment specifc window handle or pointer
// Compatible with Windows NMHDR.
// hwndFrom is really an environment specific window handle or pointer
// but most clients of Scintilla.h do not have this type visible.
//WindowID hwndFrom;
void *hwndFrom;
unsigned int idFrom;
uptr_t idFrom;
unsigned int code;
};

View File

@ -313,6 +313,9 @@ fun int MarkerPrevious=2048(int lineStart, int markerMask)
# Define a marker from a pixmap.
fun void MarkerDefinePixmap=2049(int markerNumber, string pixmap)
# Add a set of markers to a line.
fun void MarkerAddSet=2466(int line, int set)
enu MarginType=SC_MARGIN_
val SC_MARGIN_SYMBOL=0
val SC_MARGIN_NUMBER=1
@ -1629,6 +1632,15 @@ set void SetCaretSticky=2458(bool useCaretStickyBehaviour,)
# Switch between sticky and non-sticky: meant to be bound to a key.
fun void ToggleCaretSticky=2459(,)
# Enable/Disable convert-on-paste for line endings
set void SetPasteConvertEndings=2467(bool convert,)
# Get convert-on-paste setting
get bool GetPasteConvertEndings=2468(,)
# Duplicate the selection. If selection empty duplicate the line containing the caret.
fun void SelectionDuplicate=2469(,)
# Start notifying the container of all key presses and commands.
fun void StartRecord=3001(,)
@ -1670,6 +1682,9 @@ fun int GetPropertyExpanded=4009(string key, stringresult buf)
# interpreted as an int AFTER any "$()" variable replacement.
get int GetPropertyInt=4010(string key,)
# Retrieve the number of bits the current lexer needs for styling.
get int GetStyleBitsNeeded=4011(,)
# Notifications
# Type of modification and the action which caused the modification.
# These are defined as a bit mask to make it easy to specify which notifications are wanted.
@ -1722,6 +1737,7 @@ val SCK_SUBTRACT=311
val SCK_DIVIDE=312
enu KeyMod=SCMOD_
val SCMOD_NORM=0
val SCMOD_SHIFT=1
val SCMOD_CTRL=2
val SCMOD_ALT=4
@ -1823,6 +1839,8 @@ val SCE_P_OPERATOR=10
val SCE_P_IDENTIFIER=11
val SCE_P_COMMENTBLOCK=12
val SCE_P_STRINGEOL=13
val SCE_P_WORD2=14
val SCE_P_DECORATOR=15
# Lexical states for SCLEX_CPP
lex Cpp=SCLEX_CPP SCE_C_
lex Pascal=SCLEX_PASCAL SCE_C_
@ -2690,15 +2708,16 @@ val SCE_CAML_IDENTIFIER=1
val SCE_CAML_TAGNAME=2
val SCE_CAML_KEYWORD=3
val SCE_CAML_KEYWORD2=4
val SCE_CAML_LINENUM=5
val SCE_CAML_OPERATOR=6
val SCE_CAML_NUMBER=7
val SCE_CAML_CHAR=8
val SCE_CAML_STRING=9
val SCE_CAML_COMMENT=10
val SCE_CAML_COMMENT1=11
val SCE_CAML_COMMENT2=12
val SCE_CAML_COMMENT3=13
val SCE_CAML_KEYWORD3=5
val SCE_CAML_LINENUM=6
val SCE_CAML_OPERATOR=7
val SCE_CAML_NUMBER=8
val SCE_CAML_CHAR=9
val SCE_CAML_STRING=11
val SCE_CAML_COMMENT=12
val SCE_CAML_COMMENT1=13
val SCE_CAML_COMMENT2=14
val SCE_CAML_COMMENT3=15
# Lexical states for SCLEX_HASKELL
lex Haskell=SCLEX_HASKELL SCE_HA_
val SCE_HA_DEFAULT=0
@ -2794,6 +2813,7 @@ val SCE_SQL_USER1=19
val SCE_SQL_USER2=20
val SCE_SQL_USER3=21
val SCE_SQL_USER4=22
val SCE_SQL_QUOTEDIDENTIFIER=23
# Lexical states for SCLEX_SMALLTALK
lex Smalltalk=SCLEX_SMALLTALK SCE_ST_
val SCE_ST_DEFAULT=0

View File

@ -36,7 +36,7 @@ struct _ScintillaClass {
GtkType scintilla_get_type (void);
GtkWidget* scintilla_new (void);
void scintilla_set_id (ScintillaObject *sci,int id);
void scintilla_set_id (ScintillaObject *sci, uptr_t id);
sptr_t scintilla_send_message (ScintillaObject *sci,unsigned int iMessage, uptr_t wParam, sptr_t lParam);
void scintilla_release_resources(void);