File: cl_editor.h

package info (click to toggle)
codelite 17.0.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 136,204 kB
  • sloc: cpp: 491,547; ansic: 280,393; php: 10,259; sh: 8,930; lisp: 7,664; vhdl: 6,518; python: 6,020; lex: 4,920; yacc: 3,123; perl: 2,385; javascript: 1,715; cs: 1,193; xml: 1,110; makefile: 804; cobol: 741; sql: 709; ruby: 620; f90: 566; ada: 534; asm: 464; fortran: 350; objc: 289; tcl: 258; java: 157; erlang: 61; pascal: 51; ml: 49; awk: 44; haskell: 36
file content (1197 lines) | stat: -rw-r--r-- 41,672 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//
// copyright            : (C) 2008 by Eran Ifrah
// file name            : cl_editor.h
//
// -------------------------------------------------------------------------
// A
//              _____           _      _     _ _
//             /  __ \         | |    | |   (_) |
//             | /  \/ ___   __| | ___| |    _| |_ ___
//             | |    / _ \ / _  |/ _ \ |   | | __/ _ )
//             | \__/\ (_) | (_| |  __/ |___| | ||  __/
//              \____/\___/ \__,_|\___\_____/_|\__\___|
//
//                                                  F i l e
//
//    This program is free software; you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation; either version 2 of the License, or
//    (at your option) any later version.
//
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
#ifndef LITEEDITOR_EDITOR_H
#define LITEEDITOR_EDITOR_H

#include "LSP/CompletionItem.h"
#include "SFTPClientData.hpp"
#include "bookmark_manager.h"
#include "browse_record.h"
#include "clEditorStateLocker.h"
#include "cl_calltip.h"
#include "cl_defs.h"
#include "cl_unredo.h"
#include "context_base.h"
#include "debuggermanager.h"
#include "entry.h"
#include "findreplacedlg.h"
#include "globals.h"
#include "navigationmanager.h"
#include "plugin.h"
#include "stringhighlighterjob.h"
#include "wx/filename.h"
#include "wx/menu.h"

#include <map>
#include <stack>
#include <vector>
#include <wx/bitmap.h>
#include <wx/cmndata.h>
#include <wx/stc/stc.h>

#define DEBUGGER_INDICATOR 11
#define MATCH_INDICATOR 10
#define MARKER_WORD_HIGHLIGHT 2
#define USER_INDICATOR 3
#define HYPERLINK_INDICATOR 4
#define MARKER_FIND_BAR_WORD_HIGHLIGHT 5
#define MARKER_CONTEXT_WORD_HIGHLIGHT 6

#if(wxVERSION_NUMBER < 3101)
// Some wxSTC keycodes names were altered in 311, & the old versions deprecated
// So, to avoid deprecation-warning spam, #define for older versions
#define wxSTC_KEYMOD_NORM wxSTC_SCMOD_NORM
#define wxSTC_KEYMOD_SHIFT wxSTC_SCMOD_SHIFT
#define wxSTC_KEYMOD_CTRL wxSTC_SCMOD_CTRL
#define wxSTC_KEYMOD_ALT wxSTC_SCMOD_ALT
#define wxSTC_KEYMOD_SUPER wxSTC_SCMOD_SUPER
#define wxSTC_KEYMOD_META wxSTC_SCMOD_META
#endif

class wxRichToolTip;
class CCBoxTipWindow;
class IManager;
class wxFindReplaceDialog;
class CCBox;
class clEditorTipWindow;
class DisplayVariableDlg;
class EditorDeltasHolder;

enum sci_annotation_styles { eAnnotationStyleError = 128, eAnnotationStyleWarning };

/**************** NB: enum sci_marker_types has now moved to bookmark_manager.h ****************/

/**
 * @class BPtoMarker
 * Holds which marker and mask are associated with each breakpoint type
 */
typedef struct _BPtoMarker {
    enum BreakpointType bp_type; // An enum of possible break/watchpoint types. In debugger.h
    sci_marker_types marker;
    marker_mask_type mask;
    sci_marker_types marker_disabled;
    marker_mask_type mask_disabled;
} BPtoMarker;

wxDECLARE_EVENT(wxCMD_EVENT_REMOVE_MATCH_INDICATOR, wxCommandEvent);
wxDECLARE_EVENT(wxCMD_EVENT_ENABLE_WORD_HIGHLIGHT, wxCommandEvent);

/**
 * \ingroup LiteEditor
 * clEditor CodeLite editing component based on Scintilla
 * clEditor provides most of the C++/C editing capablities including:
 * -# Auto Completion
 * -# Find and replace
 * -# Bookmarks
 * -# Folding
 * -# Find definition of a symbol
 * and many many more
 *
 * \version 1.0
 * first version
 *
 * \date 04-21-2007
 *
 * \author Eran
 *
 */
class clEditor : public wxStyledTextCtrl, public IEditor
{
private:
    struct SelectionInfo {
        std::vector<std::pair<int, int>> selections;

        SelectionInfo() {}

        /**
         * @brief add selection range
         * @param from selection start position
         * @param to selectio end position
         */
        void AddSelection(int from, int to) { this->selections.push_back(std::make_pair(from, to)); }

        /**
         * @brief return the number of selections
         */
        size_t GetCount() const { return this->selections.size(); }

        /**
         * @brief return the selection at position i
         * @param from
         * @param to
         */
        void At(size_t i, int& from, int& to) const
        {
            const std::pair<int, int>& pair = this->selections.at(i);
            from = pair.first;
            to = pair.second;
        }

        /**
         * @brief clear the selection info
         */
        void Clear() { this->selections.clear(); }

        /**
         * @brief is this object OK?
         */
        bool IsOk() const { return !this->selections.empty(); }

        /**
         * @brief sort the selections from top to bottom
         */
        void Sort();
    };

    struct MarkWordInfo {
    private:
        bool m_hasMarkers;
        int m_firstOffset;
        wxString m_word;

    public:
        MarkWordInfo()
            : m_hasMarkers(false)
            , m_firstOffset(wxNOT_FOUND)
        {
        }

        void Clear()
        {
            m_hasMarkers = false;
            m_firstOffset = wxNOT_FOUND;
            m_word.Clear();
        }

        bool IsValid(wxStyledTextCtrl* ctrl) const
        {
            return ctrl->PositionFromLine(ctrl->GetFirstVisibleLine()) == m_firstOffset && m_hasMarkers;
        }

        // setters/getters
        void SetFirstOffset(int firstOffset) { this->m_firstOffset = firstOffset; }
        void SetHasMarkers(bool hasMarkers) { this->m_hasMarkers = hasMarkers; }
        void SetWord(const wxString& word) { this->m_word = word; }
        int GetFirstOffset() const { return m_firstOffset; }
        bool IsHasMarkers() const { return m_hasMarkers; }
        const wxString& GetWord() const { return m_word; }
    };

    enum eStatusBarFields {
        kShowLine = (1 << 0),
        kShowColumn = (1 << 1),
        kShowPosition = (1 << 2),
        kShowLen = (1 << 3),
        kShowSelectedChars = (1 << 4),
    };

    enum eLineStatus : short {
        LINE_NONE,
        LINE_MODIFIED,
        LINE_SAVED,
    };

protected:
    wxFileName m_fileName;
    wxString m_project;
    wxStopWatch m_watch;
    ContextBasePtr m_context;
    EditorDeltasHolder* m_deltas; // Holds any text position changes, in case they affect FindinFiles results
    std::vector<wxMenuItem*> m_dynItems;
    std::vector<BPtoMarker> m_BPstoMarkers;
    static FindReplaceDialog* m_findReplaceDlg;
    static FindReplaceData m_findReplaceData;
    int m_lastMatchPos;
    static std::map<wxString, int> ms_bookmarkShapes;
    bool m_popupIsOn;
    bool m_isDragging;
    time_t m_modifyTime;
    wxUint64 m_modificationCount;
    std::map<int, wxString> m_customCmds;
    bool m_isVisible;
    int m_hyperLinkIndicatroStart;
    int m_hyperLinkIndicatroEnd;
    bool m_hightlightMatchedBraces;
    bool m_autoAddMatchedCurlyBrace;
    bool m_autoAddNormalBraces;
    bool m_smartParen = true;
    std::map<int, std::vector<clDebuggerBreakpoint>> m_breakpointsInfo;
    bool m_autoAdjustHScrollbarWidth;
    bool m_reloadingFile;
    bool m_disableSmartIndent;
    bool m_disableSemicolonShift;
    clEditorTipWindow* m_functionTip;
    CCBoxTipWindow* m_calltip;
    wxChar m_lastCharEntered;
    int m_lastCharEnteredPos;
    bool m_isFocused;
    bool m_pluginInitializedRMenu;
    BOM m_fileBom;
    int m_positionToEnsureVisible;
    bool m_preserveSelection;
    std::vector<std::pair<int, int>> m_savedMarkers;
    bool m_findBookmarksActive;
    std::map<int, wxString> m_compilerMessagesMap;
    CLCommandProcessor m_commandsProcessor;
    wxString m_preProcessorsWords;
    SelectionInfo m_prevSelectionInfo;
    MarkWordInfo m_highlightedWordInfo;
    wxTimer* m_timerHighlightMarkers;
    IManager* m_mgr;
    OptionsConfigPtr m_options;
    bool m_hasCCAnnotation;
    wxRichToolTip* m_richTooltip;
    wxString m_keywordClasses;
    wxString m_keywordMethods;
    wxString m_keywordOthers;
    wxString m_keywordLocals;
    int m_editorBitmap = wxNOT_FOUND;
    size_t m_statusBarFields;
    int m_lastBeginLine = wxNOT_FOUND;
    int m_lastLine = wxNOT_FOUND;
    int m_lastEndLine;
    int m_lastLineCount;
    wxColour m_selTextColour;
    wxColour m_selTextBgColour;
    bool m_zoomProgrammatically = false;
    std::vector<eLineStatus> m_modifiedLines;
    bool m_trackChanges = false;
    std::unordered_map<int, wxString> m_breakpoints_tooltips;
    size_t m_default_text_width = wxNOT_FOUND;
    bool m_scrollbar_recalc_is_required = false;

public:
    static bool m_ccShowPrivateMembers;
    static bool m_ccShowItemsComments;
    static bool m_ccInitialized;

    typedef std::vector<clEditor*> Vec_t;

    IManager* GetManager() { return m_mgr; }

    /**
     * @brief CodeLite preferences updated
     */
    void PreferencesChanged();
    /**
     * @brief are the CC annotations visible?
     */
    bool IsHasCCAnnotation() const { return m_hasCCAnnotation; }
    void ClearCCAnnotations();

    void SetEditorBitmap(int editorBitmap) { this->m_editorBitmap = editorBitmap; }
    int GetEditorBitmap() const { return m_editorBitmap; }

    void NotifyMarkerChanged(int lineNumber = wxNOT_FOUND);

    /**
     * @brief static version of the below `CenterLine`
     * so we can use it outside of this class, e.g. from `QuickFindBar`
     */
    static void CenterLine(wxStyledTextCtrl* ctrl, int line, int col);

    /**
     * @brief static version
     */
    static void CenterLinePreserveSelection(wxStyledTextCtrl* ctrl, int line);

    /**
     * @brief static version of the below
     */
    static void SetCaretAt(wxStyledTextCtrl* ctrl, long pos);

    /**
     * @brief wrapper calling CenterLinePreserveSelection using CallAfter()
     */
    void CenterLinePreserveSelectionAfter(int line);

public:
    static FindReplaceData& GetFindReplaceData() { return m_findReplaceData; }

    void SetPreProcessorsWords(const wxString& preProcessorsWords) { this->m_preProcessorsWords = preProcessorsWords; }
    const wxString& GetPreProcessorsWords() const { return m_preProcessorsWords; }
    void SetLineVisible(int lineno);

    void SetReloadingFile(const bool& reloadingFile) { this->m_reloadingFile = reloadingFile; }
    const bool& GetReloadingFile() const { return m_reloadingFile; }

    clEditorTipWindow* GetFunctionTip() { return m_functionTip; }

    bool IsFocused() const;
    CLCommandProcessor& GetCommandsProcessor() { return m_commandsProcessor; }

public:
    /// Construct a clEditor object
    clEditor(wxWindow* parent);

    /// Default destructor
    virtual ~clEditor();

    // Save the editor data into file
    virtual bool SaveFile();

    // Save content of the editor to a given file (Save As...)
    // this function prompts the user for selecting file name
    bool SaveFileAs(const wxString& newname = wxEmptyString, const wxString& savePath = wxEmptyString);

    /**
     * @brief print the editor content using the printing framework
     */
    void Print();

    /**
     * @brief setup the print page
     */
    void PageSetup();

    const wxString& GetKeywordClasses() const override { return m_keywordClasses; }
    const wxString& GetKeywordLocals() const override { return m_keywordLocals; }
    const wxString& GetKeywordMethods() const override { return m_keywordMethods; }
    const wxString& GetKeywordOthers() const override { return m_keywordOthers; }

    // used by other plugins
    void SetKeywordClasses(const wxString& keywords) { this->m_keywordClasses = keywords; }
    void SetKeywordLocals(const wxString& keywords) { this->m_keywordLocals = keywords; }
    void SetKeywordMethods(const wxString& keywords) { this->m_keywordMethods = keywords; }
    void SetKeywordOthers(const wxString& keywords) { this->m_keywordOthers = keywords; }

    /**
     * @brief set semantic tokens for this editor
     */
    void SetSemanticTokens(const wxString& classes, const wxString& variables, const wxString& methods,
                           const wxString& others) override;

    /**
     * @brief split the current selection into multiple carets.
     * i.e. place a caret at the end of each line in the selection
     */
    void SplitSelection();

    void SetDisableSmartIndent(bool disableSmartIndent) { this->m_disableSmartIndent = disableSmartIndent; }

    bool GetDisableSmartIndent() const { return m_disableSmartIndent; }
    /**
     * @brief set the EOL mode of the file by applying this logic:
     * - if the file has content, use the current cotext EOL
     * - if the file is empty and the EOL mode is set to Default, make it EOL of the hosting OS
     * - Use the setting provided by the user
     */
    void SetEOL();

    void CompleteWord(LSP::CompletionItem::eTriggerKind triggerKind, bool onlyRefresh = false);

    /**
     * @brief chage the case of the current selection. If selection is empty,
     * change the selection of the character to the right of the cart. In case of changing
     * the char to the right, move the caret to the right as well.
     * @param toLower change to lower case.
     */
    void ChangeCase(bool toLower);

    // set this editor file name
    void SetFileName(const wxFileName& name) { m_fileName = name; }

    // Return the project name
    const wxString& GetProject() const { return m_project; }
    // Set the project name
    void SetProject(const wxString& proj) { m_project = proj; }

    /**
     * @brief attempt to code complete the expression up until the caret position
     * @param refreshingList when set to true, it means that the 'CodeComplete' was invoked
     * by the code completion box itself in attempt to request new items for the list
     * This feature is only supported internally for C++ and is not exposed to plugins
     * i.e. the event wxEVT_CC_CODE_COMPLETE is fired only when refreshingList == false
     */
    void CodeComplete(bool refreshingList = false);

    /**
     * @brief toggle line comment
     * @param commentSymbol the comment symbol to insert (e.g. "//")
     * @param commentStyle the wxSTC line comment style
     */
    void ToggleLineComment(const wxString& commentSymbol, int commentStyle) override;

    /**
     * @brief block comment the selection
     */
    void CommentBlockSelection(const wxString& commentBlockStart, const wxString& commentBlockEnd) override;

    /**
     * @brief is this editor modified?
     */
    bool IsEditorModified() const override { return GetModify(); }

    // User clicked Ctrl+.
    void GotoDefinition();
    /**
     * find declaration file for the current expression
     */
    void FindDeclarationFile();

    // return the EOL according to the content
    int GetEOLByContent();

    int GetEOLByOS();
    /**
     * Return true if editor definition contains more
     * on its stack
     */
    bool CanGotoPreviousDefintion() { return NavMgr::Get()->CanPrev(); }

    // Callback function for UI events
    void OnUpdateUI(wxUpdateUIEvent& event);

    // Callback function for menu command events
    void OnMenuCommand(wxCommandEvent& event);

    // try to match a brace from the current caret pos and select the region
    void MatchBraceAndSelect(bool selRegion);

    // Popup a find/replace dialog
    void DoFindAndReplace(bool isReplaceDlg);

    // set this page as active, this usually happened when user changed the notebook
    // page to this one
    void SetActive() override;

    // Ditto, but asynchronously
    void DelayedSetActive() override;

    // Perform FindNext operation based on the data stored in the FindReplaceData class
    void FindNext(const FindReplaceData& data);

    /**
     * @brief display functions' calltip from the current position of the caret
     */
    void ShowFunctionTipFromCurrentPos();

    /**
     * Change the document's syntax highlight
     * @param lexerName the syntax highlight's lexer name (as appear in the liteeditor.xml file)
     */
    void SetSyntaxHighlight(const wxString& lexerName) override;

    /**
     * Change the document's syntax highlight - use the file name to determine lexer name
     */
    virtual void SetSyntaxHighlight(bool bUpdateColors = true);

    /**
     * Return the document context object
     */
    ContextBasePtr GetContext() const { return m_context; }

    /**
     * If word-wrap isn't on, and forceDelay is false, this calls DoEnsureCaretIsVisible() immediately. Otherwise it
     * stores a position for OnScnPainted() to ensure-is-visible in the next scintilla paint event
     * This doesn't happen until scintilla painting is complete, so it isn't ruined by e.g. word-wrap
     * @param position the position to ensure is visible
     * @param preserveSelection preserve any selection
     * @param forceDelay wait for the next paint event even if word-wrap is off
     */
    void SetEnsureCaretIsVisible(int pos, bool preserveSelection = true, bool forceDelay = false);

    /**
     * Does the necessary things to ensure that the destination line of a GoTo is visible
     * @param position the position to ensure is visible
     * @param preserveSelection cache and reapply any selection, which would otherwise be cleared by scintilla
     */
    void DoEnsureCaretIsVisible(int pos, bool preserveSelection);

    // Bookmark API
    //-----------------------------------------
    /**
     * @brief return true if this editor has at least one compiler
     * marker (warning or error)
     */
    bool HasCompilerMarkers();

    /**
     * @brief center the line in the editor
     */
    void CenterLine(int line, int col = wxNOT_FOUND) override;

    /**
     * @brief center the editor at a given line, but preserve the selection
     */
    void CenterLinePreserveSelection(int line) override;

    /**
     * @brief Center line if needed (i.e. only if the line is not visible)
     */
    void CenterLineIfNeeded(int line, bool force = false);

    /**
     * @brief convert the editor indentation to spaces
     */
    void ConvertIndentToSpaces();

    /**
     * @brief convert the editor indentation to tabs
     */
    void ConvertIndentToTabs();

    // Is there currently a marker at the current line?
    bool LineIsMarked(enum marker_mask_type mask);
    // Toggle marker at the current line
    void ToggleMarker();

    /**
     * Delete markers from the current document
     * @param which_type if >0, delete the matching bookmark type; 0 delete the currently-active type; -1 delete all
     * types
     */
    void DelAllMarkers(int which_type);

    // Find next marker and move cursor to that line
    void FindNextMarker();
    // Find previous marker and move cursor to that line
    void FindPrevMarker();

    /**
     * @brief return list of bookmarks (active type)
     */
    size_t GetFindMarkers(std::vector<std::pair<int, wxString>>& bookmarksVector) override;

    /**
     * @brief similar to wxStyledTextCtrl::GetColumn(), but treat TAB as a single char
     * width
     */
    int GetColumnInChars(int pos) override;

    /**
     * Sets whether the currently-active bookmark level is Find', or the current standard-bookmark type
     */
    void SetFindBookmarksActive(bool findBookmarksActive) { m_findBookmarksActive = findBookmarksActive; }
    /**
     * Returns true if the currently-active bookmark level is 'Find'
     */
    bool IsFindBookmarksActive() const { return m_findBookmarksActive; }

    /**
     * The user is changing the currently-active bookmark type
     */
    void OnChangeActiveBookmarkType(wxCommandEvent& event);

    /**
     * Returns the currently-active bookmark level
     */
    int GetActiveBookmarkType() const;

    /**
     * Returns the mask for the currently-active bookmark level
     */
    enum marker_mask_type GetActiveBookmarkMask() const;

    /**
     * Returns the label for the passed bookmark type, or its type as a string
     */
    static wxString GetBookmarkLabel(sci_marker_types type);

    /**
     * Returns a tooltip for the most significant bookmark on the passed line
     */
    void GetBookmarkTooltip(int lineno, wxString& tip, wxString& title);

    // Replace all
    bool ReplaceAll();
    bool ReplaceAllExactMatch(const wxString& what, const wxString& replaceWith);
    // mark all occurances
    bool MarkAllFinds();

    // Folding API
    //-----------------------------------------
    void ToggleCurrentFold();
    void FoldAll();
    /**
     * Toggles *all* folds within the selection, not just the outer one of each function
     */
    void ToggleAllFoldsInSelection();
    void DoRecursivelyExpandFolds(bool expand, int startline,
                                  int endline); // Helper function for ToggleAllFoldsInSelection()
                                                /**
                                                 *  Find the topmost fold level within the selection, and toggle all selected folds of that level
                                                 */
    void ToggleTopmostFoldsInSelection();
    /**
     * Load collapsed folds from a vector
     */
    void LoadCollapsedFoldsFromArray(const clEditorStateLocker::VecInt_t& folds);
    /**
     * Store any collapsed folds to a vector, so they can be serialised
     */
    void StoreCollapsedFoldsToArray(clEditorStateLocker::VecInt_t& folds) const;

    static FindReplaceDialog* GetFindReplaceDialog() { return m_findReplaceDlg; }

    // Util function
    int SafeGetChar(int pos);
    wxString PreviousWord(int pos, int& foundPos);
    wxChar NextChar(const int& pos, int& foundPos);

    int FindString(const wxString& str, int flags, const bool down, long pos);

    /**
     * @brief find the current selection and select without removing the current selection
     */
    void QuickAddNext();

    /**
     * @brief find all occurances of the selected text and select
     */
    void QuickFindAll();

    bool FindAndSelect();
    bool SelectRange(const LSP::Range& range) override;
    bool SelectLocation(const LSP::Location& range) override;
    bool FindAndSelect(const FindReplaceData& data);
    bool FindAndSelect(const wxString& pattern, const wxString& name);
    void FindAndSelectV(const wxString& pattern, const wxString& name, int pos = 0,
                        NavMgr* unused = NULL) override; // The same but returns void, so usable with CallAfter()
    void DoFindAndSelectV(const wxArrayString& strings, int pos); // Called with CallAfter()

    bool Replace();
    bool Replace(const FindReplaceData& data);

    void RecalcHorizontalScrollbar();

    /**
     * Get editor options. Takes any workspace/project overrides into account
     */
    virtual OptionsConfigPtr GetOptions() override { return m_options; }

    /**
     * Add marker to the current line
     */
    void AddMarker();

    /**
     * Delete a marker from the current line
     */
    void DelMarker();

    /**
     * @brief return true if there is a breakpoint marker on the given line
     */
    bool HasBreakpointMarker(int line_number = wxNOT_FOUND) override;

    /**
     * @brief delete all breakpoint markers from the given line
     * @param line_number if set to wxNOT_FOUND(-1), delete all breakpoints from the editor
     */
    void DeleteBreakpointMarkers(int line_number = wxNOT_FOUND) override;

    /**
     * @brief return all lines that have breakpoint marker
     */
    size_t GetBreakpointMarkers(std::vector<int>* lines) override;

    /**
     * @brief delete all breakpoint markers from the given line
     */
    void SetBreakpointMarker(int line_number = wxNOT_FOUND, const wxString& tooltip = wxEmptyString) override;

    /**
     * Store all bookmarks in a wxArrayString
     */
    void StoreMarkersToArray(wxArrayString& bookmarks);

    /**
     * Load bookmarks from a wxArrayString
     */
    void LoadMarkersFromArray(const wxArrayString& bookmarks);

    /**
     * Attempt to match brace backward
     * @param chCloseBrace the closing brace character (can be one of: '}' ')' ']')
     * @param pos position to start the match
     * @param matchedPos output, the position of the matched brace
     * \return true on match false otherwise
     */
    bool MatchBraceBack(const wxChar& chCloseBrace, const long& pos, long& matchedPos);

    /**
     * Open file and clear the undo buffer
     */
    virtual void Create(const wxString& project, const wxFileName& fileName);

    /**
     * Insert text to the editor and keeping the page indentation
     * @param text text to enter
     * @param pos position to insert the text
     */
    void InsertTextWithIndentation(const wxString& text, int pos);

    BrowseRecord CreateBrowseRecord() override;

    bool IsContextMenuOn() const { return m_popupIsOn; }

    bool IsDragging() const { return m_isDragging; }

    /**
     * @brief return an approximation of the line height
     * @return line height
     */
    int GetCurrLineHeight();

    /**
     * toggle break point at the current line & file
     */
    void ToggleBreakpoint(int lineno = -1);

    /**
     * add a temporary or conditional break point at the current line & file
     */
    void AddOtherBreakpointType(wxCommandEvent& event);

    /**
     * Ignore the break point at the current line & file
     */
    void OnIgnoreBreakpoint();

    /**
     * Edit a breakpoint in the BreakptProperties dialog
     */
    void OnEditBreakpoint();

    /**
     * Add a breakpoint at the current line & file
     * Optionally make it temporary, disabled or conditional
     */
    void AddBreakpoint(int lineno = -1, const wxString& conditions = wxT(""), const bool is_temp = false,
                       const bool is_disabled = false);

    /**
     * Delete the breakpoint at the current line & file, or lineno if from ToggleBreakpoint()
     */
    void DelBreakpoint(int lineno = -1);

    /**
     * @brief change the breakpoint at the current line to disable or enable
     */
    void ToggleBreakpointEnablement();

    /**
     * @brief search the editor for pattern. If pattern is found, the editor will then search for 'what'
     * inside the pattern and will select it
     * @param pattern pattern to search in the editor
     * @param what    sub string of pattern to select
     * @param pos     start the search from 'pos'
     * @param navmgr  Navigation manager to place browsing recrods
     * @return return true if a match was found, false otherwise
     */
    bool FindAndSelect(const wxString& pattern, const wxString& what, int pos, NavMgr* navmgr) override;

    virtual void UpdateBreakpoints();

    //--------------------------------
    // breakpoint visualisation
    //--------------------------------
    virtual void SetBreakpointMarker(int lineno, BreakpointType bptype, bool is_disabled,
                                     const std::vector<clDebuggerBreakpoint>& li);
    virtual void DelAllBreakpointMarkers();

    void HighlightLine(int lineno) override;
    void UnHighlightAll() override;

    // compiler warnings and errors
    void SetWarningMarker(int lineno, const wxString& annotationText) override;
    void SetErrorMarker(int lineno, const wxString& annotationText) override;
    void DelAllCompilerMarkers() override;

    void DoShowCalltip(int pos, const wxString& title, const wxString& tip, bool strip_html_tags = true);
    /**
     * @brief adjust calltip window position to fit into the display screen
     */
    void DoAdjustCalltipPos(wxPoint& pt) const;
    void DoCancelCalltip();
    void DoCancelCodeCompletionBox();
    int DoGetOpenBracePos();

    //----------------------------------
    // File modifications
    //----------------------------------

    /**
     * return the last modification time (on disk) of editor's underlying file
     */
    time_t GetFileLastModifiedTime() const;

    /**
     * return/set the last modification time that was made by the editor
     */
    time_t GetEditorLastModifiedTime() const { return m_modifyTime; }
    void SetEditorLastModifiedTime(time_t modificationTime) { m_modifyTime = modificationTime; }

    /**
     * @brief Get the editor's modification count
     */
    wxUint64 GetModificationCount() const override { return m_modificationCount; }

    /**
     * @brief run through the file content and update colours for the
     * functions / locals
     */
    void UpdateColours();

    /**
     * @brief display completion box. This function also moves the completion box to the current position
     * @param tags list of tags to work with
     * @param word part of the word
     */
    void ShowCompletionBox(const std::vector<TagEntryPtr>& tags, const wxString& word);

    /**
     * @brief return true if the completion box is visible
     */
    bool IsCompletionBoxShown() override;

    /**
     * @brief highlight the word where the cursor is at
     * @param highlight
     */
    void HighlightWord(bool highlight = true);

    /**
     * @brief Trim trailing whitespace and/or ensure the file ends with a newline
     * @param trim trim trailing whitespace
     * @param appendLf append a newline to the file if none is present
     */
    void TrimText(bool trim, bool appendLf);

    /**
     *--------------------------------------------------
     * Implemetation for IEditor interace
     *--------------------------------------------------
     */
    wxStyledTextCtrl* GetCtrl() override { return static_cast<wxStyledTextCtrl*>(this); }

    /**
     * @brief set a code completion annotation at the given line. code completion
     * annotations are automatically cleared on the next char added
     * @param text
     * @param lineno
     */
    void SetCodeCompletionAnnotation(const wxString& text, int lineno) override;

    wxString GetEditorText() override { return GetText(); }
    size_t GetEditorTextRaw(std::string& text) override;
    void SetEditorText(const wxString& text) override;
    void OpenFile() override;
    void ReloadFromDisk(bool keepUndoHistory = false) override;
    void SetCaretAt(long pos) override;
    long GetCurrentPosition() override { return GetCurrentPos(); }
    const wxFileName& GetFileName() const override { return m_fileName; }
    const wxString& GetProjectName() const override { return m_project; }

    int GetPosAtMousePointer() override;

    /**
     * @brief
     * @return
     */
    wxString GetWordAtCaret(bool wordCharsOnly = true) override;
    /**
     * @brief
     * @return
     */
    void GetWordAtMousePointer(wxString& word, wxRect& wordRect) override;
    /**
     * @brief get word at a given position
     * @param pos word's position
     * @param wordCharsOnly when set to false, return the string between the nearest whitespaces
     */
    wxString GetWordAtPosition(int pos, bool wordCharsOnly = true) override;
    /**
     * @brief
     * @param text
     */
    void AppendText(const wxString& text) override { wxStyledTextCtrl::AppendText(text); }
    void InsertText(int pos, const wxString& text) override { wxStyledTextCtrl::InsertText(pos, text); }
    int GetLength() override { return wxStyledTextCtrl::GetLength(); }

    bool Save() override { return SaveFile(); }
    bool SaveAs(const wxString& defaultName = wxEmptyString, const wxString& savePath = wxEmptyString) override
    {
        return SaveFileAs(defaultName, savePath);
    }

    int GetEOL() override { return wxStyledTextCtrl::GetEOLMode(); }
    int GetCurrentLine() override;
    void ReplaceSelection(const wxString& text) override;
    wxString GetSelection() override;
    int GetSelectionStart() override;
    int GetSelectionEnd() override;
    void SelectText(int startPos, int len) override;

    void SetLexerName(const wxString& lexerName) override;

    // User Indicators API
    void SetUserIndicatorStyleAndColour(int style, const wxColour& colour) override;
    void SetUserIndicator(int startPos, int len) override;
    void ClearUserIndicators() override;
    int GetUserIndicatorStart(int pos) override;
    int GetUserIndicatorEnd(int pos) override;
    int GetLexerId() override;
    int GetStyleAtPos(int pos) override;

    /**
     * @brief Get position of start of word.
     * @param pos from position
     * @param onlyWordCharacters
     */
    int WordStartPos(int pos, bool onlyWordCharacters) override;

    /**
     * @brief  Get position of end of word.
     * @param pos from position
     * @param onlyWordCharacters
     */
    int WordEndPos(int pos, bool onlyWordCharacters) override;

    /**
     * Prepend the indentation level found at line at 'pos' to each line in the input string
     * @param text text to enter
     * @param pos position to insert the text
     * @param flags formatting flags
     */
    wxString FormatTextKeepIndent(const wxString& text, int pos, size_t flags = 0) override;

    /**
     * @brief return the line numebr containing 'pos'
     * @param pos the position
     */
    int LineFromPos(int pos) override;

    /**
     * @brief return the start pos of line nummber
     * @param line the line number
     * @return line nummber or 0 if the document is empty
     */
    int PosFromLine(int line) override;

    /**
     * @brief return the END position of 'line'
     * @param line the line number
     */
    int LineEnd(int line) override;

    /**
     * @brief return text from a given pos -> endPos
     * @param startPos
     * @param endPos
     * @return
     */
    wxString GetTextRange(int startPos, int endPos) override;

    /**
     * @brief display a calltip at the current position
     */
    void ShowCalltip(clCallTipPtr tip) override;

    wxChar PreviousChar(const int& pos, int& foundPos, bool wantWhitespace = false) override;
    int PositionAfterPos(int pos) override;
    int PositionBeforePos(int pos) override;
    int GetCharAtPos(int pos) override;

    /**
     * @brief apply editor configuration (TAB vs SPACES, tab size, EOL mode etc)
     */
    void ApplyEditorConfig() override;

    /**
     * @brief return true if the current editor is detached from the mainbook
     */
    bool IsDetached() const;

    /**
     * @brief display a tooltip (title + tip)
     * @param tip tip text
     * @param pos position for the tip. If wxNOT_FOUND the tip is positioned at mouse cursor position
     */
    void ShowTooltip(const wxString& tip, const wxString& title = wxEmptyString, int pos = wxNOT_FOUND) override;

    /**
     * @brief display a rich tooltip (title + tip)
     * @param tip tip text
     * @param pos position for the tip. If wxNOT_FOUND the tip is positioned at mouse cursor position
     */
    void ShowRichTooltip(const wxString& tip, const wxString& title, int pos = wxNOT_FOUND) override;

    /**
     * @brief return the first selection (in case there are multiple selections enabled)
     */
    wxString GetFirstSelection();

    //----------------------------------------------------------------------------
    //----------------------------------------------------------------------------

    void SetIsVisible(const bool& isVisible) { this->m_isVisible = isVisible; }
    const bool& GetIsVisible() const { return m_isVisible; }

    wxString GetEolString();
    void HighlightWord(StringHighlightOutput* highlightOutput);

    /**
     * Get a vector of relevant position changes. Used for 'GoTo next/previous FindInFiles match'
     */
    void GetChanges(std::vector<int>& changes);

    /**
     * Tells the EditorDeltasHolder that there's been (another) FindInFiles call
     */
    void OnFindInFiles();

    /**
     * @brief paste the clipboard content one line above the caret position
     */
    void PasteLineAbove();

    /**
     * @brief update editor options based on the global + workspace settings
     */
    void UpdateOptions();

    /**
     * @brief incase this editor represents a remote file, return its remote path
     */
    wxString GetRemotePath() const override;
    /**
     * @brief if this editor represents a remote file
     * return its remote path, otherwise return the local path
     * this is equal for writing:
     *
     * ```
     * wxString fullpath = editor->IsRemoteFile() ? editor->GetRemotePath() : editor->GetFileName().GetFullPath();
     * return fullpath;
     * ```
     */
    wxString GetRemotePathOrLocal() const override;

    /**
     * @brief return true if this file represents a remote file
     */
    bool IsRemoteFile() const override;

    /**
     * @brief return a pointer to the remote data
     * @return remote file info, or null if this file is not a remote a file
     */
    SFTPClientData* GetRemoteData() const override;

private:
    void UpdateLineNumberMarginWidth();
    void DoUpdateTLWTitle(bool raise);
    void DoWrapPrevSelectionWithChars(wxChar first, wxChar last);
    int GetFirstSingleLineCommentPos(int from, int commentStyle);
    void DoSelectRange(const LSP::Range& range);

    /**
     * @brief set the zoom factor
     */
    void SetZoomFactor(int zoom_factor);

    /**
     * @brief return number of whitespace characters in the beginning of the line
     */
    int GetNumberFirstSpacesInLine(int line);

    void FillBPtoMarkerArray();
    BPtoMarker GetMarkerForBreakpt(enum BreakpointType bp_type);
    void SetProperties();
    void DefineMarker(int marker, int markerType, wxColor fore, wxColor back);
    bool SaveToFile(const wxFileName& fileName);
    void BraceMatch(const bool& bSelRegion);
    void BraceMatch(long pos);
    void DoHighlightWord();
    bool IsOpenBrace(int position);
    bool IsCloseBrace(int position);
    size_t GetCodeNavModifier();
    // Conevert FindReplaceDialog flags to wxSD flags
    size_t SearchFlags(const FindReplaceData& data);

    void AddDebuggerContextMenu(wxMenu* menu);
    void RemoveDebuggerContextMenu(wxMenu* menu);
    void DoBreakptContextMenu(wxPoint clientPt);
    void DoMarkHyperlink(wxMouseEvent& event, bool isMiddle);
    void DoQuickJump(wxMouseEvent& event, bool isMiddle);
    bool DoFindAndSelect(const wxString& pattern, const wxString& what, int start_pos, NavMgr* navmgr);
    void DoSaveMarkers();
    void DoRestoreMarkers();
    int GetFirstNonWhitespacePos(bool backward = false);
    wxMenu* DoCreateDebuggerWatchMenu(const wxString& word);

    wxFontEncoding DetectEncoding(const wxString& filename);
    void DoToggleFold(int line, const wxString& textTag);

    // Line numbers drawings
    void DoUpdateLineNumbers(bool relative_numbers);
    void UpdateLineNumbers();
    void UpdateDefaultTextWidth();

    // Event handlers
    void OnIdle(wxIdleEvent& event);
    void OpenURL(wxCommandEvent& event);
    void OnHighlightWordChecked(wxCommandEvent& e);
    void OnRemoveMatchInidicator(wxCommandEvent& e);
    void OnSavePoint(wxStyledTextEvent& event);
    void OnCharAdded(wxStyledTextEvent& event);
    void OnMarginClick(wxStyledTextEvent& event);
    void OnChange(wxStyledTextEvent& event);
    void OnZoom(wxStyledTextEvent& event);
    void OnDwellStart(wxStyledTextEvent& event);
    void OnDwellEnd(wxStyledTextEvent& event);
    void OnCallTipClick(wxStyledTextEvent& event);
    void OnScnPainted(wxStyledTextEvent& event);
    void OnSciUpdateUI(wxStyledTextEvent& event);
    void OnFindDialog(wxCommandEvent& event);
    void OnContextMenu(wxContextMenuEvent& event);
    void OnKeyDown(wxKeyEvent& event);
    void OnKeyUp(wxKeyEvent& event);
    void OnLeftDown(wxMouseEvent& event);
    void OnRightDown(wxMouseEvent& event);
    void OnMotion(wxMouseEvent& event);
    void OnLeftUp(wxMouseEvent& event);
    void OnLeaveWindow(wxMouseEvent& event);
    void OnMouseWheel(wxMouseEvent& event);
    void OnFocusLost(wxFocusEvent& event);
    void OnFocus(wxFocusEvent& event);
    void OnLeftDClick(wxStyledTextEvent& event);
    void OnPopupMenuUpdateUI(wxUpdateUIEvent& event);
    void OnDbgAddWatch(wxCommandEvent& event);
    void OnDbgCustomWatch(wxCommandEvent& event);
    void OnDragStart(wxStyledTextEvent& e);
    void OnDragEnd(wxStyledTextEvent& e);
    void DoSetCaretAt(long pos);
    static void DoSetCaretAt(wxStyledTextCtrl* ctrl, long pos);
    void OnFileFormatDone(wxCommandEvent& e);
    void OnFileFormatStarting(wxCommandEvent& e);
    void OnTimer(wxTimerEvent& event);
    void OnEditorConfigChanged(wxCommandEvent& event);
    void OnColoursAndFontsUpdated(clCommandEvent& event);
};

#endif // LITEEDITOR_EDITOR_H