Update Scintilla to version 3.7.1
[TortoiseGit.git] / ext / scintilla / src / ScintillaBase.cxx
blobdf899a7a23820ff4e6b86da03a7079ac104a167d
1 // Scintilla source code edit control
2 /** @file ScintillaBase.cxx
3 ** An enhanced subclass of Editor with calltips, autocomplete and context menu.
4 **/
5 // Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
6 // The License.txt file describes the conditions under which this software may be distributed.
8 #include <stdlib.h>
9 #include <string.h>
10 #include <stdio.h>
11 #include <assert.h>
12 #include <ctype.h>
14 #include <stdexcept>
15 #include <string>
16 #include <vector>
17 #include <map>
18 #include <algorithm>
20 #include "Platform.h"
22 #include "ILexer.h"
23 #include "Scintilla.h"
25 #ifdef SCI_LEXER
26 #include "SciLexer.h"
27 #endif
29 #include "PropSetSimple.h"
31 #ifdef SCI_LEXER
32 #include "LexerModule.h"
33 #include "Catalogue.h"
34 #endif
36 #include "Position.h"
37 #include "SplitVector.h"
38 #include "Partitioning.h"
39 #include "RunStyles.h"
40 #include "ContractionState.h"
41 #include "CellBuffer.h"
42 #include "CallTip.h"
43 #include "KeyMap.h"
44 #include "Indicator.h"
45 #include "XPM.h"
46 #include "LineMarker.h"
47 #include "Style.h"
48 #include "ViewStyle.h"
49 #include "CharClassify.h"
50 #include "Decoration.h"
51 #include "CaseFolder.h"
52 #include "Document.h"
53 #include "Selection.h"
54 #include "PositionCache.h"
55 #include "EditModel.h"
56 #include "MarginView.h"
57 #include "EditView.h"
58 #include "Editor.h"
59 #include "AutoComplete.h"
60 #include "ScintillaBase.h"
62 #ifdef SCI_NAMESPACE
63 using namespace Scintilla;
64 #endif
66 ScintillaBase::ScintillaBase() {
67 displayPopupMenu = SC_POPUP_ALL;
68 listType = 0;
69 maxListWidth = 0;
70 multiAutoCMode = SC_MULTIAUTOC_ONCE;
73 ScintillaBase::~ScintillaBase() {
76 void ScintillaBase::Finalise() {
77 Editor::Finalise();
78 popup.Destroy();
81 void ScintillaBase::AddCharUTF(const char *s, unsigned int len, bool treatAsDBCS) {
82 bool isFillUp = ac.Active() && ac.IsFillUpChar(*s);
83 if (!isFillUp) {
84 Editor::AddCharUTF(s, len, treatAsDBCS);
86 if (ac.Active()) {
87 AutoCompleteCharacterAdded(s[0]);
88 // For fill ups add the character after the autocompletion has
89 // triggered so containers see the key so can display a calltip.
90 if (isFillUp) {
91 Editor::AddCharUTF(s, len, treatAsDBCS);
96 void ScintillaBase::Command(int cmdId) {
98 switch (cmdId) {
100 case idAutoComplete: // Nothing to do
102 break;
104 case idCallTip: // Nothing to do
106 break;
108 case idcmdUndo:
109 WndProc(SCI_UNDO, 0, 0);
110 break;
112 case idcmdRedo:
113 WndProc(SCI_REDO, 0, 0);
114 break;
116 case idcmdCut:
117 WndProc(SCI_CUT, 0, 0);
118 break;
120 case idcmdCopy:
121 WndProc(SCI_COPY, 0, 0);
122 break;
124 case idcmdPaste:
125 WndProc(SCI_PASTE, 0, 0);
126 break;
128 case idcmdDelete:
129 WndProc(SCI_CLEAR, 0, 0);
130 break;
132 case idcmdSelectAll:
133 WndProc(SCI_SELECTALL, 0, 0);
134 break;
138 int ScintillaBase::KeyCommand(unsigned int iMessage) {
139 // Most key commands cancel autocompletion mode
140 if (ac.Active()) {
141 switch (iMessage) {
142 // Except for these
143 case SCI_LINEDOWN:
144 AutoCompleteMove(1);
145 return 0;
146 case SCI_LINEUP:
147 AutoCompleteMove(-1);
148 return 0;
149 case SCI_PAGEDOWN:
150 AutoCompleteMove(ac.lb->GetVisibleRows());
151 return 0;
152 case SCI_PAGEUP:
153 AutoCompleteMove(-ac.lb->GetVisibleRows());
154 return 0;
155 case SCI_VCHOME:
156 AutoCompleteMove(-5000);
157 return 0;
158 case SCI_LINEEND:
159 AutoCompleteMove(5000);
160 return 0;
161 case SCI_DELETEBACK:
162 DelCharBack(true);
163 AutoCompleteCharacterDeleted();
164 EnsureCaretVisible();
165 return 0;
166 case SCI_DELETEBACKNOTLINE:
167 DelCharBack(false);
168 AutoCompleteCharacterDeleted();
169 EnsureCaretVisible();
170 return 0;
171 case SCI_TAB:
172 AutoCompleteCompleted(0, SC_AC_TAB);
173 return 0;
174 case SCI_NEWLINE:
175 AutoCompleteCompleted(0, SC_AC_NEWLINE);
176 return 0;
178 default:
179 AutoCompleteCancel();
183 if (ct.inCallTipMode) {
184 if (
185 (iMessage != SCI_CHARLEFT) &&
186 (iMessage != SCI_CHARLEFTEXTEND) &&
187 (iMessage != SCI_CHARRIGHT) &&
188 (iMessage != SCI_CHARRIGHTEXTEND) &&
189 (iMessage != SCI_EDITTOGGLEOVERTYPE) &&
190 (iMessage != SCI_DELETEBACK) &&
191 (iMessage != SCI_DELETEBACKNOTLINE)
193 ct.CallTipCancel();
195 if ((iMessage == SCI_DELETEBACK) || (iMessage == SCI_DELETEBACKNOTLINE)) {
196 if (sel.MainCaret() <= ct.posStartCallTip) {
197 ct.CallTipCancel();
201 return Editor::KeyCommand(iMessage);
204 void ScintillaBase::AutoCompleteDoubleClick(void *p) {
205 ScintillaBase *sci = reinterpret_cast<ScintillaBase *>(p);
206 sci->AutoCompleteCompleted(0, SC_AC_DOUBLECLICK);
209 void ScintillaBase::AutoCompleteInsert(Position startPos, int removeLen, const char *text, int textLen) {
210 UndoGroup ug(pdoc);
211 if (multiAutoCMode == SC_MULTIAUTOC_ONCE) {
212 pdoc->DeleteChars(startPos, removeLen);
213 const int lengthInserted = pdoc->InsertString(startPos, text, textLen);
214 SetEmptySelection(startPos + lengthInserted);
215 } else {
216 // SC_MULTIAUTOC_EACH
217 for (size_t r=0; r<sel.Count(); r++) {
218 if (!RangeContainsProtected(sel.Range(r).Start().Position(),
219 sel.Range(r).End().Position())) {
220 int positionInsert = sel.Range(r).Start().Position();
221 positionInsert = RealizeVirtualSpace(positionInsert, sel.Range(r).caret.VirtualSpace());
222 if (positionInsert - removeLen >= 0) {
223 positionInsert -= removeLen;
224 pdoc->DeleteChars(positionInsert, removeLen);
226 const int lengthInserted = pdoc->InsertString(positionInsert, text, textLen);
227 if (lengthInserted > 0) {
228 sel.Range(r).caret.SetPosition(positionInsert + lengthInserted);
229 sel.Range(r).anchor.SetPosition(positionInsert + lengthInserted);
231 sel.Range(r).ClearVirtualSpace();
237 void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) {
238 //Platform::DebugPrintf("AutoComplete %s\n", list);
239 ct.CallTipCancel();
241 if (ac.chooseSingle && (listType == 0)) {
242 if (list && !strchr(list, ac.GetSeparator())) {
243 const char *typeSep = strchr(list, ac.GetTypesep());
244 int lenInsert = typeSep ?
245 static_cast<int>(typeSep-list) : static_cast<int>(strlen(list));
246 if (ac.ignoreCase) {
247 // May need to convert the case before invocation, so remove lenEntered characters
248 AutoCompleteInsert(sel.MainCaret() - lenEntered, lenEntered, list, lenInsert);
249 } else {
250 AutoCompleteInsert(sel.MainCaret(), 0, list + lenEntered, lenInsert - lenEntered);
252 ac.Cancel();
253 return;
256 ac.Start(wMain, idAutoComplete, sel.MainCaret(), PointMainCaret(),
257 lenEntered, vs.lineHeight, IsUnicodeMode(), technology);
259 PRectangle rcClient = GetClientRectangle();
260 Point pt = LocationFromPosition(sel.MainCaret() - lenEntered);
261 PRectangle rcPopupBounds = wMain.GetMonitorRect(pt);
262 if (rcPopupBounds.Height() == 0)
263 rcPopupBounds = rcClient;
265 int heightLB = ac.heightLBDefault;
266 int widthLB = ac.widthLBDefault;
267 if (pt.x >= rcClient.right - widthLB) {
268 HorizontalScrollTo(static_cast<int>(xOffset + pt.x - rcClient.right + widthLB));
269 Redraw();
270 pt = PointMainCaret();
272 if (wMargin.GetID()) {
273 Point ptOrigin = GetVisibleOriginInMain();
274 pt.x += ptOrigin.x;
275 pt.y += ptOrigin.y;
277 PRectangle rcac;
278 rcac.left = pt.x - ac.lb->CaretFromEdge();
279 if (pt.y >= rcPopupBounds.bottom - heightLB && // Won't fit below.
280 pt.y >= (rcPopupBounds.bottom + rcPopupBounds.top) / 2) { // and there is more room above.
281 rcac.top = pt.y - heightLB;
282 if (rcac.top < rcPopupBounds.top) {
283 heightLB -= static_cast<int>(rcPopupBounds.top - rcac.top);
284 rcac.top = rcPopupBounds.top;
286 } else {
287 rcac.top = pt.y + vs.lineHeight;
289 rcac.right = rcac.left + widthLB;
290 rcac.bottom = static_cast<XYPOSITION>(Platform::Minimum(static_cast<int>(rcac.top) + heightLB, static_cast<int>(rcPopupBounds.bottom)));
291 ac.lb->SetPositionRelative(rcac, wMain);
292 ac.lb->SetFont(vs.styles[STYLE_DEFAULT].font);
293 unsigned int aveCharWidth = static_cast<unsigned int>(vs.styles[STYLE_DEFAULT].aveCharWidth);
294 ac.lb->SetAverageCharWidth(aveCharWidth);
295 ac.lb->SetDoubleClickAction(AutoCompleteDoubleClick, this);
297 ac.SetList(list ? list : "");
299 // Fiddle the position of the list so it is right next to the target and wide enough for all its strings
300 PRectangle rcList = ac.lb->GetDesiredRect();
301 int heightAlloced = static_cast<int>(rcList.bottom - rcList.top);
302 widthLB = Platform::Maximum(widthLB, static_cast<int>(rcList.right - rcList.left));
303 if (maxListWidth != 0)
304 widthLB = Platform::Minimum(widthLB, aveCharWidth*maxListWidth);
305 // Make an allowance for large strings in list
306 rcList.left = pt.x - ac.lb->CaretFromEdge();
307 rcList.right = rcList.left + widthLB;
308 if (((pt.y + vs.lineHeight) >= (rcPopupBounds.bottom - heightAlloced)) && // Won't fit below.
309 ((pt.y + vs.lineHeight / 2) >= (rcPopupBounds.bottom + rcPopupBounds.top) / 2)) { // and there is more room above.
310 rcList.top = pt.y - heightAlloced;
311 } else {
312 rcList.top = pt.y + vs.lineHeight;
314 rcList.bottom = rcList.top + heightAlloced;
315 ac.lb->SetPositionRelative(rcList, wMain);
316 ac.Show(true);
317 if (lenEntered != 0) {
318 AutoCompleteMoveToCurrentWord();
322 void ScintillaBase::AutoCompleteCancel() {
323 if (ac.Active()) {
324 SCNotification scn = {};
325 scn.nmhdr.code = SCN_AUTOCCANCELLED;
326 scn.wParam = 0;
327 scn.listType = 0;
328 NotifyParent(scn);
330 ac.Cancel();
333 void ScintillaBase::AutoCompleteMove(int delta) {
334 ac.Move(delta);
337 void ScintillaBase::AutoCompleteMoveToCurrentWord() {
338 std::string wordCurrent = RangeText(ac.posStart - ac.startLen, sel.MainCaret());
339 ac.Select(wordCurrent.c_str());
342 void ScintillaBase::AutoCompleteCharacterAdded(char ch) {
343 if (ac.IsFillUpChar(ch)) {
344 AutoCompleteCompleted(ch, SC_AC_FILLUP);
345 } else if (ac.IsStopChar(ch)) {
346 AutoCompleteCancel();
347 } else {
348 AutoCompleteMoveToCurrentWord();
352 void ScintillaBase::AutoCompleteCharacterDeleted() {
353 if (sel.MainCaret() < ac.posStart - ac.startLen) {
354 AutoCompleteCancel();
355 } else if (ac.cancelAtStartPos && (sel.MainCaret() <= ac.posStart)) {
356 AutoCompleteCancel();
357 } else {
358 AutoCompleteMoveToCurrentWord();
360 SCNotification scn = {};
361 scn.nmhdr.code = SCN_AUTOCCHARDELETED;
362 scn.wParam = 0;
363 scn.listType = 0;
364 NotifyParent(scn);
367 void ScintillaBase::AutoCompleteCompleted(char ch, unsigned int completionMethod) {
368 int item = ac.GetSelection();
369 if (item == -1) {
370 AutoCompleteCancel();
371 return;
373 const std::string selected = ac.GetValue(item);
375 ac.Show(false);
377 SCNotification scn = {};
378 scn.nmhdr.code = listType > 0 ? SCN_USERLISTSELECTION : SCN_AUTOCSELECTION;
379 scn.message = 0;
380 scn.ch = ch;
381 scn.listCompletionMethod = completionMethod;
382 scn.wParam = listType;
383 scn.listType = listType;
384 Position firstPos = ac.posStart - ac.startLen;
385 scn.position = firstPos;
386 scn.lParam = firstPos;
387 scn.text = selected.c_str();
388 NotifyParent(scn);
390 if (!ac.Active())
391 return;
392 ac.Cancel();
394 if (listType > 0)
395 return;
397 Position endPos = sel.MainCaret();
398 if (ac.dropRestOfWord)
399 endPos = pdoc->ExtendWordSelect(endPos, 1, true);
400 if (endPos < firstPos)
401 return;
402 AutoCompleteInsert(firstPos, endPos - firstPos, selected.c_str(), static_cast<int>(selected.length()));
403 SetLastXChosen();
405 scn.nmhdr.code = SCN_AUTOCCOMPLETED;
406 NotifyParent(scn);
410 int ScintillaBase::AutoCompleteGetCurrent() const {
411 if (!ac.Active())
412 return -1;
413 return ac.GetSelection();
416 int ScintillaBase::AutoCompleteGetCurrentText(char *buffer) const {
417 if (ac.Active()) {
418 int item = ac.GetSelection();
419 if (item != -1) {
420 const std::string selected = ac.GetValue(item);
421 if (buffer != NULL)
422 memcpy(buffer, selected.c_str(), selected.length()+1);
423 return static_cast<int>(selected.length());
426 if (buffer != NULL)
427 *buffer = '\0';
428 return 0;
431 void ScintillaBase::CallTipShow(Point pt, const char *defn) {
432 ac.Cancel();
433 // If container knows about STYLE_CALLTIP then use it in place of the
434 // STYLE_DEFAULT for the face name, size and character set. Also use it
435 // for the foreground and background colour.
436 int ctStyle = ct.UseStyleCallTip() ? STYLE_CALLTIP : STYLE_DEFAULT;
437 if (ct.UseStyleCallTip()) {
438 ct.SetForeBack(vs.styles[STYLE_CALLTIP].fore, vs.styles[STYLE_CALLTIP].back);
440 if (wMargin.GetID()) {
441 Point ptOrigin = GetVisibleOriginInMain();
442 pt.x += ptOrigin.x;
443 pt.y += ptOrigin.y;
445 PRectangle rc = ct.CallTipStart(sel.MainCaret(), pt,
446 vs.lineHeight,
447 defn,
448 vs.styles[ctStyle].fontName,
449 vs.styles[ctStyle].sizeZoomed,
450 CodePage(),
451 vs.styles[ctStyle].characterSet,
452 vs.technology,
453 wMain);
454 // If the call-tip window would be out of the client
455 // space
456 PRectangle rcClient = GetClientRectangle();
457 int offset = vs.lineHeight + static_cast<int>(rc.Height());
458 // adjust so it displays above the text.
459 if (rc.bottom > rcClient.bottom && rc.Height() < rcClient.Height()) {
460 rc.top -= offset;
461 rc.bottom -= offset;
463 // adjust so it displays below the text.
464 if (rc.top < rcClient.top && rc.Height() < rcClient.Height()) {
465 rc.top += offset;
466 rc.bottom += offset;
468 // Now display the window.
469 CreateCallTipWindow(rc);
470 ct.wCallTip.SetPositionRelative(rc, wMain);
471 ct.wCallTip.Show();
474 void ScintillaBase::CallTipClick() {
475 SCNotification scn = {};
476 scn.nmhdr.code = SCN_CALLTIPCLICK;
477 scn.position = ct.clickPlace;
478 NotifyParent(scn);
481 bool ScintillaBase::ShouldDisplayPopup(Point ptInWindowCoordinates) const {
482 return (displayPopupMenu == SC_POPUP_ALL ||
483 (displayPopupMenu == SC_POPUP_TEXT && !PointInSelMargin(ptInWindowCoordinates)));
486 void ScintillaBase::ContextMenu(Point pt) {
487 if (displayPopupMenu) {
488 bool writable = !WndProc(SCI_GETREADONLY, 0, 0);
489 popup.CreatePopUp();
490 AddToPopUp("Undo", idcmdUndo, writable && pdoc->CanUndo());
491 AddToPopUp("Redo", idcmdRedo, writable && pdoc->CanRedo());
492 AddToPopUp("");
493 AddToPopUp("Cut", idcmdCut, writable && !sel.Empty());
494 AddToPopUp("Copy", idcmdCopy, !sel.Empty());
495 AddToPopUp("Paste", idcmdPaste, writable && WndProc(SCI_CANPASTE, 0, 0));
496 AddToPopUp("Delete", idcmdDelete, writable && !sel.Empty());
497 AddToPopUp("");
498 AddToPopUp("Select All", idcmdSelectAll);
499 popup.Show(pt, wMain);
503 void ScintillaBase::CancelModes() {
504 AutoCompleteCancel();
505 ct.CallTipCancel();
506 Editor::CancelModes();
509 void ScintillaBase::ButtonDownWithModifiers(Point pt, unsigned int curTime, int modifiers) {
510 CancelModes();
511 Editor::ButtonDownWithModifiers(pt, curTime, modifiers);
514 void ScintillaBase::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt) {
515 ButtonDownWithModifiers(pt, curTime, ModifierFlags(shift, ctrl, alt));
518 void ScintillaBase::RightButtonDownWithModifiers(Point pt, unsigned int curTime, int modifiers) {
519 CancelModes();
520 Editor::RightButtonDownWithModifiers(pt, curTime, modifiers);
523 #ifdef SCI_LEXER
525 #ifdef SCI_NAMESPACE
526 namespace Scintilla {
527 #endif
529 class LexState : public LexInterface {
530 const LexerModule *lexCurrent;
531 void SetLexerModule(const LexerModule *lex);
532 PropSetSimple props;
533 int interfaceVersion;
534 public:
535 int lexLanguage;
537 explicit LexState(Document *pdoc_);
538 virtual ~LexState();
539 void SetLexer(uptr_t wParam);
540 void SetLexerLanguage(const char *languageName);
541 const char *DescribeWordListSets();
542 void SetWordList(int n, const char *wl);
543 const char *GetName() const;
544 void *PrivateCall(int operation, void *pointer);
545 const char *PropertyNames();
546 int PropertyType(const char *name);
547 const char *DescribeProperty(const char *name);
548 void PropSet(const char *key, const char *val);
549 const char *PropGet(const char *key) const;
550 int PropGetInt(const char *key, int defaultValue=0) const;
551 int PropGetExpanded(const char *key, char *result) const;
553 int LineEndTypesSupported();
554 int AllocateSubStyles(int styleBase, int numberStyles);
555 int SubStylesStart(int styleBase);
556 int SubStylesLength(int styleBase);
557 int StyleFromSubStyle(int subStyle);
558 int PrimaryStyleFromStyle(int style);
559 void FreeSubStyles();
560 void SetIdentifiers(int style, const char *identifiers);
561 int DistanceToSecondaryStyles();
562 const char *GetSubStyleBases();
565 #ifdef SCI_NAMESPACE
567 #endif
569 LexState::LexState(Document *pdoc_) : LexInterface(pdoc_) {
570 lexCurrent = 0;
571 performingStyle = false;
572 interfaceVersion = lvOriginal;
573 lexLanguage = SCLEX_CONTAINER;
576 LexState::~LexState() {
577 if (instance) {
578 instance->Release();
579 instance = 0;
583 LexState *ScintillaBase::DocumentLexState() {
584 if (!pdoc->pli) {
585 pdoc->pli = new LexState(pdoc);
587 return static_cast<LexState *>(pdoc->pli);
590 void LexState::SetLexerModule(const LexerModule *lex) {
591 if (lex != lexCurrent) {
592 if (instance) {
593 instance->Release();
594 instance = 0;
596 interfaceVersion = lvOriginal;
597 lexCurrent = lex;
598 if (lexCurrent) {
599 instance = lexCurrent->Create();
600 interfaceVersion = instance->Version();
602 pdoc->LexerChanged();
606 void LexState::SetLexer(uptr_t wParam) {
607 lexLanguage = static_cast<int>(wParam);
608 if (lexLanguage == SCLEX_CONTAINER) {
609 SetLexerModule(0);
610 } else {
611 const LexerModule *lex = Catalogue::Find(lexLanguage);
612 if (!lex)
613 lex = Catalogue::Find(SCLEX_NULL);
614 SetLexerModule(lex);
618 void LexState::SetLexerLanguage(const char *languageName) {
619 const LexerModule *lex = Catalogue::Find(languageName);
620 if (!lex)
621 lex = Catalogue::Find(SCLEX_NULL);
622 if (lex)
623 lexLanguage = lex->GetLanguage();
624 SetLexerModule(lex);
627 const char *LexState::DescribeWordListSets() {
628 if (instance) {
629 return instance->DescribeWordListSets();
630 } else {
631 return 0;
635 void LexState::SetWordList(int n, const char *wl) {
636 if (instance) {
637 int firstModification = instance->WordListSet(n, wl);
638 if (firstModification >= 0) {
639 pdoc->ModifiedAt(firstModification);
644 const char *LexState::GetName() const {
645 return lexCurrent ? lexCurrent->languageName : "";
648 void *LexState::PrivateCall(int operation, void *pointer) {
649 if (pdoc && instance) {
650 return instance->PrivateCall(operation, pointer);
651 } else {
652 return 0;
656 const char *LexState::PropertyNames() {
657 if (instance) {
658 return instance->PropertyNames();
659 } else {
660 return 0;
664 int LexState::PropertyType(const char *name) {
665 if (instance) {
666 return instance->PropertyType(name);
667 } else {
668 return SC_TYPE_BOOLEAN;
672 const char *LexState::DescribeProperty(const char *name) {
673 if (instance) {
674 return instance->DescribeProperty(name);
675 } else {
676 return 0;
680 void LexState::PropSet(const char *key, const char *val) {
681 props.Set(key, val);
682 if (instance) {
683 int firstModification = instance->PropertySet(key, val);
684 if (firstModification >= 0) {
685 pdoc->ModifiedAt(firstModification);
690 const char *LexState::PropGet(const char *key) const {
691 return props.Get(key);
694 int LexState::PropGetInt(const char *key, int defaultValue) const {
695 return props.GetInt(key, defaultValue);
698 int LexState::PropGetExpanded(const char *key, char *result) const {
699 return props.GetExpanded(key, result);
702 int LexState::LineEndTypesSupported() {
703 if (instance && (interfaceVersion >= lvSubStyles)) {
704 return static_cast<ILexerWithSubStyles *>(instance)->LineEndTypesSupported();
706 return 0;
709 int LexState::AllocateSubStyles(int styleBase, int numberStyles) {
710 if (instance && (interfaceVersion >= lvSubStyles)) {
711 return static_cast<ILexerWithSubStyles *>(instance)->AllocateSubStyles(styleBase, numberStyles);
713 return -1;
716 int LexState::SubStylesStart(int styleBase) {
717 if (instance && (interfaceVersion >= lvSubStyles)) {
718 return static_cast<ILexerWithSubStyles *>(instance)->SubStylesStart(styleBase);
720 return -1;
723 int LexState::SubStylesLength(int styleBase) {
724 if (instance && (interfaceVersion >= lvSubStyles)) {
725 return static_cast<ILexerWithSubStyles *>(instance)->SubStylesLength(styleBase);
727 return 0;
730 int LexState::StyleFromSubStyle(int subStyle) {
731 if (instance && (interfaceVersion >= lvSubStyles)) {
732 return static_cast<ILexerWithSubStyles *>(instance)->StyleFromSubStyle(subStyle);
734 return 0;
737 int LexState::PrimaryStyleFromStyle(int style) {
738 if (instance && (interfaceVersion >= lvSubStyles)) {
739 return static_cast<ILexerWithSubStyles *>(instance)->PrimaryStyleFromStyle(style);
741 return 0;
744 void LexState::FreeSubStyles() {
745 if (instance && (interfaceVersion >= lvSubStyles)) {
746 static_cast<ILexerWithSubStyles *>(instance)->FreeSubStyles();
750 void LexState::SetIdentifiers(int style, const char *identifiers) {
751 if (instance && (interfaceVersion >= lvSubStyles)) {
752 static_cast<ILexerWithSubStyles *>(instance)->SetIdentifiers(style, identifiers);
753 pdoc->ModifiedAt(0);
757 int LexState::DistanceToSecondaryStyles() {
758 if (instance && (interfaceVersion >= lvSubStyles)) {
759 return static_cast<ILexerWithSubStyles *>(instance)->DistanceToSecondaryStyles();
761 return 0;
764 const char *LexState::GetSubStyleBases() {
765 if (instance && (interfaceVersion >= lvSubStyles)) {
766 return static_cast<ILexerWithSubStyles *>(instance)->GetSubStyleBases();
768 return "";
771 #endif
773 void ScintillaBase::NotifyStyleToNeeded(int endStyleNeeded) {
774 #ifdef SCI_LEXER
775 if (DocumentLexState()->lexLanguage != SCLEX_CONTAINER) {
776 int lineEndStyled = pdoc->LineFromPosition(pdoc->GetEndStyled());
777 int endStyled = pdoc->LineStart(lineEndStyled);
778 DocumentLexState()->Colourise(endStyled, endStyleNeeded);
779 return;
781 #endif
782 Editor::NotifyStyleToNeeded(endStyleNeeded);
785 void ScintillaBase::NotifyLexerChanged(Document *, void *) {
786 #ifdef SCI_LEXER
787 vs.EnsureStyle(0xff);
788 #endif
791 sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
792 switch (iMessage) {
793 case SCI_AUTOCSHOW:
794 listType = 0;
795 AutoCompleteStart(static_cast<int>(wParam), reinterpret_cast<const char *>(lParam));
796 break;
798 case SCI_AUTOCCANCEL:
799 ac.Cancel();
800 break;
802 case SCI_AUTOCACTIVE:
803 return ac.Active();
805 case SCI_AUTOCPOSSTART:
806 return ac.posStart;
808 case SCI_AUTOCCOMPLETE:
809 AutoCompleteCompleted(0, SC_AC_COMMAND);
810 break;
812 case SCI_AUTOCSETSEPARATOR:
813 ac.SetSeparator(static_cast<char>(wParam));
814 break;
816 case SCI_AUTOCGETSEPARATOR:
817 return ac.GetSeparator();
819 case SCI_AUTOCSTOPS:
820 ac.SetStopChars(reinterpret_cast<char *>(lParam));
821 break;
823 case SCI_AUTOCSELECT:
824 ac.Select(reinterpret_cast<char *>(lParam));
825 break;
827 case SCI_AUTOCGETCURRENT:
828 return AutoCompleteGetCurrent();
830 case SCI_AUTOCGETCURRENTTEXT:
831 return AutoCompleteGetCurrentText(reinterpret_cast<char *>(lParam));
833 case SCI_AUTOCSETCANCELATSTART:
834 ac.cancelAtStartPos = wParam != 0;
835 break;
837 case SCI_AUTOCGETCANCELATSTART:
838 return ac.cancelAtStartPos;
840 case SCI_AUTOCSETFILLUPS:
841 ac.SetFillUpChars(reinterpret_cast<char *>(lParam));
842 break;
844 case SCI_AUTOCSETCHOOSESINGLE:
845 ac.chooseSingle = wParam != 0;
846 break;
848 case SCI_AUTOCGETCHOOSESINGLE:
849 return ac.chooseSingle;
851 case SCI_AUTOCSETIGNORECASE:
852 ac.ignoreCase = wParam != 0;
853 break;
855 case SCI_AUTOCGETIGNORECASE:
856 return ac.ignoreCase;
858 case SCI_AUTOCSETCASEINSENSITIVEBEHAVIOUR:
859 ac.ignoreCaseBehaviour = static_cast<unsigned int>(wParam);
860 break;
862 case SCI_AUTOCGETCASEINSENSITIVEBEHAVIOUR:
863 return ac.ignoreCaseBehaviour;
865 case SCI_AUTOCSETMULTI:
866 multiAutoCMode = static_cast<int>(wParam);
867 break;
869 case SCI_AUTOCGETMULTI:
870 return multiAutoCMode;
872 case SCI_AUTOCSETORDER:
873 ac.autoSort = static_cast<int>(wParam);
874 break;
876 case SCI_AUTOCGETORDER:
877 return ac.autoSort;
879 case SCI_USERLISTSHOW:
880 listType = static_cast<int>(wParam);
881 AutoCompleteStart(0, reinterpret_cast<const char *>(lParam));
882 break;
884 case SCI_AUTOCSETAUTOHIDE:
885 ac.autoHide = wParam != 0;
886 break;
888 case SCI_AUTOCGETAUTOHIDE:
889 return ac.autoHide;
891 case SCI_AUTOCSETDROPRESTOFWORD:
892 ac.dropRestOfWord = wParam != 0;
893 break;
895 case SCI_AUTOCGETDROPRESTOFWORD:
896 return ac.dropRestOfWord;
898 case SCI_AUTOCSETMAXHEIGHT:
899 ac.lb->SetVisibleRows(static_cast<int>(wParam));
900 break;
902 case SCI_AUTOCGETMAXHEIGHT:
903 return ac.lb->GetVisibleRows();
905 case SCI_AUTOCSETMAXWIDTH:
906 maxListWidth = static_cast<int>(wParam);
907 break;
909 case SCI_AUTOCGETMAXWIDTH:
910 return maxListWidth;
912 case SCI_REGISTERIMAGE:
913 ac.lb->RegisterImage(static_cast<int>(wParam), reinterpret_cast<const char *>(lParam));
914 break;
916 case SCI_REGISTERRGBAIMAGE:
917 ac.lb->RegisterRGBAImage(static_cast<int>(wParam), static_cast<int>(sizeRGBAImage.x), static_cast<int>(sizeRGBAImage.y),
918 reinterpret_cast<unsigned char *>(lParam));
919 break;
921 case SCI_CLEARREGISTEREDIMAGES:
922 ac.lb->ClearRegisteredImages();
923 break;
925 case SCI_AUTOCSETTYPESEPARATOR:
926 ac.SetTypesep(static_cast<char>(wParam));
927 break;
929 case SCI_AUTOCGETTYPESEPARATOR:
930 return ac.GetTypesep();
932 case SCI_CALLTIPSHOW:
933 CallTipShow(LocationFromPosition(static_cast<int>(wParam)),
934 reinterpret_cast<const char *>(lParam));
935 break;
937 case SCI_CALLTIPCANCEL:
938 ct.CallTipCancel();
939 break;
941 case SCI_CALLTIPACTIVE:
942 return ct.inCallTipMode;
944 case SCI_CALLTIPPOSSTART:
945 return ct.posStartCallTip;
947 case SCI_CALLTIPSETPOSSTART:
948 ct.posStartCallTip = static_cast<int>(wParam);
949 break;
951 case SCI_CALLTIPSETHLT:
952 ct.SetHighlight(static_cast<int>(wParam), static_cast<int>(lParam));
953 break;
955 case SCI_CALLTIPSETBACK:
956 ct.colourBG = ColourDesired(static_cast<long>(wParam));
957 vs.styles[STYLE_CALLTIP].back = ct.colourBG;
958 InvalidateStyleRedraw();
959 break;
961 case SCI_CALLTIPSETFORE:
962 ct.colourUnSel = ColourDesired(static_cast<long>(wParam));
963 vs.styles[STYLE_CALLTIP].fore = ct.colourUnSel;
964 InvalidateStyleRedraw();
965 break;
967 case SCI_CALLTIPSETFOREHLT:
968 ct.colourSel = ColourDesired(static_cast<long>(wParam));
969 InvalidateStyleRedraw();
970 break;
972 case SCI_CALLTIPUSESTYLE:
973 ct.SetTabSize(static_cast<int>(wParam));
974 InvalidateStyleRedraw();
975 break;
977 case SCI_CALLTIPSETPOSITION:
978 ct.SetPosition(wParam != 0);
979 InvalidateStyleRedraw();
980 break;
982 case SCI_USEPOPUP:
983 displayPopupMenu = static_cast<int>(wParam);
984 break;
986 #ifdef SCI_LEXER
987 case SCI_SETLEXER:
988 DocumentLexState()->SetLexer(static_cast<int>(wParam));
989 break;
991 case SCI_GETLEXER:
992 return DocumentLexState()->lexLanguage;
994 case SCI_COLOURISE:
995 if (DocumentLexState()->lexLanguage == SCLEX_CONTAINER) {
996 pdoc->ModifiedAt(static_cast<int>(wParam));
997 NotifyStyleToNeeded((lParam == -1) ? pdoc->Length() : static_cast<int>(lParam));
998 } else {
999 DocumentLexState()->Colourise(static_cast<int>(wParam), static_cast<int>(lParam));
1001 Redraw();
1002 break;
1004 case SCI_SETPROPERTY:
1005 DocumentLexState()->PropSet(reinterpret_cast<const char *>(wParam),
1006 reinterpret_cast<const char *>(lParam));
1007 break;
1009 case SCI_GETPROPERTY:
1010 return StringResult(lParam, DocumentLexState()->PropGet(reinterpret_cast<const char *>(wParam)));
1012 case SCI_GETPROPERTYEXPANDED:
1013 return DocumentLexState()->PropGetExpanded(reinterpret_cast<const char *>(wParam),
1014 reinterpret_cast<char *>(lParam));
1016 case SCI_GETPROPERTYINT:
1017 return DocumentLexState()->PropGetInt(reinterpret_cast<const char *>(wParam), static_cast<int>(lParam));
1019 case SCI_SETKEYWORDS:
1020 DocumentLexState()->SetWordList(static_cast<int>(wParam), reinterpret_cast<const char *>(lParam));
1021 break;
1023 case SCI_SETLEXERLANGUAGE:
1024 DocumentLexState()->SetLexerLanguage(reinterpret_cast<const char *>(lParam));
1025 break;
1027 case SCI_GETLEXERLANGUAGE:
1028 return StringResult(lParam, DocumentLexState()->GetName());
1030 case SCI_PRIVATELEXERCALL:
1031 return reinterpret_cast<sptr_t>(
1032 DocumentLexState()->PrivateCall(static_cast<int>(wParam), reinterpret_cast<void *>(lParam)));
1034 case SCI_GETSTYLEBITSNEEDED:
1035 return 8;
1037 case SCI_PROPERTYNAMES:
1038 return StringResult(lParam, DocumentLexState()->PropertyNames());
1040 case SCI_PROPERTYTYPE:
1041 return DocumentLexState()->PropertyType(reinterpret_cast<const char *>(wParam));
1043 case SCI_DESCRIBEPROPERTY:
1044 return StringResult(lParam,
1045 DocumentLexState()->DescribeProperty(reinterpret_cast<const char *>(wParam)));
1047 case SCI_DESCRIBEKEYWORDSETS:
1048 return StringResult(lParam, DocumentLexState()->DescribeWordListSets());
1050 case SCI_GETLINEENDTYPESSUPPORTED:
1051 return DocumentLexState()->LineEndTypesSupported();
1053 case SCI_ALLOCATESUBSTYLES:
1054 return DocumentLexState()->AllocateSubStyles(static_cast<int>(wParam), static_cast<int>(lParam));
1056 case SCI_GETSUBSTYLESSTART:
1057 return DocumentLexState()->SubStylesStart(static_cast<int>(wParam));
1059 case SCI_GETSUBSTYLESLENGTH:
1060 return DocumentLexState()->SubStylesLength(static_cast<int>(wParam));
1062 case SCI_GETSTYLEFROMSUBSTYLE:
1063 return DocumentLexState()->StyleFromSubStyle(static_cast<int>(wParam));
1065 case SCI_GETPRIMARYSTYLEFROMSTYLE:
1066 return DocumentLexState()->PrimaryStyleFromStyle(static_cast<int>(wParam));
1068 case SCI_FREESUBSTYLES:
1069 DocumentLexState()->FreeSubStyles();
1070 break;
1072 case SCI_SETIDENTIFIERS:
1073 DocumentLexState()->SetIdentifiers(static_cast<int>(wParam),
1074 reinterpret_cast<const char *>(lParam));
1075 break;
1077 case SCI_DISTANCETOSECONDARYSTYLES:
1078 return DocumentLexState()->DistanceToSecondaryStyles();
1080 case SCI_GETSUBSTYLEBASES:
1081 return StringResult(lParam, DocumentLexState()->GetSubStyleBases());
1082 #endif
1084 default:
1085 return Editor::WndProc(iMessage, wParam, lParam);
1087 return 0l;