Fix typos
[TortoiseGit.git] / ext / scintilla / src / ScintillaBase.cxx
blob288de6ef0dff170cb032f470d88d407b8d419843
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 <cstddef>
9 #include <cstdlib>
10 #include <cstdint>
11 #include <cassert>
12 #include <cstring>
14 #include <stdexcept>
15 #include <string>
16 #include <string_view>
17 #include <vector>
18 #include <map>
19 #include <set>
20 #include <optional>
21 #include <algorithm>
22 #include <memory>
24 #include "ScintillaTypes.h"
25 #include "ScintillaMessages.h"
26 #include "ScintillaStructures.h"
27 #include "ILoader.h"
28 #include "ILexer.h"
30 #include "Debugging.h"
31 #include "Geometry.h"
32 #include "Platform.h"
34 #include "CharacterCategoryMap.h"
36 #include "Position.h"
37 #include "UniqueString.h"
38 #include "SplitVector.h"
39 #include "Partitioning.h"
40 #include "RunStyles.h"
41 #include "ContractionState.h"
42 #include "CellBuffer.h"
43 #include "CallTip.h"
44 #include "KeyMap.h"
45 #include "Indicator.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 using namespace Scintilla;
63 using namespace Scintilla::Internal;
65 ScintillaBase::ScintillaBase() {
66 displayPopupMenu = PopUp::All;
67 listType = 0;
68 maxListWidth = 0;
69 multiAutoCMode = MultiAutoComplete::Once;
72 ScintillaBase::~ScintillaBase() {
75 void ScintillaBase::Finalise() {
76 Editor::Finalise();
77 popup.Destroy();
80 void ScintillaBase::InsertCharacter(std::string_view sv, CharacterSource charSource) {
81 const bool acActive = ac.Active();
82 const bool isFillUp = acActive && ac.IsFillUpChar(sv[0]);
83 if (!isFillUp) {
84 Editor::InsertCharacter(sv, charSource);
86 if (acActive && ac.Active()) { // if it was and still is active
87 AutoCompleteCharacterAdded(sv[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::InsertCharacter(sv, charSource);
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(Message::Undo, 0, 0);
110 break;
112 case idcmdRedo:
113 WndProc(Message::Redo, 0, 0);
114 break;
116 case idcmdCut:
117 WndProc(Message::Cut, 0, 0);
118 break;
120 case idcmdCopy:
121 WndProc(Message::Copy, 0, 0);
122 break;
124 case idcmdPaste:
125 WndProc(Message::Paste, 0, 0);
126 break;
128 case idcmdDelete:
129 WndProc(Message::Clear, 0, 0);
130 break;
132 case idcmdSelectAll:
133 WndProc(Message::SelectAll, 0, 0);
134 break;
138 int ScintillaBase::KeyCommand(Message iMessage) {
139 // Most key commands cancel autocompletion mode
140 if (ac.Active()) {
141 switch (iMessage) {
142 // Except for these
143 case Message::LineDown:
144 AutoCompleteMove(1);
145 return 0;
146 case Message::LineUp:
147 AutoCompleteMove(-1);
148 return 0;
149 case Message::PageDown:
150 AutoCompleteMove(ac.lb->GetVisibleRows());
151 return 0;
152 case Message::PageUp:
153 AutoCompleteMove(-ac.lb->GetVisibleRows());
154 return 0;
155 case Message::VCHome:
156 AutoCompleteMove(-5000);
157 return 0;
158 case Message::LineEnd:
159 AutoCompleteMove(5000);
160 return 0;
161 case Message::DeleteBack:
162 DelCharBack(true);
163 AutoCompleteCharacterDeleted();
164 EnsureCaretVisible();
165 return 0;
166 case Message::DeleteBackNotLine:
167 DelCharBack(false);
168 AutoCompleteCharacterDeleted();
169 EnsureCaretVisible();
170 return 0;
171 case Message::Tab:
172 AutoCompleteCompleted(0, CompletionMethods::Tab);
173 return 0;
174 case Message::NewLine:
175 AutoCompleteCompleted(0, CompletionMethods::Newline);
176 return 0;
178 default:
179 AutoCompleteCancel();
183 if (ct.inCallTipMode) {
184 if (
185 (iMessage != Message::CharLeft) &&
186 (iMessage != Message::CharLeftExtend) &&
187 (iMessage != Message::CharRight) &&
188 (iMessage != Message::CharRightExtend) &&
189 (iMessage != Message::EditToggleOvertype) &&
190 (iMessage != Message::DeleteBack) &&
191 (iMessage != Message::DeleteBackNotLine)
193 ct.CallTipCancel();
195 if ((iMessage == Message::DeleteBack) || (iMessage == Message::DeleteBackNotLine)) {
196 if (sel.MainCaret() <= ct.posStartCallTip) {
197 ct.CallTipCancel();
201 return Editor::KeyCommand(iMessage);
204 void ScintillaBase::ListNotify(ListBoxEvent *plbe) {
205 switch (plbe->event) {
206 case ListBoxEvent::EventType::selectionChange:
207 AutoCompleteSelection();
208 break;
209 case ListBoxEvent::EventType::doubleClick:
210 AutoCompleteCompleted(0, CompletionMethods::DoubleClick);
211 break;
215 void ScintillaBase::AutoCompleteInsert(Sci::Position startPos, Sci::Position removeLen, std::string_view text) {
216 UndoGroup ug(pdoc);
217 if (multiAutoCMode == MultiAutoComplete::Once) {
218 pdoc->DeleteChars(startPos, removeLen);
219 const Sci::Position lengthInserted = pdoc->InsertString(startPos, text);
220 SetEmptySelection(startPos + lengthInserted);
221 } else {
222 // MultiAutoComplete::Each
223 for (size_t r=0; r<sel.Count(); r++) {
224 if (!RangeContainsProtected(sel.Range(r).Start().Position(),
225 sel.Range(r).End().Position())) {
226 Sci::Position positionInsert = sel.Range(r).Start().Position();
227 positionInsert = RealizeVirtualSpace(positionInsert, sel.Range(r).caret.VirtualSpace());
228 if (positionInsert - removeLen >= 0) {
229 positionInsert -= removeLen;
230 pdoc->DeleteChars(positionInsert, removeLen);
232 const Sci::Position lengthInserted = pdoc->InsertString(positionInsert, text);
233 if (lengthInserted > 0) {
234 sel.Range(r).caret.SetPosition(positionInsert + lengthInserted);
235 sel.Range(r).anchor.SetPosition(positionInsert + lengthInserted);
237 sel.Range(r).ClearVirtualSpace();
243 void ScintillaBase::AutoCompleteStart(Sci::Position lenEntered, const char *list) {
244 //Platform::DebugPrintf("AutoComplete %s\n", list);
245 ct.CallTipCancel();
247 if (ac.chooseSingle && (listType == 0)) {
248 if (list && !strchr(list, ac.GetSeparator())) {
249 // list contains just one item so choose it
250 const std::string_view item(list);
251 const std::string_view choice = item.substr(0, item.find_first_of(ac.GetTypesep()));
252 if (ac.ignoreCase) {
253 // May need to convert the case before invocation, so remove lenEntered characters
254 AutoCompleteInsert(sel.MainCaret() - lenEntered, lenEntered, choice);
255 } else {
256 AutoCompleteInsert(sel.MainCaret(), 0, choice.substr(lenEntered));
258 const Sci::Position firstPos = sel.MainCaret() - lenEntered;
259 // Construct a string with a NUL at end as that is expected by applications
260 const std::string selected(choice);
261 AutoCompleteNotifyCompleted('\0', CompletionMethods::SingleChoice, firstPos, selected.c_str());
263 ac.Cancel();
264 return;
268 const ListOptions options{
269 vs.ElementColour(Element::List),
270 vs.ElementColour(Element::ListBack),
271 vs.ElementColour(Element::ListSelected),
272 vs.ElementColour(Element::ListSelectedBack),
273 ac.options,
276 ac.Start(wMain, idAutoComplete, sel.MainCaret(), PointMainCaret(),
277 lenEntered, vs.lineHeight, IsUnicodeMode(), technology, options);
279 const PRectangle rcClient = GetClientRectangle();
280 Point pt = LocationFromPosition(sel.MainCaret() - lenEntered);
281 PRectangle rcPopupBounds = wMain.GetMonitorRect(pt);
282 if (rcPopupBounds.Height() == 0)
283 rcPopupBounds = rcClient;
285 int heightLB = ac.heightLBDefault;
286 int widthLB = ac.widthLBDefault;
287 if (pt.x >= rcClient.right - widthLB) {
288 HorizontalScrollTo(static_cast<int>(xOffset + pt.x - rcClient.right + widthLB));
289 Redraw();
290 pt = PointMainCaret();
292 if (wMargin.Created()) {
293 pt = pt + GetVisibleOriginInMain();
295 PRectangle rcac;
296 rcac.left = pt.x - ac.lb->CaretFromEdge();
297 if (pt.y >= rcPopupBounds.bottom - heightLB && // Won't fit below.
298 pt.y >= (rcPopupBounds.bottom + rcPopupBounds.top) / 2) { // and there is more room above.
299 rcac.top = pt.y - heightLB;
300 if (rcac.top < rcPopupBounds.top) {
301 heightLB -= static_cast<int>(rcPopupBounds.top - rcac.top);
302 rcac.top = rcPopupBounds.top;
304 } else {
305 rcac.top = pt.y + vs.lineHeight;
307 rcac.right = rcac.left + widthLB;
308 rcac.bottom = static_cast<XYPOSITION>(std::min(static_cast<int>(rcac.top) + heightLB, static_cast<int>(rcPopupBounds.bottom)));
309 ac.lb->SetPositionRelative(rcac, &wMain);
310 ac.lb->SetFont(vs.styles[StyleDefault].font.get());
311 const int aveCharWidth = static_cast<int>(vs.styles[StyleDefault].aveCharWidth);
312 ac.lb->SetAverageCharWidth(aveCharWidth);
313 ac.lb->SetDelegate(this);
315 ac.SetList(list ? list : "");
317 // Fiddle the position of the list so it is right next to the target and wide enough for all its strings
318 PRectangle rcList = ac.lb->GetDesiredRect();
319 const int heightAlloced = static_cast<int>(rcList.bottom - rcList.top);
320 widthLB = std::max(widthLB, static_cast<int>(rcList.right - rcList.left));
321 if (maxListWidth != 0)
322 widthLB = std::min(widthLB, aveCharWidth*maxListWidth);
323 // Make an allowance for large strings in list
324 rcList.left = pt.x - ac.lb->CaretFromEdge();
325 rcList.right = rcList.left + widthLB;
326 if (((pt.y + vs.lineHeight) >= (rcPopupBounds.bottom - heightAlloced)) && // Won't fit below.
327 ((pt.y + vs.lineHeight / 2) >= (rcPopupBounds.bottom + rcPopupBounds.top) / 2)) { // and there is more room above.
328 rcList.top = pt.y - heightAlloced;
329 } else {
330 rcList.top = pt.y + vs.lineHeight;
332 rcList.bottom = rcList.top + heightAlloced;
333 ac.lb->SetPositionRelative(rcList, &wMain);
334 ac.Show(true);
335 if (lenEntered != 0) {
336 AutoCompleteMoveToCurrentWord();
340 void ScintillaBase::AutoCompleteCancel() {
341 if (ac.Active()) {
342 NotificationData scn = {};
343 scn.nmhdr.code = Notification::AutoCCancelled;
344 scn.wParam = 0;
345 scn.listType = 0;
346 NotifyParent(scn);
348 ac.Cancel();
351 void ScintillaBase::AutoCompleteMove(int delta) {
352 ac.Move(delta);
355 void ScintillaBase::AutoCompleteMoveToCurrentWord() {
356 if (FlagSet(ac.options, AutoCompleteOption::SelectFirstItem))
357 return;
358 std::string wordCurrent = RangeText(ac.posStart - ac.startLen, sel.MainCaret());
359 ac.Select(wordCurrent.c_str());
362 void ScintillaBase::AutoCompleteSelection() {
363 const int item = ac.GetSelection();
364 std::string selected;
365 if (item != -1) {
366 selected = ac.GetValue(item);
369 NotificationData scn = {};
370 scn.nmhdr.code = Notification::AutoCSelectionChange;
371 scn.message = static_cast<Message>(0);
372 scn.wParam = listType;
373 scn.listType = listType;
374 const Sci::Position firstPos = ac.posStart - ac.startLen;
375 scn.position = firstPos;
376 scn.lParam = firstPos;
377 scn.text = selected.c_str();
378 NotifyParent(scn);
381 void ScintillaBase::AutoCompleteCharacterAdded(char ch) {
382 if (ac.IsFillUpChar(ch)) {
383 AutoCompleteCompleted(ch, CompletionMethods::FillUp);
384 } else if (ac.IsStopChar(ch)) {
385 AutoCompleteCancel();
386 } else {
387 AutoCompleteMoveToCurrentWord();
391 void ScintillaBase::AutoCompleteCharacterDeleted() {
392 if (sel.MainCaret() < ac.posStart - ac.startLen) {
393 AutoCompleteCancel();
394 } else if (ac.cancelAtStartPos && (sel.MainCaret() <= ac.posStart)) {
395 AutoCompleteCancel();
396 } else {
397 AutoCompleteMoveToCurrentWord();
399 NotificationData scn = {};
400 scn.nmhdr.code = Notification::AutoCCharDeleted;
401 scn.wParam = 0;
402 scn.listType = 0;
403 NotifyParent(scn);
406 void ScintillaBase::AutoCompleteNotifyCompleted(char ch, CompletionMethods completionMethod, Sci::Position firstPos, const char *text) {
407 NotificationData scn = {};
408 scn.nmhdr.code = Notification::AutoCCompleted;
409 scn.message = static_cast<Message>(0);
410 scn.ch = ch;
411 scn.listCompletionMethod = completionMethod;
412 scn.wParam = listType;
413 scn.listType = listType;
414 scn.position = firstPos;
415 scn.lParam = firstPos;
416 scn.text = text;
417 NotifyParent(scn);
420 void ScintillaBase::AutoCompleteCompleted(char ch, CompletionMethods completionMethod) {
421 const int item = ac.GetSelection();
422 if (item == -1) {
423 AutoCompleteCancel();
424 return;
426 const std::string selected = ac.GetValue(item);
428 ac.Show(false);
430 NotificationData scn = {};
431 scn.nmhdr.code = listType > 0 ? Notification::UserListSelection : Notification::AutoCSelection;
432 scn.message = static_cast<Message>(0);
433 scn.ch = ch;
434 scn.listCompletionMethod = completionMethod;
435 scn.wParam = listType;
436 scn.listType = listType;
437 const Sci::Position firstPos = ac.posStart - ac.startLen;
438 scn.position = firstPos;
439 scn.lParam = firstPos;
440 scn.text = selected.c_str();
441 NotifyParent(scn);
443 if (!ac.Active())
444 return;
445 ac.Cancel();
447 if (listType > 0)
448 return;
450 Sci::Position endPos = sel.MainCaret();
451 if (ac.dropRestOfWord)
452 endPos = pdoc->ExtendWordSelect(endPos, 1, true);
453 if (endPos < firstPos)
454 return;
455 AutoCompleteInsert(firstPos, endPos - firstPos, selected);
456 SetLastXChosen();
458 AutoCompleteNotifyCompleted(ch, completionMethod, firstPos, selected.c_str());
461 int ScintillaBase::AutoCompleteGetCurrent() const {
462 if (!ac.Active())
463 return -1;
464 return ac.GetSelection();
467 int ScintillaBase::AutoCompleteGetCurrentText(char *buffer) const {
468 if (ac.Active()) {
469 const int item = ac.GetSelection();
470 if (item != -1) {
471 const std::string selected = ac.GetValue(item);
472 if (buffer)
473 memcpy(buffer, selected.c_str(), selected.length()+1);
474 return static_cast<int>(selected.length());
477 if (buffer)
478 *buffer = '\0';
479 return 0;
482 void ScintillaBase::CallTipShow(Point pt, const char *defn) {
483 ac.Cancel();
484 // If container knows about StyleCallTip then use it in place of the
485 // StyleDefault for the face name, size and character set. Also use it
486 // for the foreground and background colour.
487 const int ctStyle = ct.UseStyleCallTip() ? StyleCallTip : StyleDefault;
488 const Style &style = vs.styles[ctStyle];
489 if (ct.UseStyleCallTip()) {
490 ct.SetForeBack(style.fore, style.back);
492 if (wMargin.Created()) {
493 pt = pt + GetVisibleOriginInMain();
495 AutoSurface surfaceMeasure(this);
496 PRectangle rc = ct.CallTipStart(sel.MainCaret(), pt,
497 vs.lineHeight,
498 defn,
499 CodePage(),
500 surfaceMeasure,
501 style.font);
502 // If the call-tip window would be out of the client
503 // space
504 const PRectangle rcClient = GetClientRectangle();
505 const int offset = vs.lineHeight + static_cast<int>(rc.Height());
506 // adjust so it displays above the text.
507 if (rc.bottom > rcClient.bottom && rc.Height() < rcClient.Height()) {
508 rc.top -= offset;
509 rc.bottom -= offset;
511 // adjust so it displays below the text.
512 if (rc.top < rcClient.top && rc.Height() < rcClient.Height()) {
513 rc.top += offset;
514 rc.bottom += offset;
516 // Now display the window.
517 CreateCallTipWindow(rc);
518 ct.wCallTip.SetPositionRelative(rc, &wMain);
519 ct.wCallTip.Show();
520 ct.wCallTip.InvalidateAll();
523 void ScintillaBase::CallTipClick() {
524 NotificationData scn = {};
525 scn.nmhdr.code = Notification::CallTipClick;
526 scn.position = ct.clickPlace;
527 NotifyParent(scn);
530 bool ScintillaBase::ShouldDisplayPopup(Point ptInWindowCoordinates) const {
531 return (displayPopupMenu == PopUp::All ||
532 (displayPopupMenu == PopUp::Text && !PointInSelMargin(ptInWindowCoordinates)));
535 void ScintillaBase::ContextMenu(Point pt) {
536 if (displayPopupMenu != PopUp::Never) {
537 const bool writable = !WndProc(Message::GetReadOnly, 0, 0);
538 popup.CreatePopUp();
539 AddToPopUp("Undo", idcmdUndo, writable && pdoc->CanUndo());
540 AddToPopUp("Redo", idcmdRedo, writable && pdoc->CanRedo());
541 AddToPopUp("");
542 AddToPopUp("Cut", idcmdCut, writable && !sel.Empty());
543 AddToPopUp("Copy", idcmdCopy, !sel.Empty());
544 AddToPopUp("Paste", idcmdPaste, writable && WndProc(Message::CanPaste, 0, 0));
545 AddToPopUp("Delete", idcmdDelete, writable && !sel.Empty());
546 AddToPopUp("");
547 AddToPopUp("Select All", idcmdSelectAll);
548 popup.Show(pt, wMain);
552 void ScintillaBase::CancelModes() {
553 AutoCompleteCancel();
554 ct.CallTipCancel();
555 Editor::CancelModes();
558 void ScintillaBase::ButtonDownWithModifiers(Point pt, unsigned int curTime, KeyMod modifiers) {
559 CancelModes();
560 Editor::ButtonDownWithModifiers(pt, curTime, modifiers);
563 void ScintillaBase::RightButtonDownWithModifiers(Point pt, unsigned int curTime, KeyMod modifiers) {
564 CancelModes();
565 Editor::RightButtonDownWithModifiers(pt, curTime, modifiers);
568 namespace Scintilla::Internal {
570 class LexState : public LexInterface {
571 public:
572 explicit LexState(Document *pdoc_) noexcept;
574 // LexInterface deleted the standard operators and defined the virtual destructor so don't need to here.
576 const char *DescribeWordListSets();
577 void SetWordList(int n, const char *wl);
578 int GetIdentifier() const;
579 const char *GetName() const;
580 void *PrivateCall(int operation, void *pointer);
581 const char *PropertyNames();
582 TypeProperty PropertyType(const char *name);
583 const char *DescribeProperty(const char *name);
584 void PropSet(const char *key, const char *val);
585 const char *PropGet(const char *key) const;
586 int PropGetInt(const char *key, int defaultValue=0) const;
588 LineEndType LineEndTypesSupported() override;
589 int AllocateSubStyles(int styleBase, int numberStyles);
590 int SubStylesStart(int styleBase);
591 int SubStylesLength(int styleBase);
592 int StyleFromSubStyle(int subStyle);
593 int PrimaryStyleFromStyle(int style);
594 void FreeSubStyles();
595 void SetIdentifiers(int style, const char *identifiers);
596 int DistanceToSecondaryStyles();
597 const char *GetSubStyleBases();
598 int NamedStyles();
599 const char *NameOfStyle(int style);
600 const char *TagsOfStyle(int style);
601 const char *DescriptionOfStyle(int style);
606 LexState::LexState(Document *pdoc_) noexcept : LexInterface(pdoc_) {
609 LexState *ScintillaBase::DocumentLexState() {
610 if (!pdoc->GetLexInterface()) {
611 pdoc->SetLexInterface(std::make_unique<LexState>(pdoc));
613 return dynamic_cast<LexState *>(pdoc->GetLexInterface());
616 const char *LexState::DescribeWordListSets() {
617 if (instance) {
618 return instance->DescribeWordListSets();
619 } else {
620 return nullptr;
624 void LexState::SetWordList(int n, const char *wl) {
625 if (instance) {
626 const Sci_Position firstModification = instance->WordListSet(n, wl);
627 if (firstModification >= 0) {
628 pdoc->ModifiedAt(firstModification);
633 int LexState::GetIdentifier() const {
634 if (instance) {
635 return instance->GetIdentifier();
637 return 0;
640 const char *LexState::GetName() const {
641 if (instance) {
642 return instance->GetName();
644 return "";
647 void *LexState::PrivateCall(int operation, void *pointer) {
648 if (instance) {
649 return instance->PrivateCall(operation, pointer);
650 } else {
651 return nullptr;
655 const char *LexState::PropertyNames() {
656 if (instance) {
657 return instance->PropertyNames();
658 } else {
659 return nullptr;
663 TypeProperty LexState::PropertyType(const char *name) {
664 if (instance) {
665 return static_cast<TypeProperty>(instance->PropertyType(name));
666 } else {
667 return TypeProperty::Boolean;
671 const char *LexState::DescribeProperty(const char *name) {
672 if (instance) {
673 return instance->DescribeProperty(name);
674 } else {
675 return nullptr;
679 void LexState::PropSet(const char *key, const char *val) {
680 if (instance) {
681 const Sci_Position firstModification = instance->PropertySet(key, val);
682 if (firstModification >= 0) {
683 pdoc->ModifiedAt(firstModification);
688 const char *LexState::PropGet(const char *key) const {
689 if (instance) {
690 return instance->PropertyGet(key);
691 } else {
692 return nullptr;
696 int LexState::PropGetInt(const char *key, int defaultValue) const {
697 if (instance) {
698 const char *value = instance->PropertyGet(key);
699 if (value && *value) {
700 return atoi(value);
703 return defaultValue;
706 LineEndType LexState::LineEndTypesSupported() {
707 if (instance) {
708 return static_cast<LineEndType>(instance->LineEndTypesSupported());
710 return LineEndType::Default;
713 int LexState::AllocateSubStyles(int styleBase, int numberStyles) {
714 if (instance) {
715 return instance->AllocateSubStyles(styleBase, numberStyles);
717 return -1;
720 int LexState::SubStylesStart(int styleBase) {
721 if (instance) {
722 return instance->SubStylesStart(styleBase);
724 return -1;
727 int LexState::SubStylesLength(int styleBase) {
728 if (instance) {
729 return instance->SubStylesLength(styleBase);
731 return 0;
734 int LexState::StyleFromSubStyle(int subStyle) {
735 if (instance) {
736 return instance->StyleFromSubStyle(subStyle);
738 return 0;
741 int LexState::PrimaryStyleFromStyle(int style) {
742 if (instance) {
743 return instance->PrimaryStyleFromStyle(style);
745 return 0;
748 void LexState::FreeSubStyles() {
749 if (instance) {
750 instance->FreeSubStyles();
754 void LexState::SetIdentifiers(int style, const char *identifiers) {
755 if (instance) {
756 instance->SetIdentifiers(style, identifiers);
757 pdoc->ModifiedAt(0);
761 int LexState::DistanceToSecondaryStyles() {
762 if (instance) {
763 return instance->DistanceToSecondaryStyles();
765 return 0;
768 const char *LexState::GetSubStyleBases() {
769 if (instance) {
770 return instance->GetSubStyleBases();
772 return "";
775 int LexState::NamedStyles() {
776 if (instance) {
777 return instance->NamedStyles();
778 } else {
779 return -1;
783 const char *LexState::NameOfStyle(int style) {
784 if (instance) {
785 return instance->NameOfStyle(style);
786 } else {
787 return nullptr;
791 const char *LexState::TagsOfStyle(int style) {
792 if (instance) {
793 return instance->TagsOfStyle(style);
794 } else {
795 return nullptr;
799 const char *LexState::DescriptionOfStyle(int style) {
800 if (instance) {
801 return instance->DescriptionOfStyle(style);
802 } else {
803 return nullptr;
807 void ScintillaBase::NotifyStyleToNeeded(Sci::Position endStyleNeeded) {
808 if (!DocumentLexState()->UseContainerLexing()) {
809 const Sci::Position endStyled = pdoc->LineStartPosition(pdoc->GetEndStyled());
810 DocumentLexState()->Colourise(endStyled, endStyleNeeded);
811 return;
813 Editor::NotifyStyleToNeeded(endStyleNeeded);
816 sptr_t ScintillaBase::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
817 switch (iMessage) {
818 case Message::AutoCShow:
819 listType = 0;
820 AutoCompleteStart(PositionFromUPtr(wParam), ConstCharPtrFromSPtr(lParam));
821 break;
823 case Message::AutoCCancel:
824 ac.Cancel();
825 break;
827 case Message::AutoCActive:
828 return ac.Active();
830 case Message::AutoCPosStart:
831 return ac.posStart;
833 case Message::AutoCComplete:
834 AutoCompleteCompleted(0, CompletionMethods::Command);
835 break;
837 case Message::AutoCSetSeparator:
838 ac.SetSeparator(static_cast<char>(wParam));
839 break;
841 case Message::AutoCGetSeparator:
842 return ac.GetSeparator();
844 case Message::AutoCStops:
845 ac.SetStopChars(ConstCharPtrFromSPtr(lParam));
846 break;
848 case Message::AutoCSelect:
849 ac.Select(ConstCharPtrFromSPtr(lParam));
850 break;
852 case Message::AutoCGetCurrent:
853 return AutoCompleteGetCurrent();
855 case Message::AutoCGetCurrentText:
856 return AutoCompleteGetCurrentText(CharPtrFromSPtr(lParam));
858 case Message::AutoCSetCancelAtStart:
859 ac.cancelAtStartPos = wParam != 0;
860 break;
862 case Message::AutoCGetCancelAtStart:
863 return ac.cancelAtStartPos;
865 case Message::AutoCSetFillUps:
866 ac.SetFillUpChars(ConstCharPtrFromSPtr(lParam));
867 break;
869 case Message::AutoCSetChooseSingle:
870 ac.chooseSingle = wParam != 0;
871 break;
873 case Message::AutoCGetChooseSingle:
874 return ac.chooseSingle;
876 case Message::AutoCSetIgnoreCase:
877 ac.ignoreCase = wParam != 0;
878 break;
880 case Message::AutoCGetIgnoreCase:
881 return ac.ignoreCase;
883 case Message::AutoCSetCaseInsensitiveBehaviour:
884 ac.ignoreCaseBehaviour = static_cast<CaseInsensitiveBehaviour>(wParam);
885 break;
887 case Message::AutoCGetCaseInsensitiveBehaviour:
888 return static_cast<sptr_t>(ac.ignoreCaseBehaviour);
890 case Message::AutoCSetMulti:
891 multiAutoCMode = static_cast<MultiAutoComplete>(wParam);
892 break;
894 case Message::AutoCGetMulti:
895 return static_cast<sptr_t>(multiAutoCMode);
897 case Message::AutoCSetOrder:
898 ac.autoSort = static_cast<Ordering>(wParam);
899 break;
901 case Message::AutoCGetOrder:
902 return static_cast<sptr_t>(ac.autoSort);
904 case Message::UserListShow:
905 listType = static_cast<int>(wParam);
906 AutoCompleteStart(0, ConstCharPtrFromSPtr(lParam));
907 break;
909 case Message::AutoCSetAutoHide:
910 ac.autoHide = wParam != 0;
911 break;
913 case Message::AutoCGetAutoHide:
914 return ac.autoHide;
916 case Message::AutoCSetOptions:
917 ac.options = static_cast<AutoCompleteOption>(wParam);
918 break;
920 case Message::AutoCGetOptions:
921 return static_cast<sptr_t>(ac.options);
923 case Message::AutoCSetDropRestOfWord:
924 ac.dropRestOfWord = wParam != 0;
925 break;
927 case Message::AutoCGetDropRestOfWord:
928 return ac.dropRestOfWord;
930 case Message::AutoCSetMaxHeight:
931 ac.lb->SetVisibleRows(static_cast<int>(wParam));
932 break;
934 case Message::AutoCGetMaxHeight:
935 return ac.lb->GetVisibleRows();
937 case Message::AutoCSetMaxWidth:
938 maxListWidth = static_cast<int>(wParam);
939 break;
941 case Message::AutoCGetMaxWidth:
942 return maxListWidth;
944 case Message::RegisterImage:
945 ac.lb->RegisterImage(static_cast<int>(wParam), ConstCharPtrFromSPtr(lParam));
946 break;
948 case Message::RegisterRGBAImage:
949 ac.lb->RegisterRGBAImage(static_cast<int>(wParam), static_cast<int>(sizeRGBAImage.x), static_cast<int>(sizeRGBAImage.y),
950 ConstUCharPtrFromSPtr(lParam));
951 break;
953 case Message::ClearRegisteredImages:
954 ac.lb->ClearRegisteredImages();
955 break;
957 case Message::AutoCSetTypeSeparator:
958 ac.SetTypesep(static_cast<char>(wParam));
959 break;
961 case Message::AutoCGetTypeSeparator:
962 return ac.GetTypesep();
964 case Message::CallTipShow:
965 CallTipShow(LocationFromPosition(wParam),
966 ConstCharPtrFromSPtr(lParam));
967 break;
969 case Message::CallTipCancel:
970 ct.CallTipCancel();
971 break;
973 case Message::CallTipActive:
974 return ct.inCallTipMode;
976 case Message::CallTipPosStart:
977 return ct.posStartCallTip;
979 case Message::CallTipSetPosStart:
980 ct.posStartCallTip = wParam;
981 break;
983 case Message::CallTipSetHlt:
984 ct.SetHighlight(wParam, lParam);
985 break;
987 case Message::CallTipSetBack:
988 ct.colourBG = ColourRGBA::FromIpRGB(SPtrFromUPtr(wParam));
989 vs.styles[StyleCallTip].back = ct.colourBG;
990 InvalidateStyleRedraw();
991 break;
993 case Message::CallTipSetFore:
994 ct.colourUnSel = ColourRGBA::FromIpRGB(SPtrFromUPtr(wParam));
995 vs.styles[StyleCallTip].fore = ct.colourUnSel;
996 InvalidateStyleRedraw();
997 break;
999 case Message::CallTipSetForeHlt:
1000 ct.colourSel = ColourRGBA::FromIpRGB(SPtrFromUPtr(wParam));
1001 InvalidateStyleRedraw();
1002 break;
1004 case Message::CallTipUseStyle:
1005 ct.SetTabSize(static_cast<int>(wParam));
1006 InvalidateStyleRedraw();
1007 break;
1009 case Message::CallTipSetPosition:
1010 ct.SetPosition(wParam != 0);
1011 InvalidateStyleRedraw();
1012 break;
1014 case Message::UsePopUp:
1015 displayPopupMenu = static_cast<PopUp>(wParam);
1016 break;
1018 case Message::GetLexer:
1019 return DocumentLexState()->GetIdentifier();
1021 case Message::SetILexer:
1022 DocumentLexState()->SetInstance(static_cast<ILexer5 *>(PtrFromSPtr(lParam)));
1023 return 0;
1025 case Message::Colourise:
1026 if (DocumentLexState()->UseContainerLexing()) {
1027 pdoc->ModifiedAt(PositionFromUPtr(wParam));
1028 NotifyStyleToNeeded((lParam == -1) ? pdoc->Length() : lParam);
1029 } else {
1030 DocumentLexState()->Colourise(PositionFromUPtr(wParam), lParam);
1032 Redraw();
1033 break;
1035 case Message::SetProperty:
1036 DocumentLexState()->PropSet(ConstCharPtrFromUPtr(wParam),
1037 ConstCharPtrFromSPtr(lParam));
1038 break;
1040 case Message::GetProperty:
1041 return StringResult(lParam, DocumentLexState()->PropGet(ConstCharPtrFromUPtr(wParam)));
1043 case Message::GetPropertyExpanded:
1044 return StringResult(lParam, DocumentLexState()->PropGet(ConstCharPtrFromUPtr(wParam)));
1046 case Message::GetPropertyInt:
1047 return DocumentLexState()->PropGetInt(ConstCharPtrFromUPtr(wParam), static_cast<int>(lParam));
1049 case Message::SetKeyWords:
1050 DocumentLexState()->SetWordList(static_cast<int>(wParam), ConstCharPtrFromSPtr(lParam));
1051 break;
1053 case Message::GetLexerLanguage:
1054 return StringResult(lParam, DocumentLexState()->GetName());
1056 case Message::PrivateLexerCall:
1057 return reinterpret_cast<sptr_t>(
1058 DocumentLexState()->PrivateCall(static_cast<int>(wParam), PtrFromSPtr(lParam)));
1060 #ifdef INCLUDE_DEPRECATED_FEATURES
1061 case SCI_GETSTYLEBITSNEEDED:
1062 return 8;
1063 #endif
1065 case Message::PropertyNames:
1066 return StringResult(lParam, DocumentLexState()->PropertyNames());
1068 case Message::PropertyType:
1069 return static_cast<sptr_t>(DocumentLexState()->PropertyType(ConstCharPtrFromUPtr(wParam)));
1071 case Message::DescribeProperty:
1072 return StringResult(lParam,
1073 DocumentLexState()->DescribeProperty(ConstCharPtrFromUPtr(wParam)));
1075 case Message::DescribeKeyWordSets:
1076 return StringResult(lParam, DocumentLexState()->DescribeWordListSets());
1078 case Message::GetLineEndTypesSupported:
1079 return static_cast<sptr_t>(DocumentLexState()->LineEndTypesSupported());
1081 case Message::AllocateSubStyles:
1082 return DocumentLexState()->AllocateSubStyles(static_cast<int>(wParam), static_cast<int>(lParam));
1084 case Message::GetSubStylesStart:
1085 return DocumentLexState()->SubStylesStart(static_cast<int>(wParam));
1087 case Message::GetSubStylesLength:
1088 return DocumentLexState()->SubStylesLength(static_cast<int>(wParam));
1090 case Message::GetStyleFromSubStyle:
1091 return DocumentLexState()->StyleFromSubStyle(static_cast<int>(wParam));
1093 case Message::GetPrimaryStyleFromStyle:
1094 return DocumentLexState()->PrimaryStyleFromStyle(static_cast<int>(wParam));
1096 case Message::FreeSubStyles:
1097 DocumentLexState()->FreeSubStyles();
1098 break;
1100 case Message::SetIdentifiers:
1101 DocumentLexState()->SetIdentifiers(static_cast<int>(wParam),
1102 ConstCharPtrFromSPtr(lParam));
1103 break;
1105 case Message::DistanceToSecondaryStyles:
1106 return DocumentLexState()->DistanceToSecondaryStyles();
1108 case Message::GetSubStyleBases:
1109 return StringResult(lParam, DocumentLexState()->GetSubStyleBases());
1111 case Message::GetNamedStyles:
1112 return DocumentLexState()->NamedStyles();
1114 case Message::NameOfStyle:
1115 return StringResult(lParam, DocumentLexState()->
1116 NameOfStyle(static_cast<int>(wParam)));
1118 case Message::TagsOfStyle:
1119 return StringResult(lParam, DocumentLexState()->
1120 TagsOfStyle(static_cast<int>(wParam)));
1122 case Message::DescriptionOfStyle:
1123 return StringResult(lParam, DocumentLexState()->
1124 DescriptionOfStyle(static_cast<int>(wParam)));
1126 default:
1127 return Editor::WndProc(iMessage, wParam, lParam);
1129 return 0;