aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/ContractionState.cxx6
-rw-r--r--src/Editor.cxx29
-rw-r--r--src/LexCPP.cxx9
-rw-r--r--src/PropSet.cxx104
-rw-r--r--win32/ScintillaWin.cxx34
5 files changed, 122 insertions, 60 deletions
diff --git a/src/ContractionState.cxx b/src/ContractionState.cxx
index 456948900..0b987b81b 100644
--- a/src/ContractionState.cxx
+++ b/src/ContractionState.cxx
@@ -171,12 +171,6 @@ bool ContractionState::SetVisible(int lineDocStart, int lineDocEnd, bool visible
delta += visible ? 1 : -1;
lines[line].visible = visible;
}
- lines[line].displayLine += delta;
- }
- if (delta != 0) {
- for (int line=lineDocEnd+1; line <= linesInDoc; line++) {
- lines[line].displayLine += delta;
- }
}
}
linesInDisplay += delta;
diff --git a/src/Editor.cxx b/src/Editor.cxx
index 3cf2c179e..694d4855a 100644
--- a/src/Editor.cxx
+++ b/src/Editor.cxx
@@ -734,9 +734,10 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
char styleByte = 0;
int styleMask = pdoc->stylingBitsMask;
ll.xHighlightGuide = 0;
- for (int charInDoc = posLineStart;
- charInDoc < posLineEnd && numCharsInLine < LineLayout::maxLineLength - 2;
- charInDoc++) {
+ if (posLineEnd >= (posLineStart + LineLayout::maxLineLength)) {
+ posLineEnd = posLineStart + LineLayout::maxLineLength - 1;
+ }
+ for (int charInDoc=posLineStart; charInDoc<posLineEnd; charInDoc++) {
char chDoc = pdoc->CharAt(charInDoc);
styleByte = pdoc->StyleAt(charInDoc);
if (vstyle.viewEOL || ((chDoc != '\r') && (chDoc != '\n'))) {
@@ -772,8 +773,14 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
ll.positions[charInLine + 1] = surface->WidthText(ctrlCharsFont, ctrlChar, strlen(ctrlChar)) + 3;
}
} else {
- surface->MeasureWidths(vstyle.styles[ll.styles[charInLine]].font, ll.chars + startseg,
- charInLine - startseg + 1, ll.positions + startseg + 1);
+ int lenSeg = charInLine - startseg + 1;
+ if ((lenSeg == 1) && (' ' == ll.chars[startseg])) {
+ // Over half the segments are single characters and of these about half are space characters.
+ ll.positions[charInLine + 1] = vstyle.styles[ll.styles[charInLine]].spaceWidth;
+ } else {
+ surface->MeasureWidths(vstyle.styles[ll.styles[charInLine]].font, ll.chars + startseg,
+ charInLine - startseg + 1, ll.positions + startseg + 1);
+ }
}
for (int posToIncrease = startseg; posToIncrease <= (charInLine + 1); posToIncrease++) {
ll.positions[posToIncrease] += startsegx;
@@ -1723,10 +1730,14 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) {
}
}
}
- if (mh.modificationType & SC_MOD_BEFOREINSERT) {
- NotifyNeedShown(mh.position, 0);
- } else if (mh.modificationType & SC_MOD_BEFOREDELETE) {
- NotifyNeedShown(mh.position, mh.length);
+ if (cs.LinesDisplayed() < cs.LinesInDoc()) {
+ // Some lines are hidden so may need shown.
+ // TODO: check if the modified area is hidden.
+ if (mh.modificationType & SC_MOD_BEFOREINSERT) {
+ NotifyNeedShown(mh.position, 0);
+ } else if (mh.modificationType & SC_MOD_BEFOREDELETE) {
+ NotifyNeedShown(mh.position, mh.length);
+ }
}
if (mh.linesAdded != 0) {
diff --git a/src/LexCPP.cxx b/src/LexCPP.cxx
index 8e3b7c498..b77468a44 100644
--- a/src/LexCPP.cxx
+++ b/src/LexCPP.cxx
@@ -19,14 +19,13 @@
static bool classifyWordCpp(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
char s[100];
- bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');
- bool wordIsUUID = false;
for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
s[i] = styler[start + i];
s[i + 1] = '\0';
}
+ bool wordIsUUID = false;
char chAttr = SCE_C_IDENTIFIER;
- if (wordIsNumber)
+ if (isdigit(s[0]) || (s[0] == '.'))
chAttr = SCE_C_NUMBER;
else {
if (keywords.InList(s)) {
@@ -99,7 +98,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
state = SCE_C_UUID;
lastWordWasUUID = false;
} else {
- state = SCE_C_WORD;
+ state = SCE_C_IDENTIFIER;
}
} else if (ch == '/' && chNext == '*') {
styler.ColourTo(i-1, state);
@@ -132,7 +131,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
levelCurrent += (ch == '{') ? 1 : -1;
}
}
- } else if (state == SCE_C_WORD) {
+ } else if (state == SCE_C_IDENTIFIER) {
if (!iswordchar(ch)) {
lastWordWasUUID = classifyWordCpp(styler.GetStartSegment(), i - 1, keywords, styler);
state = SCE_C_DEFAULT;
diff --git a/src/PropSet.cxx b/src/PropSet.cxx
index 6fc02cb0a..0f2b1bd85 100644
--- a/src/PropSet.cxx
+++ b/src/PropSet.cxx
@@ -24,6 +24,16 @@ bool EqualCaseInsensitive(const char *a, const char *b) {
#endif
}
+unsigned int HashString(const char *s) {
+ unsigned int ret = 0;
+ while (*s) {
+ ret <<= 4;
+ ret ^= *s;
+ s++;
+ }
+ return ret;
+}
+
// Get a line of input. If end of line escaped with '\\' then continue reading.
static bool GetFullLine(const char *&fpc, int &lenData, char *s, int len) {
bool continuation = true;
@@ -56,44 +66,46 @@ static bool GetFullLine(const char *&fpc, int &lenData, char *s, int len) {
PropSet::PropSet() {
superPS = 0;
- size = 10;
+ size = 20;
used = 0;
- vals = new char * [size];
+ properties = new Property[size];
}
PropSet::~PropSet() {
superPS = 0;
Clear();
- delete []vals;
+ delete []properties;
}
void PropSet::EnsureCanAddEntry() {
- if (used >= size - 2) {
- int newsize = size + 10;
- char **newvals = new char * [newsize];
+ if (used >= size - 1) {
+ int newsize = size + 20;
+ Property *newprops = new Property[newsize];
for (int i = 0; i < used; i++) {
- newvals[i] = vals[i];
+ newprops[i] = properties[i];
}
- delete []vals;
- vals = newvals;
+ delete []properties;
+ properties = newprops;
size = newsize;
}
}
void PropSet::Set(const char *key, const char *val) {
EnsureCanAddEntry();
- for (int i = 0; i < used; i += 2) {
- if (0 == strcmp(vals[i], key)) {
+ for (int i = 0; i < used; i++) {
+ if (0 == strcmp(properties[i].key, key)) {
// Replace current value
- delete [](vals[i + 1]);
- vals[i + 1] = StringDup(val);
+ delete [](properties[i].val);
+ properties[i].val = StringDup(val);
return;
}
}
// Not found
- vals[used++] = StringDup(key);
- vals[used++] = StringDup(val);
+ properties[used].hash = HashString(key);
+ properties[used].key = StringDup(key);
+ properties[used].val = StringDup(val);
+ used++;
}
void PropSet::Set(char *keyval) {
@@ -108,9 +120,10 @@ void PropSet::Set(char *keyval) {
}
SString PropSet::Get(const char *key) {
- for (int i = 0; i < used; i += 2) {
- if (0 == strcmp(vals[i], key)) {
- return vals[i + 1];
+ unsigned int hash = HashString(key);
+ for (int i = 0; i < used; i++) {
+ if ((hash == properties[i].hash) && (0 == strcmp(properties[i].key, key))) {
+ return properties[i].val;
}
}
if (superPS) {
@@ -121,6 +134,36 @@ SString PropSet::Get(const char *key) {
}
}
+SString PropSet::GetExpanded(const char *key) {
+ SString val = Get(key);
+ return Expand(val.c_str());
+}
+
+SString PropSet::Expand(const char *withvars) {
+ char *base = StringDup(withvars);
+ char *cpvar = strstr(base, "$(");
+ while (cpvar) {
+ char *cpendvar = strchr(cpvar, ')');
+ if (cpendvar) {
+ int lenvar = cpendvar - cpvar - 2; // Subtract the $()
+ char *var = StringDup(cpvar+2, lenvar);
+ SString val = GetExpanded(var);
+ int newlenbase = strlen(base) + val.length() - lenvar;
+ char *newbase = new char[newlenbase];
+ strncpy(newbase, base, cpvar - base);
+ strcpy(newbase + (cpvar - base), val.c_str());
+ strcpy(newbase + (cpvar - base) + val.length(), cpendvar + 1);
+ delete []var;
+ delete []base;
+ base = newbase;
+ }
+ cpvar = strstr(base, "$(");
+ }
+ SString sret = base;
+ delete []base;
+ return sret;
+}
+
int PropSet::GetInt(const char *key, int defaultValue) {
SString val = Get(key);
if (val.length())
@@ -155,9 +198,9 @@ bool issuffix(const char *target, const char *suffix) {
}
SString PropSet::GetWild(const char *keybase, const char *filename) {
- for (int i = 0; i < used; i += 2) {
- if (isprefix(vals[i], keybase)) {
- char *orgkeyfile = vals[i] + strlen(keybase);
+ for (int i = 0; i < used; i++) {
+ if (isprefix(properties[i].key, keybase)) {
+ char *orgkeyfile = properties[i].key + strlen(keybase);
char *keyfile = NULL;
if (strstr(orgkeyfile, "$(") == orgkeyfile) {
@@ -184,12 +227,12 @@ SString PropSet::GetWild(const char *keybase, const char *filename) {
if (issuffix(filename, keyfile + 1)) {
*del = delchr;
free(keyptr);
- return vals[i + 1];
+ return properties[i].val;
}
} else if (0 == strcmp(keyfile, filename)) {
*del = delchr;
free(keyptr);
- return vals[i + 1];
+ return properties[i].val;
}
if (delchr == '\0')
break;
@@ -198,8 +241,8 @@ SString PropSet::GetWild(const char *keybase, const char *filename) {
}
free(keyptr);
- if (0 == strcmp(vals[i], keybase)) {
- return vals[i + 1];
+ if (0 == strcmp(properties[i].key, keybase)) {
+ return properties[i].val;
}
}
}
@@ -218,9 +261,7 @@ SString PropSet::GetNewExpand(const char *keybase, const char *filename) {
char *cpendvar = strchr(cpvar, ')');
if (cpendvar) {
int lenvar = cpendvar - cpvar - 2; // Subtract the $()
- char *var = new char[lenvar + 1];
- strncpy(var, cpvar + 2, lenvar);
- var[lenvar] = '\0';
+ char *var = StringDup(cpvar+2, lenvar);
SString val = GetWild(var, filename);
int newlenbase = strlen(base) + val.length() - lenvar;
char *newbase = new char[newlenbase];
@@ -240,8 +281,11 @@ SString PropSet::GetNewExpand(const char *keybase, const char *filename) {
void PropSet::Clear() {
for (int i = 0; i < used; i++) {
- delete [](vals[i]);
- vals[i] = 0;
+ properties[i].hash = 0;
+ delete []properties[i].key;
+ properties[i].key = 0;
+ delete []properties[i].val;
+ properties[i].val = 0;
}
used = 0;
}
diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx
index 7cdbc64e6..31419127f 100644
--- a/win32/ScintillaWin.cxx
+++ b/win32/ScintillaWin.cxx
@@ -345,7 +345,7 @@ LRESULT ScintillaWin::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) {
// i.e. if datazoomed out only class structures are visible, when datazooming in the control
// structures appear, then eventually the individual statements...)
if (wParam & MK_SHIFT) {
- return DefWindowProc(wMain.GetID(), iMessage, wParam, lParam);
+ return ::DefWindowProc(wMain.GetID(), iMessage, wParam, lParam);
}
// Either SCROLL or ZOOM. We handle the wheel steppings calculation
@@ -435,12 +435,12 @@ LRESULT ScintillaWin::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) {
int ret = KeyDown(wParam, Platform::IsKeyDown(VK_SHIFT),
Platform::IsKeyDown(VK_CONTROL), false);
if (!ret)
- return DefWindowProc(wMain.GetID(), iMessage, wParam, lParam);
+ return ::DefWindowProc(wMain.GetID(), iMessage, wParam, lParam);
break;
}
case WM_IME_KEYDOWN:
- return DefWindowProc(wMain.GetID(), iMessage, wParam, lParam);
+ return ::DefWindowProc(wMain.GetID(), iMessage, wParam, lParam);
case WM_KEYUP:
//Platform::DebugPrintf("S keyup %d %x %x\n",iMessage, wParam, lParam);
@@ -537,13 +537,27 @@ LRESULT ScintillaWin::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) {
return ::DefWindowProc(wMain.GetID(), iMessage, wParam, lParam);
case WM_ERASEBKGND:
+ return 1; // Avoid any background erasure as whole window painted.
+
+ // These are not handled in Scintilla and its faster to dispatch them here.
+ // Also moves time out to here so profile doesn't count lots of empty message calls.
+ case WM_MOVE:
+ case WM_MOUSEACTIVATE:
case WM_NCHITTEST:
+ case WM_NCCALCSIZE:
case WM_NCPAINT:
+ case WM_NCMOUSEMOVE:
+ case WM_NCLBUTTONDOWN:
+ case WM_CAPTURECHANGED:
+ case WM_IME_SETCONTEXT:
+ case WM_IME_NOTIFY:
+ case WM_SYSCOMMAND:
+ case WM_WINDOWPOSCHANGING:
+ case WM_WINDOWPOSCHANGED:
return ::DefWindowProc(wMain.GetID(), iMessage, wParam, lParam);
default:
- //return ::DefWindowProc(wMain.GetID(), iMessage, wParam, lParam);
- return ScintillaBase::WndProc(iMessage, wParam, lParam);
+ return ScintillaBase::WndProc(iMessage, wParam, lParam);
}
return 0l;
}
@@ -1493,12 +1507,12 @@ LRESULT PASCAL ScintillaWin::CTWndProc(
reinterpret_cast<LONG>(pCreate->lpCreateParams));
return 0;
} else {
- return DefWindowProc(hWnd, iMessage, wParam, lParam);
+ return ::DefWindowProc(hWnd, iMessage, wParam, lParam);
}
} else {
if (iMessage == WM_DESTROY) {
SetWindowLong(hWnd, 0, 0);
- return DefWindowProc(hWnd, iMessage, wParam, lParam);
+ return ::DefWindowProc(hWnd, iMessage, wParam, lParam);
} else if (iMessage == WM_PAINT) {
PAINTSTRUCT ps;
::BeginPaint(hWnd, &ps);
@@ -1509,7 +1523,7 @@ LRESULT PASCAL ScintillaWin::CTWndProc(
::EndPaint(hWnd, &ps);
return 0;
} else {
- return DefWindowProc(hWnd, iMessage, wParam, lParam);
+ return ::DefWindowProc(hWnd, iMessage, wParam, lParam);
}
}
}
@@ -1528,14 +1542,14 @@ LRESULT PASCAL ScintillaWin::SWndProc(
SetWindowLong(hWnd, 0, reinterpret_cast<LONG>(sci));
return sci->WndProc(iMessage, wParam, lParam);
} else {
- return DefWindowProc(hWnd, iMessage, wParam, lParam);
+ return ::DefWindowProc(hWnd, iMessage, wParam, lParam);
}
} else {
if (iMessage == WM_DESTROY) {
sci->Finalise();
delete sci;
SetWindowLong(hWnd, 0, 0);
- return DefWindowProc(hWnd, iMessage, wParam, lParam);
+ return ::DefWindowProc(hWnd, iMessage, wParam, lParam);
} else {
return sci->WndProc(iMessage, wParam, lParam);
}