Update Scintilla to version 3.4.4
[TortoiseGit.git] / ext / scintilla / src / ScintillaBase.cxx
blob713cfd291e31683b891461f1d60093c9f17b8063
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 <string>
15 #include <vector>
16 #include <map>
17 #include <algorithm>
19 #include "Platform.h"
21 #include "ILexer.h"
22 #include "Scintilla.h"
24 #ifdef SCI_LEXER
25 #include "SciLexer.h"
26 #endif
28 #include "PropSetSimple.h"
30 #ifdef SCI_LEXER
31 #include "LexerModule.h"
32 #include "Catalogue.h"
33 #endif
35 #include "SplitVector.h"
36 #include "Partitioning.h"
37 #include "RunStyles.h"
38 #include "ContractionState.h"
39 #include "CellBuffer.h"
40 #include "CallTip.h"
41 #include "KeyMap.h"
42 #include "Indicator.h"
43 #include "XPM.h"
44 #include "LineMarker.h"
45 #include "Style.h"
46 #include "ViewStyle.h"
47 #include "CharClassify.h"
48 #include "Decoration.h"
49 #include "CaseFolder.h"
50 #include "Document.h"
51 #include "Selection.h"
52 #include "PositionCache.h"
53 #include "Editor.h"
54 #include "AutoComplete.h"
55 #include "ScintillaBase.h"
57 #ifdef SCI_NAMESPACE
58 using namespace Scintilla;
59 #endif
61 ScintillaBase::ScintillaBase() {
62 displayPopupMenu = true;
63 listType = 0;
64 maxListWidth = 0;
65 multiAutoCMode = SC_MULTIAUTOC_ONCE;
68 ScintillaBase::~ScintillaBase() {
71 void ScintillaBase::Finalise() {
72 Editor::Finalise();
73 popup.Destroy();
76 void ScintillaBase::AddCharUTF(char *s, unsigned int len, bool treatAsDBCS) {
77 bool isFillUp = ac.Active() && ac.IsFillUpChar(*s);
78 if (!isFillUp) {
79 Editor::AddCharUTF(s, len, treatAsDBCS);
81 if (ac.Active()) {
82 AutoCompleteCharacterAdded(s[0]);
83 // For fill ups add the character after the autocompletion has
84 // triggered so containers see the key so can display a calltip.
85 if (isFillUp) {
86 Editor::AddCharUTF(s, len, treatAsDBCS);
91 void ScintillaBase::Command(int cmdId) {
93 switch (cmdId) {
95 case idAutoComplete: // Nothing to do
97 break;
99 case idCallTip: // Nothing to do
101 break;
103 case idcmdUndo:
104 WndProc(SCI_UNDO, 0, 0);
105 break;
107 case idcmdRedo:
108 WndProc(SCI_REDO, 0, 0);
109 break;
111 case idcmdCut:
112 WndProc(SCI_CUT, 0, 0);
113 break;
115 case idcmdCopy:
116 WndProc(SCI_COPY, 0, 0);
117 break;
119 case idcmdPaste:
120 WndProc(SCI_PASTE, 0, 0);
121 break;
123 case idcmdDelete:
124 WndProc(SCI_CLEAR, 0, 0);
125 break;
127 case idcmdSelectAll:
128 WndProc(SCI_SELECTALL, 0, 0);
129 break;
133 int ScintillaBase::KeyCommand(unsigned int iMessage) {
134 // Most key commands cancel autocompletion mode
135 if (ac.Active()) {
136 switch (iMessage) {
137 // Except for these
138 case SCI_LINEDOWN:
139 AutoCompleteMove(1);
140 return 0;
141 case SCI_LINEUP:
142 AutoCompleteMove(-1);
143 return 0;
144 case SCI_PAGEDOWN:
145 AutoCompleteMove(ac.lb->GetVisibleRows());
146 return 0;
147 case SCI_PAGEUP:
148 AutoCompleteMove(-ac.lb->GetVisibleRows());
149 return 0;
150 case SCI_VCHOME:
151 AutoCompleteMove(-5000);
152 return 0;
153 case SCI_LINEEND:
154 AutoCompleteMove(5000);
155 return 0;
156 case SCI_DELETEBACK:
157 DelCharBack(true);
158 AutoCompleteCharacterDeleted();
159 EnsureCaretVisible();
160 return 0;
161 case SCI_DELETEBACKNOTLINE:
162 DelCharBack(false);
163 AutoCompleteCharacterDeleted();
164 EnsureCaretVisible();
165 return 0;
166 case SCI_TAB:
167 AutoCompleteCompleted();
168 return 0;
169 case SCI_NEWLINE:
170 AutoCompleteCompleted();
171 return 0;
173 default:
174 AutoCompleteCancel();
178 if (ct.inCallTipMode) {
179 if (
180 (iMessage != SCI_CHARLEFT) &&
181 (iMessage != SCI_CHARLEFTEXTEND) &&
182 (iMessage != SCI_CHARRIGHT) &&
183 (iMessage != SCI_CHARRIGHTEXTEND) &&
184 (iMessage != SCI_EDITTOGGLEOVERTYPE) &&
185 (iMessage != SCI_DELETEBACK) &&
186 (iMessage != SCI_DELETEBACKNOTLINE)
188 ct.CallTipCancel();
190 if ((iMessage == SCI_DELETEBACK) || (iMessage == SCI_DELETEBACKNOTLINE)) {
191 if (sel.MainCaret() <= ct.posStartCallTip) {
192 ct.CallTipCancel();
196 return Editor::KeyCommand(iMessage);
199 void ScintillaBase::AutoCompleteDoubleClick(void *p) {
200 ScintillaBase *sci = reinterpret_cast<ScintillaBase *>(p);
201 sci->AutoCompleteCompleted();
204 void ScintillaBase::AutoCompleteInsert(Position startPos, int removeLen, const char *text, int textLen) {
205 UndoGroup ug(pdoc);
206 if (multiAutoCMode == SC_MULTIAUTOC_ONCE) {
207 pdoc->DeleteChars(startPos, removeLen);
208 const int lengthInserted = pdoc->InsertString(startPos, text, textLen);
209 SetEmptySelection(startPos + lengthInserted);
210 } else {
211 // SC_MULTIAUTOC_EACH
212 for (size_t r=0; r<sel.Count(); r++) {
213 if (!RangeContainsProtected(sel.Range(r).Start().Position(),
214 sel.Range(r).End().Position())) {
215 int positionInsert = sel.Range(r).Start().Position();
216 positionInsert = InsertSpace(positionInsert, sel.Range(r).caret.VirtualSpace());
217 if (positionInsert - removeLen >= 0) {
218 positionInsert -= removeLen;
219 pdoc->DeleteChars(positionInsert, removeLen);
221 const int lengthInserted = pdoc->InsertString(positionInsert, text, textLen);
222 if (lengthInserted > 0) {
223 sel.Range(r).caret.SetPosition(positionInsert + lengthInserted);
224 sel.Range(r).anchor.SetPosition(positionInsert + lengthInserted);
226 sel.Range(r).ClearVirtualSpace();
232 void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) {
233 //Platform::DebugPrintf("AutoComplete %s\n", list);
234 ct.CallTipCancel();
236 if (ac.chooseSingle && (listType == 0)) {
237 if (list && !strchr(list, ac.GetSeparator())) {
238 const char *typeSep = strchr(list, ac.GetTypesep());
239 int lenInsert = typeSep ?
240 static_cast<int>(typeSep-list) : static_cast<int>(strlen(list));
241 if (ac.ignoreCase) {
242 // May need to convert the case before invocation, so remove lenEntered characters
243 AutoCompleteInsert(sel.MainCaret() - lenEntered, lenEntered, list, lenInsert);
244 } else {
245 AutoCompleteInsert(sel.MainCaret(), 0, list + lenEntered, lenInsert - lenEntered);
247 ac.Cancel();
248 return;
251 ac.Start(wMain, idAutoComplete, sel.MainCaret(), PointMainCaret(),
252 lenEntered, vs.lineHeight, IsUnicodeMode(), technology);
254 PRectangle rcClient = GetClientRectangle();
255 Point pt = LocationFromPosition(sel.MainCaret() - lenEntered);
256 PRectangle rcPopupBounds = wMain.GetMonitorRect(pt);
257 if (rcPopupBounds.Height() == 0)
258 rcPopupBounds = rcClient;
260 int heightLB = ac.heightLBDefault;
261 int widthLB = ac.widthLBDefault;
262 if (pt.x >= rcClient.right - widthLB) {
263 HorizontalScrollTo(static_cast<int>(xOffset + pt.x - rcClient.right + widthLB));
264 Redraw();
265 pt = PointMainCaret();
267 if (wMargin.GetID()) {
268 Point ptOrigin = GetVisibleOriginInMain();
269 pt.x += ptOrigin.x;
270 pt.y += ptOrigin.y;
272 PRectangle rcac;
273 rcac.left = pt.x - ac.lb->CaretFromEdge();
274 if (pt.y >= rcPopupBounds.bottom - heightLB && // Wont fit below.
275 pt.y >= (rcPopupBounds.bottom + rcPopupBounds.top) / 2) { // and there is more room above.
276 rcac.top = pt.y - heightLB;
277 if (rcac.top < rcPopupBounds.top) {
278 heightLB -= static_cast<int>(rcPopupBounds.top - rcac.top);
279 rcac.top = rcPopupBounds.top;
281 } else {
282 rcac.top = pt.y + vs.lineHeight;
284 rcac.right = rcac.left + widthLB;
285 rcac.bottom = static_cast<XYPOSITION>(Platform::Minimum(static_cast<int>(rcac.top) + heightLB, static_cast<int>(rcPopupBounds.bottom)));
286 ac.lb->SetPositionRelative(rcac, wMain);
287 ac.lb->SetFont(vs.styles[STYLE_DEFAULT].font);
288 unsigned int aveCharWidth = static_cast<unsigned int>(vs.styles[STYLE_DEFAULT].aveCharWidth);
289 ac.lb->SetAverageCharWidth(aveCharWidth);
290 ac.lb->SetDoubleClickAction(AutoCompleteDoubleClick, this);
292 ac.SetList(list ? list : "");
294 // Fiddle the position of the list so it is right next to the target and wide enough for all its strings
295 PRectangle rcList = ac.lb->GetDesiredRect();
296 int heightAlloced = static_cast<int>(rcList.bottom - rcList.top);
297 widthLB = Platform::Maximum(widthLB, static_cast<int>(rcList.right - rcList.left));
298 if (maxListWidth != 0)
299 widthLB = Platform::Minimum(widthLB, aveCharWidth*maxListWidth);
300 // Make an allowance for large strings in list
301 rcList.left = pt.x - ac.lb->CaretFromEdge();
302 rcList.right = rcList.left + widthLB;
303 if (((pt.y + vs.lineHeight) >= (rcPopupBounds.bottom - heightAlloced)) && // Wont fit below.
304 ((pt.y + vs.lineHeight / 2) >= (rcPopupBounds.bottom + rcPopupBounds.top) / 2)) { // and there is more room above.
305 rcList.top = pt.y - heightAlloced;
306 } else {
307 rcList.top = pt.y + vs.lineHeight;
309 rcList.bottom = rcList.top + heightAlloced;
310 ac.lb->SetPositionRelative(rcList, wMain);
311 ac.Show(true);
312 if (lenEntered != 0) {
313 AutoCompleteMoveToCurrentWord();
317 void ScintillaBase::AutoCompleteCancel() {
318 if (ac.Active()) {
319 SCNotification scn = {};
320 scn.nmhdr.code = SCN_AUTOCCANCELLED;
321 scn.wParam = 0;
322 scn.listType = 0;
323 NotifyParent(scn);
325 ac.Cancel();
328 void ScintillaBase::AutoCompleteMove(int delta) {
329 ac.Move(delta);
332 void ScintillaBase::AutoCompleteMoveToCurrentWord() {
333 std::string wordCurrent = RangeText(ac.posStart - ac.startLen, sel.MainCaret());
334 ac.Select(wordCurrent.c_str());
337 void ScintillaBase::AutoCompleteCharacterAdded(char ch) {
338 if (ac.IsFillUpChar(ch)) {
339 AutoCompleteCompleted();
340 } else if (ac.IsStopChar(ch)) {
341 AutoCompleteCancel();
342 } else {
343 AutoCompleteMoveToCurrentWord();
347 void ScintillaBase::AutoCompleteCharacterDeleted() {
348 if (sel.MainCaret() < ac.posStart - ac.startLen) {
349 AutoCompleteCancel();
350 } else if (ac.cancelAtStartPos && (sel.MainCaret() <= ac.posStart)) {
351 AutoCompleteCancel();
352 } else {
353 AutoCompleteMoveToCurrentWord();
355 SCNotification scn = {};
356 scn.nmhdr.code = SCN_AUTOCCHARDELETED;
357 scn.wParam = 0;
358 scn.listType = 0;
359 NotifyParent(scn);
362 void ScintillaBase::AutoCompleteCompleted() {
363 int item = ac.GetSelection();
364 if (item == -1) {
365 AutoCompleteCancel();
366 return;
368 const std::string selected = ac.GetValue(item);
370 ac.Show(false);
372 SCNotification scn = {};
373 scn.nmhdr.code = listType > 0 ? SCN_USERLISTSELECTION : SCN_AUTOCSELECTION;
374 scn.message = 0;
375 scn.wParam = listType;
376 scn.listType = listType;
377 Position firstPos = ac.posStart - ac.startLen;
378 scn.position = firstPos;
379 scn.lParam = firstPos;
380 scn.text = selected.c_str();
381 NotifyParent(scn);
383 if (!ac.Active())
384 return;
385 ac.Cancel();
387 if (listType > 0)
388 return;
390 Position endPos = sel.MainCaret();
391 if (ac.dropRestOfWord)
392 endPos = pdoc->ExtendWordSelect(endPos, 1, true);
393 if (endPos < firstPos)
394 return;
395 AutoCompleteInsert(firstPos, endPos - firstPos, selected.c_str(), static_cast<int>(selected.length()));
396 SetLastXChosen();
399 int ScintillaBase::AutoCompleteGetCurrent() const {
400 if (!ac.Active())
401 return -1;
402 return ac.GetSelection();
405 int ScintillaBase::AutoCompleteGetCurrentText(char *buffer) const {
406 if (ac.Active()) {
407 int item = ac.GetSelection();
408 if (item != -1) {
409 const std::string selected = ac.GetValue(item);
410 if (buffer != NULL)
411 memcpy(buffer, selected.c_str(), selected.length()+1);
412 return static_cast<int>(selected.length());
415 if (buffer != NULL)
416 *buffer = '\0';
417 return 0;
420 void ScintillaBase::CallTipShow(Point pt, const char *defn) {
421 ac.Cancel();
422 // If container knows about STYLE_CALLTIP then use it in place of the
423 // STYLE_DEFAULT for the face name, size and character set. Also use it
424 // for the foreground and background colour.
425 int ctStyle = ct.UseStyleCallTip() ? STYLE_CALLTIP : STYLE_DEFAULT;
426 if (ct.UseStyleCallTip()) {
427 ct.SetForeBack(vs.styles[STYLE_CALLTIP].fore, vs.styles[STYLE_CALLTIP].back);
429 if (wMargin.GetID()) {
430 Point ptOrigin = GetVisibleOriginInMain();
431 pt.x += ptOrigin.x;
432 pt.y += ptOrigin.y;
434 PRectangle rc = ct.CallTipStart(sel.MainCaret(), pt,
435 vs.lineHeight,
436 defn,
437 vs.styles[ctStyle].fontName,
438 vs.styles[ctStyle].sizeZoomed,
439 CodePage(),
440 vs.styles[ctStyle].characterSet,
441 vs.technology,
442 wMain);
443 // If the call-tip window would be out of the client
444 // space
445 PRectangle rcClient = GetClientRectangle();
446 int offset = vs.lineHeight + static_cast<int>(rc.Height());
447 // adjust so it displays above the text.
448 if (rc.bottom > rcClient.bottom) {
449 rc.top -= offset;
450 rc.bottom -= offset;
452 // adjust so it displays below the text.
453 if (rc.top < rcClient.top) {
454 rc.top += offset;
455 rc.bottom += offset;
457 // Now display the window.
458 CreateCallTipWindow(rc);
459 ct.wCallTip.SetPositionRelative(rc, wMain);
460 ct.wCallTip.Show();
463 void ScintillaBase::CallTipClick() {
464 SCNotification scn = {};
465 scn.nmhdr.code = SCN_CALLTIPCLICK;
466 scn.position = ct.clickPlace;
467 NotifyParent(scn);
470 void ScintillaBase::ContextMenu(Point pt) {
471 if (displayPopupMenu) {
472 bool writable = !WndProc(SCI_GETREADONLY, 0, 0);
473 popup.CreatePopUp();
474 AddToPopUp("Undo", idcmdUndo, writable && pdoc->CanUndo());
475 AddToPopUp("Redo", idcmdRedo, writable && pdoc->CanRedo());
476 AddToPopUp("");
477 AddToPopUp("Cut", idcmdCut, writable && !sel.Empty());
478 AddToPopUp("Copy", idcmdCopy, !sel.Empty());
479 AddToPopUp("Paste", idcmdPaste, writable && WndProc(SCI_CANPASTE, 0, 0));
480 AddToPopUp("Delete", idcmdDelete, writable && !sel.Empty());
481 AddToPopUp("");
482 AddToPopUp("Select All", idcmdSelectAll);
483 popup.Show(pt, wMain);
487 void ScintillaBase::CancelModes() {
488 AutoCompleteCancel();
489 ct.CallTipCancel();
490 Editor::CancelModes();
493 void ScintillaBase::ButtonDownWithModifiers(Point pt, unsigned int curTime, int modifiers) {
494 CancelModes();
495 Editor::ButtonDownWithModifiers(pt, curTime, modifiers);
498 void ScintillaBase::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt) {
499 ButtonDownWithModifiers(pt, curTime, ModifierFlags(shift, ctrl, alt));
502 #ifdef SCI_LEXER
504 #ifdef SCI_NAMESPACE
505 namespace Scintilla {
506 #endif
508 class LexState : public LexInterface {
509 const LexerModule *lexCurrent;
510 void SetLexerModule(const LexerModule *lex);
511 PropSetSimple props;
512 int interfaceVersion;
513 public:
514 int lexLanguage;
516 explicit LexState(Document *pdoc_);
517 virtual ~LexState();
518 void SetLexer(uptr_t wParam);
519 void SetLexerLanguage(const char *languageName);
520 const char *DescribeWordListSets();
521 void SetWordList(int n, const char *wl);
522 const char *GetName() const;
523 void *PrivateCall(int operation, void *pointer);
524 const char *PropertyNames();
525 int PropertyType(const char *name);
526 const char *DescribeProperty(const char *name);
527 void PropSet(const char *key, const char *val);
528 const char *PropGet(const char *key) const;
529 int PropGetInt(const char *key, int defaultValue=0) const;
530 int PropGetExpanded(const char *key, char *result) const;
532 int LineEndTypesSupported();
533 int AllocateSubStyles(int styleBase, int numberStyles);
534 int SubStylesStart(int styleBase);
535 int SubStylesLength(int styleBase);
536 int StyleFromSubStyle(int subStyle);
537 int PrimaryStyleFromStyle(int style);
538 void FreeSubStyles();
539 void SetIdentifiers(int style, const char *identifiers);
540 int DistanceToSecondaryStyles();
541 const char *GetSubStyleBases();
544 #ifdef SCI_NAMESPACE
546 #endif
548 LexState::LexState(Document *pdoc_) : LexInterface(pdoc_) {
549 lexCurrent = 0;
550 performingStyle = false;
551 interfaceVersion = lvOriginal;
552 lexLanguage = SCLEX_CONTAINER;
555 LexState::~LexState() {
556 if (instance) {
557 instance->Release();
558 instance = 0;
562 LexState *ScintillaBase::DocumentLexState() {
563 if (!pdoc->pli) {
564 pdoc->pli = new LexState(pdoc);
566 return static_cast<LexState *>(pdoc->pli);
569 void LexState::SetLexerModule(const LexerModule *lex) {
570 if (lex != lexCurrent) {
571 if (instance) {
572 instance->Release();
573 instance = 0;
575 interfaceVersion = lvOriginal;
576 lexCurrent = lex;
577 if (lexCurrent) {
578 instance = lexCurrent->Create();
579 interfaceVersion = instance->Version();
581 pdoc->LexerChanged();
585 void LexState::SetLexer(uptr_t wParam) {
586 lexLanguage = wParam;
587 if (lexLanguage == SCLEX_CONTAINER) {
588 SetLexerModule(0);
589 } else {
590 const LexerModule *lex = Catalogue::Find(lexLanguage);
591 if (!lex)
592 lex = Catalogue::Find(SCLEX_NULL);
593 SetLexerModule(lex);
597 void LexState::SetLexerLanguage(const char *languageName) {
598 const LexerModule *lex = Catalogue::Find(languageName);
599 if (!lex)
600 lex = Catalogue::Find(SCLEX_NULL);
601 if (lex)
602 lexLanguage = lex->GetLanguage();
603 SetLexerModule(lex);
606 const char *LexState::DescribeWordListSets() {
607 if (instance) {
608 return instance->DescribeWordListSets();
609 } else {
610 return 0;
614 void LexState::SetWordList(int n, const char *wl) {
615 if (instance) {
616 int firstModification = instance->WordListSet(n, wl);
617 if (firstModification >= 0) {
618 pdoc->ModifiedAt(firstModification);
623 const char *LexState::GetName() const {
624 return lexCurrent ? lexCurrent->languageName : "";
627 void *LexState::PrivateCall(int operation, void *pointer) {
628 if (pdoc && instance) {
629 return instance->PrivateCall(operation, pointer);
630 } else {
631 return 0;
635 const char *LexState::PropertyNames() {
636 if (instance) {
637 return instance->PropertyNames();
638 } else {
639 return 0;
643 int LexState::PropertyType(const char *name) {
644 if (instance) {
645 return instance->PropertyType(name);
646 } else {
647 return SC_TYPE_BOOLEAN;
651 const char *LexState::DescribeProperty(const char *name) {
652 if (instance) {
653 return instance->DescribeProperty(name);
654 } else {
655 return 0;
659 void LexState::PropSet(const char *key, const char *val) {
660 props.Set(key, val);
661 if (instance) {
662 int firstModification = instance->PropertySet(key, val);
663 if (firstModification >= 0) {
664 pdoc->ModifiedAt(firstModification);
669 const char *LexState::PropGet(const char *key) const {
670 return props.Get(key);
673 int LexState::PropGetInt(const char *key, int defaultValue) const {
674 return props.GetInt(key, defaultValue);
677 int LexState::PropGetExpanded(const char *key, char *result) const {
678 return props.GetExpanded(key, result);
681 int LexState::LineEndTypesSupported() {
682 if (instance && (interfaceVersion >= lvSubStyles)) {
683 return static_cast<ILexerWithSubStyles *>(instance)->LineEndTypesSupported();
685 return 0;
688 int LexState::AllocateSubStyles(int styleBase, int numberStyles) {
689 if (instance && (interfaceVersion >= lvSubStyles)) {
690 return static_cast<ILexerWithSubStyles *>(instance)->AllocateSubStyles(styleBase, numberStyles);
692 return -1;
695 int LexState::SubStylesStart(int styleBase) {
696 if (instance && (interfaceVersion >= lvSubStyles)) {
697 return static_cast<ILexerWithSubStyles *>(instance)->SubStylesStart(styleBase);
699 return -1;
702 int LexState::SubStylesLength(int styleBase) {
703 if (instance && (interfaceVersion >= lvSubStyles)) {
704 return static_cast<ILexerWithSubStyles *>(instance)->SubStylesLength(styleBase);
706 return 0;
709 int LexState::StyleFromSubStyle(int subStyle) {
710 if (instance && (interfaceVersion >= lvSubStyles)) {
711 return static_cast<ILexerWithSubStyles *>(instance)->StyleFromSubStyle(subStyle);
713 return 0;
716 int LexState::PrimaryStyleFromStyle(int style) {
717 if (instance && (interfaceVersion >= lvSubStyles)) {
718 return static_cast<ILexerWithSubStyles *>(instance)->PrimaryStyleFromStyle(style);
720 return 0;
723 void LexState::FreeSubStyles() {
724 if (instance && (interfaceVersion >= lvSubStyles)) {
725 static_cast<ILexerWithSubStyles *>(instance)->FreeSubStyles();
729 void LexState::SetIdentifiers(int style, const char *identifiers) {
730 if (instance && (interfaceVersion >= lvSubStyles)) {
731 static_cast<ILexerWithSubStyles *>(instance)->SetIdentifiers(style, identifiers);
735 int LexState::DistanceToSecondaryStyles() {
736 if (instance && (interfaceVersion >= lvSubStyles)) {
737 return static_cast<ILexerWithSubStyles *>(instance)->DistanceToSecondaryStyles();
739 return 0;
742 const char *LexState::GetSubStyleBases() {
743 if (instance && (interfaceVersion >= lvSubStyles)) {
744 return static_cast<ILexerWithSubStyles *>(instance)->GetSubStyleBases();
746 return "";
749 #endif
751 void ScintillaBase::NotifyStyleToNeeded(int endStyleNeeded) {
752 #ifdef SCI_LEXER
753 if (DocumentLexState()->lexLanguage != SCLEX_CONTAINER) {
754 int lineEndStyled = pdoc->LineFromPosition(pdoc->GetEndStyled());
755 int endStyled = pdoc->LineStart(lineEndStyled);
756 DocumentLexState()->Colourise(endStyled, endStyleNeeded);
757 return;
759 #endif
760 Editor::NotifyStyleToNeeded(endStyleNeeded);
763 void ScintillaBase::NotifyLexerChanged(Document *, void *) {
764 #ifdef SCI_LEXER
765 vs.EnsureStyle(0xff);
766 #endif
769 sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
770 switch (iMessage) {
771 case SCI_AUTOCSHOW:
772 listType = 0;
773 AutoCompleteStart(static_cast<int>(wParam), reinterpret_cast<const char *>(lParam));
774 break;
776 case SCI_AUTOCCANCEL:
777 ac.Cancel();
778 break;
780 case SCI_AUTOCACTIVE:
781 return ac.Active();
783 case SCI_AUTOCPOSSTART:
784 return ac.posStart;
786 case SCI_AUTOCCOMPLETE:
787 AutoCompleteCompleted();
788 break;
790 case SCI_AUTOCSETSEPARATOR:
791 ac.SetSeparator(static_cast<char>(wParam));
792 break;
794 case SCI_AUTOCGETSEPARATOR:
795 return ac.GetSeparator();
797 case SCI_AUTOCSTOPS:
798 ac.SetStopChars(reinterpret_cast<char *>(lParam));
799 break;
801 case SCI_AUTOCSELECT:
802 ac.Select(reinterpret_cast<char *>(lParam));
803 break;
805 case SCI_AUTOCGETCURRENT:
806 return AutoCompleteGetCurrent();
808 case SCI_AUTOCGETCURRENTTEXT:
809 return AutoCompleteGetCurrentText(reinterpret_cast<char *>(lParam));
811 case SCI_AUTOCSETCANCELATSTART:
812 ac.cancelAtStartPos = wParam != 0;
813 break;
815 case SCI_AUTOCGETCANCELATSTART:
816 return ac.cancelAtStartPos;
818 case SCI_AUTOCSETFILLUPS:
819 ac.SetFillUpChars(reinterpret_cast<char *>(lParam));
820 break;
822 case SCI_AUTOCSETCHOOSESINGLE:
823 ac.chooseSingle = wParam != 0;
824 break;
826 case SCI_AUTOCGETCHOOSESINGLE:
827 return ac.chooseSingle;
829 case SCI_AUTOCSETIGNORECASE:
830 ac.ignoreCase = wParam != 0;
831 break;
833 case SCI_AUTOCGETIGNORECASE:
834 return ac.ignoreCase;
836 case SCI_AUTOCSETCASEINSENSITIVEBEHAVIOUR:
837 ac.ignoreCaseBehaviour = static_cast<unsigned int>(wParam);
838 break;
840 case SCI_AUTOCGETCASEINSENSITIVEBEHAVIOUR:
841 return ac.ignoreCaseBehaviour;
843 case SCI_AUTOCSETMULTI:
844 multiAutoCMode = static_cast<int>(wParam);
845 break;
847 case SCI_AUTOCGETMULTI:
848 return multiAutoCMode;
850 case SCI_AUTOCSETORDER:
851 ac.autoSort = static_cast<int>(wParam);
852 break;
854 case SCI_AUTOCGETORDER:
855 return ac.autoSort;
857 case SCI_USERLISTSHOW:
858 listType = static_cast<int>(wParam);
859 AutoCompleteStart(0, reinterpret_cast<const char *>(lParam));
860 break;
862 case SCI_AUTOCSETAUTOHIDE:
863 ac.autoHide = wParam != 0;
864 break;
866 case SCI_AUTOCGETAUTOHIDE:
867 return ac.autoHide;
869 case SCI_AUTOCSETDROPRESTOFWORD:
870 ac.dropRestOfWord = wParam != 0;
871 break;
873 case SCI_AUTOCGETDROPRESTOFWORD:
874 return ac.dropRestOfWord;
876 case SCI_AUTOCSETMAXHEIGHT:
877 ac.lb->SetVisibleRows(static_cast<int>(wParam));
878 break;
880 case SCI_AUTOCGETMAXHEIGHT:
881 return ac.lb->GetVisibleRows();
883 case SCI_AUTOCSETMAXWIDTH:
884 maxListWidth = static_cast<int>(wParam);
885 break;
887 case SCI_AUTOCGETMAXWIDTH:
888 return maxListWidth;
890 case SCI_REGISTERIMAGE:
891 ac.lb->RegisterImage(static_cast<int>(wParam), reinterpret_cast<const char *>(lParam));
892 break;
894 case SCI_REGISTERRGBAIMAGE:
895 ac.lb->RegisterRGBAImage(static_cast<int>(wParam), static_cast<int>(sizeRGBAImage.x), static_cast<int>(sizeRGBAImage.y),
896 reinterpret_cast<unsigned char *>(lParam));
897 break;
899 case SCI_CLEARREGISTEREDIMAGES:
900 ac.lb->ClearRegisteredImages();
901 break;
903 case SCI_AUTOCSETTYPESEPARATOR:
904 ac.SetTypesep(static_cast<char>(wParam));
905 break;
907 case SCI_AUTOCGETTYPESEPARATOR:
908 return ac.GetTypesep();
910 case SCI_CALLTIPSHOW:
911 CallTipShow(LocationFromPosition(static_cast<int>(wParam)),
912 reinterpret_cast<const char *>(lParam));
913 break;
915 case SCI_CALLTIPCANCEL:
916 ct.CallTipCancel();
917 break;
919 case SCI_CALLTIPACTIVE:
920 return ct.inCallTipMode;
922 case SCI_CALLTIPPOSSTART:
923 return ct.posStartCallTip;
925 case SCI_CALLTIPSETPOSSTART:
926 ct.posStartCallTip = static_cast<int>(wParam);
927 break;
929 case SCI_CALLTIPSETHLT:
930 ct.SetHighlight(static_cast<int>(wParam), static_cast<int>(lParam));
931 break;
933 case SCI_CALLTIPSETBACK:
934 ct.colourBG = ColourDesired(static_cast<long>(wParam));
935 vs.styles[STYLE_CALLTIP].back = ct.colourBG;
936 InvalidateStyleRedraw();
937 break;
939 case SCI_CALLTIPSETFORE:
940 ct.colourUnSel = ColourDesired(static_cast<long>(wParam));
941 vs.styles[STYLE_CALLTIP].fore = ct.colourUnSel;
942 InvalidateStyleRedraw();
943 break;
945 case SCI_CALLTIPSETFOREHLT:
946 ct.colourSel = ColourDesired(static_cast<long>(wParam));
947 InvalidateStyleRedraw();
948 break;
950 case SCI_CALLTIPUSESTYLE:
951 ct.SetTabSize(static_cast<int>(wParam));
952 InvalidateStyleRedraw();
953 break;
955 case SCI_CALLTIPSETPOSITION:
956 ct.SetPosition(wParam != 0);
957 InvalidateStyleRedraw();
958 break;
960 case SCI_USEPOPUP:
961 displayPopupMenu = wParam != 0;
962 break;
964 #ifdef SCI_LEXER
965 case SCI_SETLEXER:
966 DocumentLexState()->SetLexer(static_cast<int>(wParam));
967 break;
969 case SCI_GETLEXER:
970 return DocumentLexState()->lexLanguage;
972 case SCI_COLOURISE:
973 if (DocumentLexState()->lexLanguage == SCLEX_CONTAINER) {
974 pdoc->ModifiedAt(static_cast<int>(wParam));
975 NotifyStyleToNeeded((lParam == -1) ? pdoc->Length() : static_cast<int>(lParam));
976 } else {
977 DocumentLexState()->Colourise(static_cast<int>(wParam), static_cast<int>(lParam));
979 Redraw();
980 break;
982 case SCI_SETPROPERTY:
983 DocumentLexState()->PropSet(reinterpret_cast<const char *>(wParam),
984 reinterpret_cast<const char *>(lParam));
985 break;
987 case SCI_GETPROPERTY:
988 return StringResult(lParam, DocumentLexState()->PropGet(reinterpret_cast<const char *>(wParam)));
990 case SCI_GETPROPERTYEXPANDED:
991 return DocumentLexState()->PropGetExpanded(reinterpret_cast<const char *>(wParam),
992 reinterpret_cast<char *>(lParam));
994 case SCI_GETPROPERTYINT:
995 return DocumentLexState()->PropGetInt(reinterpret_cast<const char *>(wParam), static_cast<int>(lParam));
997 case SCI_SETKEYWORDS:
998 DocumentLexState()->SetWordList(wParam, reinterpret_cast<const char *>(lParam));
999 break;
1001 case SCI_SETLEXERLANGUAGE:
1002 DocumentLexState()->SetLexerLanguage(reinterpret_cast<const char *>(lParam));
1003 break;
1005 case SCI_GETLEXERLANGUAGE:
1006 return StringResult(lParam, DocumentLexState()->GetName());
1008 case SCI_PRIVATELEXERCALL:
1009 return reinterpret_cast<sptr_t>(
1010 DocumentLexState()->PrivateCall(wParam, reinterpret_cast<void *>(lParam)));
1012 case SCI_GETSTYLEBITSNEEDED:
1013 return 8;
1015 case SCI_PROPERTYNAMES:
1016 return StringResult(lParam, DocumentLexState()->PropertyNames());
1018 case SCI_PROPERTYTYPE:
1019 return DocumentLexState()->PropertyType(reinterpret_cast<const char *>(wParam));
1021 case SCI_DESCRIBEPROPERTY:
1022 return StringResult(lParam, DocumentLexState()->DescribeProperty(reinterpret_cast<const char *>(wParam)));
1024 case SCI_DESCRIBEKEYWORDSETS:
1025 return StringResult(lParam, DocumentLexState()->DescribeWordListSets());
1027 case SCI_GETLINEENDTYPESSUPPORTED:
1028 return DocumentLexState()->LineEndTypesSupported();
1030 case SCI_ALLOCATESUBSTYLES:
1031 return DocumentLexState()->AllocateSubStyles(wParam, lParam);
1033 case SCI_GETSUBSTYLESSTART:
1034 return DocumentLexState()->SubStylesStart(wParam);
1036 case SCI_GETSUBSTYLESLENGTH:
1037 return DocumentLexState()->SubStylesLength(wParam);
1039 case SCI_GETSTYLEFROMSUBSTYLE:
1040 return DocumentLexState()->StyleFromSubStyle(wParam);
1042 case SCI_GETPRIMARYSTYLEFROMSTYLE:
1043 return DocumentLexState()->PrimaryStyleFromStyle(wParam);
1045 case SCI_FREESUBSTYLES:
1046 DocumentLexState()->FreeSubStyles();
1047 break;
1049 case SCI_SETIDENTIFIERS:
1050 DocumentLexState()->SetIdentifiers(wParam, reinterpret_cast<const char *>(lParam));
1051 break;
1053 case SCI_DISTANCETOSECONDARYSTYLES:
1054 return DocumentLexState()->DistanceToSecondaryStyles();
1056 case SCI_GETSUBSTYLEBASES:
1057 return StringResult(lParam, DocumentLexState()->GetSubStyleBases());
1058 #endif
1060 default:
1061 return Editor::WndProc(iMessage, wParam, lParam);
1063 return 0l;