1 // SciTE - Scintilla based Text Editor
2 /** @file SciTEBase.h
3  ** Definition of platform independent base class of editor.
4  **/
5 // Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org>
6 // The License.txt file describes the conditions under which this software may be distributed.
7 
8 #ifndef SCITEBASE_H
9 #define SCITEBASE_H
10 
11 extern const GUI::gui_char appName[];
12 
13 extern const GUI::gui_char propUserFileName[];
14 extern const GUI::gui_char propGlobalFileName[];
15 extern const GUI::gui_char propAbbrevFileName[];
16 
Minimum(int a,int b)17 inline int Minimum(int a, int b) noexcept {
18 	return (a < b) ? a : b;
19 }
20 
Maximum(int a,int b)21 inline int Maximum(int a, int b) noexcept {
22 	return (a > b) ? a : b;
23 }
24 
IntFromTwoShorts(short a,short b)25 inline int IntFromTwoShorts(short a, short b) noexcept {
26 	return (a) | ((b) << 16);
27 }
28 
29 /**
30  * The order of menus on Windows - the Buffers menu may not be present
31  * and there is a Help menu at the end.
32  */
33 enum {
34 	menuFile = 0, menuEdit = 1, menuSearch = 2, menuView = 3,
35 	menuTools = 4, menuOptions = 5, menuLanguage = 6, menuBuffers = 7,
36 	menuHelp = 8
37 };
38 
39 namespace SA = Scintilla::API;
40 
41 constexpr int StyleMax = static_cast<int>(SA::StylesCommon::Max);
42 constexpr int StyleDefault = static_cast<int>(SA::StylesCommon::Default);
43 
44 struct SelectedRange {
45 	SA::Position position;
46 	SA::Position anchor;
47 	SelectedRange(SA::Position position_= SA::InvalidPosition, SA::Position anchor_= SA::InvalidPosition) noexcept :
positionSelectedRange48 		position(position_), anchor(anchor_) {
49 	}
50 };
51 
52 class RecentFile : public FilePath {
53 public:
54 	SelectedRange selection;
55 	SA::Line scrollPosition;
RecentFile()56 	RecentFile() {
57 		scrollPosition = 0;
58 	}
RecentFile(const FilePath & path_,SelectedRange selection_,SA::Line scrollPosition_)59 	RecentFile(const FilePath &path_, SelectedRange selection_, SA::Line scrollPosition_) :
60 		FilePath(path_), selection(selection_), scrollPosition(scrollPosition_) {
61 	}
62 	RecentFile(RecentFile const &) = default;
63 	RecentFile(RecentFile &&) = default;
64 	RecentFile &operator=(RecentFile const &) = default;
65 	RecentFile &operator=(RecentFile &&) = default;
66 	~RecentFile() override = default;
Init()67 	void Init() noexcept override {
68 		FilePath::Init();
69 		selection.position = SA::InvalidPosition;
70 		selection.anchor = SA::InvalidPosition;
71 		scrollPosition = 0;
72 	}
73 };
74 
75 struct BufferState {
76 public:
77 	RecentFile file;
78 	std::vector<SA::Line> foldState;
79 	std::vector<SA::Line> bookmarks;
80 };
81 
82 class Session {
83 public:
84 	FilePath pathActive;
85 	std::vector<BufferState> buffers;
86 };
87 
88 struct FileWorker;
89 
90 class Buffer {
91 public:
92 	RecentFile file;
93 	void *doc;
94 	bool isDirty;
95 	bool isReadOnly;
96 	bool failedSave;
97 	bool useMonoFont;
98 	enum { empty, reading, readAll, opened } lifeState;
99 	UniMode unicodeMode;
100 	time_t fileModTime;
101 	time_t fileModLastAsk;
102 	time_t documentModTime;
103 	enum { fmNone, fmTemporary, fmMarked, fmModified} findMarks;
104 	std::string overrideExtension;	///< User has chosen to use a particular language
105 	std::vector<SA::Line> foldState;
106 	std::vector<SA::Line> bookmarks;
107 	FileWorker *pFileWorker;
108 	PropSetFile props;
109 	enum FutureDo { fdNone=0, fdFinishSave=1 } futureDo;
Buffer()110 	Buffer() :
111 		file(), doc(nullptr), isDirty(false), isReadOnly(false), failedSave(false), useMonoFont(false), lifeState(empty),
112 		unicodeMode(uni8Bit), fileModTime(0), fileModLastAsk(0), documentModTime(0),
113 		findMarks(fmNone), pFileWorker(nullptr), futureDo(fdNone) {}
114 
115 	~Buffer() = default;
Init()116 	void Init() {
117 		file.Init();
118 		isDirty = false;
119 		isReadOnly = false;
120 		failedSave = false;
121 		useMonoFont = false;
122 		lifeState = empty;
123 		unicodeMode = uni8Bit;
124 		fileModTime = 0;
125 		fileModLastAsk = 0;
126 		documentModTime = 0;
127 		findMarks = fmNone;
128 		overrideExtension = "";
129 		foldState.clear();
130 		bookmarks.clear();
131 		pFileWorker = nullptr;
132 		futureDo = fdNone;
133 	}
134 
SetTimeFromFile()135 	void SetTimeFromFile() {
136 		fileModTime = file.ModifiedTime();
137 		fileModLastAsk = fileModTime;
138 		documentModTime = fileModTime;
139 		failedSave = false;
140 	}
141 
142 	void DocumentModified() noexcept;
143 	bool NeedsSave(int delayBeforeSave) const;
144 
145 	void CompleteLoading() noexcept;
146 	void CompleteStoring();
147 	void AbandonAutomaticSave();
148 
ShouldNotSave()149 	bool ShouldNotSave() const noexcept {
150 		return lifeState != opened;
151 	}
152 
153 	void CancelLoad();
154 };
155 
156 struct BackgroundActivities {
157 	int loaders;
158 	int storers;
159 	size_t totalWork;
160 	size_t totalProgress;
161 	GUI::gui_string fileNameLast;
162 };
163 
164 class BufferList {
165 protected:
166 	int current;
167 	int stackcurrent;
168 	std::vector<int> stack;
169 public:
170 	std::vector<Buffer> buffers;
171 	int length;
172 	int lengthVisible;
173 	bool initialised;
174 
175 	BufferList();
176 	~BufferList();
size()177 	int size() const noexcept {
178 		return static_cast<int>(buffers.size());
179 	}
180 	void Allocate(int maxSize);
181 	int Add();
182 	int GetDocumentByWorker(const FileWorker *pFileWorker) const;
183 	int GetDocumentByName(const FilePath &filename, bool excludeCurrent=false);
184 	void RemoveInvisible(int index);
185 	void RemoveCurrent();
186 	int Current() const noexcept;
187 	Buffer *CurrentBuffer();
188 	const Buffer *CurrentBufferConst() const;
189 	void SetCurrent(int index) noexcept;
190 	int StackNext();
191 	int StackPrev();
192 	void CommitStackSelection();
193 	void MoveToStackTop(int index);
194 	void ShiftTo(int indexFrom, int indexTo);
195 	void Swap(int indexA, int indexB);
196 	bool SingleBuffer() const noexcept;
197 	BackgroundActivities CountBackgroundActivities() const;
198 	bool SavingInBackground() const;
199 	bool GetVisible(int index) const noexcept;
200 	void SetVisible(int index, bool visible);
201 	void AddFuture(int index, Buffer::FutureDo fd);
202 	void FinishedFuture(int index, Buffer::FutureDo fd);
203 private:
204 	void PopStack();
205 };
206 
207 // class to hold user defined keyboard short cuts
208 class ShortcutItem {
209 public:
210 	std::string menuKey; // the keyboard short cut
211 	std::string menuCommand; // the menu command to be passed to "SciTEBase::MenuCommand"
212 };
213 
214 class LanguageMenuItem {
215 public:
216 	std::string menuItem;
217 	std::string menuKey;
218 	std::string extension;
219 };
220 
221 enum {
222 	heightTools = 24,
223 	heightToolsBig = 32,
224 	heightTab = 24,
225 	heightStatus = 20,
226 	statusPosWidth = 256
227 };
228 
229 /// Warning IDs.
230 enum {
231 	warnFindWrapped = 1,
232 	warnNotFound,
233 	warnNoOtherBookmark,
234 	warnWrongFile,
235 	warnExecuteOK,
236 	warnExecuteKO
237 };
238 
239 /// Codes representing the effect a line has on indentation.
240 enum IndentationStatus {
241 	isNone,		// no effect on indentation
242 	isBlockStart,	// indentation block begin such as "{" or VB "function"
243 	isBlockEnd,	// indentation end indicator such as "}" or VB "end"
244 	isKeyWordStart	// Keywords that cause indentation
245 };
246 
247 struct StyleAndWords {
248 	int styleNumber;
249 	std::string words;
StyleAndWordsStyleAndWords250 	StyleAndWords() noexcept : styleNumber(0) {
251 	}
IsEmptyStyleAndWords252 	bool IsEmpty() const noexcept { return words.length() == 0; }
IsSingleCharStyleAndWords253 	bool IsSingleChar() const noexcept { return words.length() == 1; }
254 };
255 
256 struct CurrentWordHighlight {
257 	enum {
258 		noDelay,            // No delay, and no word at the caret.
259 		delay,              // Delay before to highlight the word at the caret.
260 		delayJustEnded,     // Delay has just ended. This state allows to ignore next HighlightCurrentWord (UpdateUI and SC_UPDATE_CONTENT for setting indicators).
261 		delayAlreadyElapsed // Delay has already elapsed, word at the caret and occurrences are (or have to be) highlighted.
262 	} statesOfDelay;
263 	bool isEnabled;
264 	bool textHasChanged;
265 	GUI::ElapsedTime elapsedTimes;
266 	bool isOnlyWithSameStyle;
267 
CurrentWordHighlightCurrentWordHighlight268 	CurrentWordHighlight() {
269 		statesOfDelay = noDelay;
270 		isEnabled = false;
271 		textHasChanged = false;
272 		isOnlyWithSameStyle = false;
273 	}
274 };
275 
276 class Localization : public PropSetFile, public ILocalize {
277 	std::string missing;
278 public:
279 	bool read;
Localization()280 	Localization() : PropSetFile(true), read(false) {
281 	}
282 	GUI::gui_string Text(const char *s, bool retainIfNotFound=true) override;
SetMissing(const std::string & missing_)283 	void SetMissing(const std::string &missing_) {
284 		missing = missing_;
285 	}
286 };
287 
288 // Interface between SciTE and dialogs and strips for find and replace
289 class Searcher {
290 public:
291 	std::string findWhat;
292 	std::string replaceWhat;
293 
294 	bool wholeWord;
295 	bool matchCase;
296 	bool regExp;
297 	bool unSlash;
298 	bool wrapFind;
299 	bool reverseFind;
300 
301 	SA::Position searchStartPosition;
302 	bool replacing;
303 	bool havefound;
304 	bool failedfind;
305 	bool findInStyle;
306 	int findStyle;
307 	enum class CloseFind { closePrevent, closeAlways, closeOnMatch } closeFind;
308 	ComboMemory memFinds;
309 	ComboMemory memReplaces;
310 
311 	bool focusOnReplace;
312 
313 	Searcher();
314 
315 	virtual void SetFindText(const char *sFind) = 0;
316 	virtual void SetFind(const char *sFind) = 0;
317 	virtual bool FindHasText() const noexcept = 0;
318 	void InsertFindInMemory();
319 	virtual void SetReplace(const char *sReplace) = 0;
320 	virtual void SetCaretAsStart() = 0;
321 	virtual void MoveBack() = 0;
322 	virtual void ScrollEditorIfNeeded() = 0;
323 
324 	virtual SA::Position FindNext(bool reverseDirection, bool showWarnings=true, bool allowRegExp=true) = 0;
325 	virtual void HideMatch() = 0;
326 	enum MarkPurpose { markWithBookMarks, markIncremental };
327 	virtual void MarkAll(MarkPurpose purpose=markWithBookMarks) = 0;
328 	virtual intptr_t ReplaceAll(bool inSelection) = 0;
329 	virtual void ReplaceOnce(bool showWarnings=true) = 0;
330 	virtual void UIClosed() = 0;
331 	virtual void UIHasFocus() = 0;
332 	bool &FlagFromCmd(int cmd) noexcept;
ShouldClose(bool found)333 	bool ShouldClose(bool found) const noexcept {
334 		return (closeFind == CloseFind::closeAlways) || (found && (closeFind == CloseFind::closeOnMatch));
335 	}
336 };
337 
338 // User interface for search options implemented as both buttons and popup menu items
339 struct SearchOption {
340 	enum { tWord, tCase, tRegExp, tBackslash, tWrap, tUp };
341 	const char *label;
342 	int cmd;	// Menu item
343 	int id;	// Control in dialog
344 };
345 
346 class SearchUI {
347 protected:
348 	Searcher *pSearcher;
349 public:
SearchUI()350 	SearchUI() noexcept : pSearcher(nullptr) {
351 	}
SetSearcher(Searcher * pSearcher_)352 	void SetSearcher(Searcher *pSearcher_) noexcept {
353 		pSearcher = pSearcher_;
354 	}
355 };
356 
357 class IEditorConfig;
358 struct SCNotification;
359 
360 struct SystemAppearance {
361 	bool dark;
362 	bool highContrast;
363 	bool operator==(const SystemAppearance &other) const noexcept {
364 		return dark == other.dark && highContrast == other.highContrast;
365 	}
366 };
367 
368 class SciTEBase : public ExtensionAPI, public Searcher, public WorkerListener {
369 protected:
370 	bool needIdle;
371 	GUI::gui_string windowName;
372 	FilePath filePath;
373 	FilePath dirNameAtExecute;
374 	FilePath dirNameForExecute;
375 
376 	static constexpr int fileStackMax = 10;
377 	RecentFile recentFileStack[fileStackMax];
378 	enum { fileStackCmdID = IDM_MRUFILE, bufferCmdID = IDM_BUFFER };
379 
380 	static constexpr int importMax = 50;
381 	FilePathSet importFiles;
382 	enum { importCmdID = IDM_IMPORT };
383 	ImportFilter filter;
384 
385 	enum { indicatorMatch = static_cast<int>(SA::IndicatorStyle::Container),
386 	       indicatorHighlightCurrentWord,
387 	       indicatorSpellingMistake,
388 	       indicatorSentinel
389 	     };
390 	enum { markerBookmark = 1 };
391 	ComboMemory memFiles;
392 	ComboMemory memDirectory;
393 	std::string parameterisedCommand;
394 	std::string abbrevInsert;
395 
396 	enum { languageCmdID = IDM_LANGUAGE };
397 	std::vector<LanguageMenuItem> languageMenu;
398 
399 	// an array of short cut items that are defined by the user in the properties file.
400 	std::vector<ShortcutItem> shortCutItemList;
401 
402 	int codePage;
403 	SA::CharacterSet characterSet;
404 	std::string language;
405 	int lexLanguage;
406 	std::string subStyleBases;
407 	int lexLPeg;
408 	StringList apis;
409 	std::string apisFileNames;
410 	std::string functionDefinition;
411 
412 	int diagnosticStyleStart;
413 	enum { diagnosticStyles=4};
414 
415 	bool stripTrailingSpaces;
416 	bool ensureFinalLineEnd;
417 	bool ensureConsistentLineEnds;
418 
419 	bool indentOpening;
420 	bool indentClosing;
421 	bool indentMaintain;
422 	int statementLookback;
423 	StyleAndWords statementIndent;
424 	StyleAndWords statementEnd;
425 	StyleAndWords blockStart;
426 	StyleAndWords blockEnd;
427 	enum class PreProc { None, Start, Middle, End, Dummy };	///< Indicate the kind of preprocessor condition line
428 	char preprocessorSymbol;	///< Preprocessor symbol (in C, #)
429 	std::map<std::string, PreProc> preprocOfString; ///< Map preprocessor keywords to positions
430 	/// In C, if ifdef ifndef : start, else elif : middle, endif : end.
431 
432 	GUI::Window wSciTE;  ///< Contains wToolBar, wTabBar, wContent, and wStatusBar
433 	GUI::Window wContent;    ///< Contains wEditor and wOutput
434 	GUI::ScintillaWindow wEditor;
435 	GUI::ScintillaWindow wOutput;
436 	GUI::ScintillaWindow *pwFocussed;
437 	GUI::Window wIncrement;
438 	GUI::Window wToolBar;
439 	GUI::Window wStatusBar;
440 	GUI::Window wTabBar;
441 	GUI::Menu popup;
442 	bool tbVisible;
443 	bool tabVisible;
444 	bool tabHideOne; // Hide tab bar if one buffer is opened only
445 	bool tabMultiLine;
446 	bool sbVisible;	///< @c true if status bar is visible.
447 	std::string sbValue;	///< Status bar text.
448 	int sbNum;	///< Number of the currently displayed status bar information.
449 	int visHeightTools;
450 	int visHeightTab;
451 	int visHeightStatus;
452 	int visHeightEditor;
453 	int heightBar;
454 	// Prevent automatic load dialog appearing at the same time as
455 	// other dialogs as this can leads to reentry errors.
456 	int dialogsOnScreen;
457 	bool topMost;
458 	bool wrap;
459 	bool wrapOutput;
460 	SA::Wrap wrapStyle;
461 	SA::IdleStyling idleStyling;
462 	SA::Alpha alphaIndicator;
463 	bool underIndicator;
464 	std::string foldColour;
465 	std::string foldHiliteColour;
466 	bool openFilesHere;
467 	bool fullScreen;
468 	SystemAppearance appearance;
469 	enum { toolMax = 50 };
470 	Extension *extender;
471 	bool needReadProperties;
472 	bool quitting;
473 
474 	int timerMask;
475 	enum { timerAutoSave=1 };
476 	int delayBeforeAutoSave;
477 
478 	int heightOutput;
479 	int heightOutputStartDrag;
480 	GUI::Point ptStartDrag;
481 	bool capturedMouse;
482 	int previousHeightOutput;
483 	bool firstPropertiesRead;
484 	bool splitVertical;	///< @c true if the split bar between editor and output is vertical.
485 	bool bufferedDraw;
486 	bool bracesCheck;
487 	bool bracesSloppy;
488 	int bracesStyle;
489 	int braceCount;
490 
491 	int indentationWSVisible;
492 	SA::IndentView indentExamine;
493 	bool autoCompleteIgnoreCase;
494 	bool imeAutoComplete;
495 	bool callTipUseEscapes;
496 	bool callTipIgnoreCase;
497 	bool autoCCausedByOnlyOne;
498 	std::string calltipWordCharacters;
499 	std::string calltipParametersStart;
500 	std::string calltipParametersEnd;
501 	std::string calltipParametersSeparators;
502 	std::string calltipEndDefinition;
503 	std::string autoCompleteStartCharacters;
504 	std::string autoCompleteFillUpCharacters;
505 	std::string autoCompleteTypeSeparator;
506 	std::string wordCharacters;
507 	std::string whitespaceCharacters;
508 	SA::Position startCalltipWord;
509 	int currentCallTip;
510 	int maxCallTips;
511 	std::string currentCallTipWord;
512 	SA::Position lastPosCallTip;
513 
514 	bool margin;
515 	int marginWidth;
516 	enum { marginWidthDefault = 20};
517 
518 	bool foldMargin;
519 	int foldMarginWidth;
520 	enum { foldMarginWidthDefault = 14};
521 
522 	bool lineNumbers;
523 	int lineNumbersWidth;
524 	enum { lineNumbersWidthDefault = 4 };
525 	bool lineNumbersExpand;
526 
527 	bool allowMenuActions;
528 	int scrollOutput;
529 	bool returnOutputToCommand;
530 	JobQueue jobQueue;
531 
532 	bool macrosEnabled;
533 	std::string currentMacro;
534 	bool recording;
535 
536 	PropSetFile propsPlatform;
537 	PropSetFile propsEmbed;
538 	PropSetFile propsBase;
539 	PropSetFile propsUser;
540 	PropSetFile propsDirectory;
541 	PropSetFile propsLocal;
542 	PropSetFile propsDiscovered;
543 	PropSetFile props;
544 
545 	PropSetFile propsAbbrev;
546 
547 	PropSetFile propsSession;
548 
549 	FilePath pathAbbreviations;
550 
551 	Localization localiser;
552 
553 	PropSetFile propsStatus;
554 
555 	std::unique_ptr<IEditorConfig> editorConfig;
556 
557 	enum { bufferMax = IDM_IMPORT - IDM_BUFFER };
558 	BufferList buffers;
559 
560 	// Handle buffers
561 	void *GetDocumentAt(int index);
562 	void SwitchDocumentAt(int index, void *pdoc);
563 	void UpdateBuffersCurrent();
564 	bool IsBufferAvailable() const noexcept;
565 	bool CanMakeRoom(bool maySaveIfDirty = true);
566 	void SetDocumentAt(int index, bool updateStack = true);
CurrentBuffer()567 	Buffer *CurrentBuffer() {
568 		return buffers.CurrentBuffer();
569 	}
CurrentBufferConst()570 	const Buffer *CurrentBufferConst() const {
571 		return buffers.CurrentBufferConst();
572 	}
573 	void SetBuffersMenu();
574 	void BuffersMenu();
575 	void Next();
576 	void Prev();
577 	void NextInStack();
578 	void PrevInStack();
579 	void EndStackedTabbing();
580 
581 	virtual void TabInsert(int index, const GUI::gui_char *title) = 0;
582 	virtual void TabSelect(int index) = 0;
583 	virtual void RemoveAllTabs() = 0;
584 	void ShiftTab(int indexFrom, int indexTo);
585 	void MoveTabRight();
586 	void MoveTabLeft();
587 
588 	virtual void ReadEmbeddedProperties();
589 	void ReadEnvironment();
590 	void ReadGlobalPropFile();
591 	void ReadAbbrevPropFile();
592 	void ReadLocalPropFile();
593 	void ReadDirectoryPropFile();
594 
595 	virtual SystemAppearance CurrentAppearance() const noexcept;
596 	void CheckAppearanceChanged();
597 	void SetPaneFocus(bool editPane) noexcept;
598 	GUI::ScintillaWindow &PaneFocused();
599 	GUI::ScintillaWindow &PaneSource(int destination);
600 	intptr_t CallFocusedElseDefault(int defaultValue, SA::Message msg, uintptr_t wParam = 0, intptr_t lParam = 0);
601 	void CallChildren(SA::Message msg, uintptr_t wParam = 0, intptr_t lParam = 0);
602 	std::string GetTranslationToAbout(const char *const propname, bool retainIfNotFound = true);
603 	SA::Position LengthDocument();
604 	SA::Position GetCaretInLine();
605 	std::string GetLine(SA::Line line);
606 	std::string GetCurrentLine();
607 	PreProc LinePreprocessorCondition(SA::Line line);
608 	bool FindMatchingPreprocessorCondition(SA::Line &curLine, int direction, PreProc condEnd1, PreProc condEnd2);
609 	bool FindMatchingPreprocCondPosition(bool isForward, SA::Position mppcAtCaret, SA::Position &mppcMatch);
610 	bool FindMatchingBracePosition(bool editor, SA::Position &braceAtCaret, SA::Position &braceOpposite, bool sloppy);
611 	void BraceMatch(bool editor);
612 
613 	virtual void WarnUser(int warnID) = 0;
614 	void SetWindowName();
615 	void SetFileName(const FilePath &openName, bool fixCase = true);
FileNameExt()616 	FilePath FileNameExt() const {
617 		return filePath.Name();
618 	}
619 	void ClearDocument();
620 	void CreateBuffers();
621 	void InitialiseBuffers();
622 	FilePath UserFilePath(const GUI::gui_char *name);
623 	void LoadSessionFile(const GUI::gui_char *sessionName);
624 	void RestoreRecentMenu();
625 	void RestoreFromSession(const Session &session);
626 	void RestoreSession();
627 	void SaveSessionFile(const GUI::gui_char *sessionName);
628 	virtual void GetWindowPosition(int *left, int *top, int *width, int *height, int *maximize) = 0;
629 	void SetIndentSettings();
630 	void SetEol();
631 	void New();
632 	void RestoreState(const Buffer &buffer, bool restoreBookmarks);
633 	void Close(bool updateUI = true, bool loadingSession = false, bool makingRoomForNew = false);
634 	static bool Exists(const GUI::gui_char *dir, const GUI::gui_char *path, FilePath *resultPath);
635 	void DiscoverEOLSetting();
636 	void DiscoverIndentSetting();
637 	std::string DiscoverLanguage();
638 	void OpenCurrentFile(long long fileSize, bool suppressMessage, bool asynchronous);
OpenUriList(const char *)639 	virtual void OpenUriList(const char *) {}
640 	virtual bool OpenDialog(const FilePath &directory, const GUI::gui_char *filesFilter) = 0;
641 	virtual bool SaveAsDialog() = 0;
LoadSessionDialog()642 	virtual void LoadSessionDialog() {}
SaveSessionDialog()643 	virtual void SaveSessionDialog() {}
644 	void CountLineEnds(int &linesCR, int &linesLF, int &linesCRLF);
645 	enum OpenFlags {
646 		ofNone = 0, 		// Default
647 		ofNoSaveIfDirty = 1, 	// Suppress check for unsaved changes
648 		ofForceLoad = 2,	// Reload file even if already in a buffer
649 		ofPreserveUndo = 4,	// Do not delete undo history
650 		ofQuiet = 8,		// Avoid "Could not open file" message
651 		ofSynchronous = 16	// Force synchronous read
652 	};
653 	void TextRead(FileWorker *pFileWorker);
654 	void TextWritten(FileWorker *pFileWorker);
655 	void UpdateProgress(Worker *pWorker);
656 	void PerformDeferredTasks();
657 	enum OpenCompletion { ocSynchronous, ocCompleteCurrent, ocCompleteSwitch };
658 	void CompleteOpen(OpenCompletion oc);
659 	virtual bool PreOpenCheck(const GUI::gui_char *file);
660 	bool Open(const FilePath &file, OpenFlags of = ofNone);
661 	bool OpenSelected();
662 	void Revert();
663 	FilePath SaveName(const char *ext) const;
664 	enum SaveFlags {
665 		sfNone = 0, 		// Default
666 		sfProgressVisible = 1, 	// Show in background save strip
667 		sfSynchronous = 16	// Write synchronously blocking UI
668 	};
669 	enum SaveResult {
670 		saveCompleted,
671 		saveCancelled
672 	};
673 	SaveResult SaveIfUnsure(bool forceQuestion = false, SaveFlags sf = sfProgressVisible);
674 	SaveResult SaveIfUnsureAll();
675 	SaveResult SaveIfUnsureForBuilt();
676 	bool SaveIfNotOpen(const FilePath &destFile, bool fixCase);
677 	void AbandonAutomaticSave();
678 	bool Save(SaveFlags sf = sfProgressVisible);
679 	void SaveAs(const GUI::gui_char *file, bool fixCase);
680 	virtual void SaveACopy() = 0;
681 	void SaveToHTML(const FilePath &saveName);
682 	void StripTrailingSpaces();
683 	void EnsureFinalNewLine();
684 	bool PrepareBufferForSave(const FilePath &saveName);
685 	bool SaveBuffer(const FilePath &saveName, SaveFlags sf);
686 	virtual void SaveAsHTML() = 0;
687 	void SaveToStreamRTF(std::ostream &os, SA::Position start = 0, SA::Position end = -1);
688 	void SaveToRTF(const FilePath &saveName, SA::Position start = 0, SA::Position end = -1);
689 	virtual void SaveAsRTF() = 0;
690 	void SaveToPDF(const FilePath &saveName);
691 	virtual void SaveAsPDF() = 0;
692 	void SaveToTEX(const FilePath &saveName);
693 	virtual void SaveAsTEX() = 0;
694 	void SaveToXML(const FilePath &saveName);
695 	virtual void SaveAsXML() = 0;
696 	virtual FilePath GetDefaultDirectory() = 0;
697 	virtual FilePath GetSciteDefaultHome() = 0;
698 	virtual FilePath GetSciteUserHome() = 0;
699 	FilePath GetDefaultPropertiesFileName();
700 	FilePath GetUserPropertiesFileName();
701 	FilePath GetDirectoryPropertiesFileName();
702 	FilePath GetLocalPropertiesFileName();
703 	FilePath GetAbbrevPropertiesFileName();
704 	void OpenProperties(int propsFile);
705 	static int GetMenuCommandAsInt(std::string commandName);
Print(bool)706 	virtual void Print(bool) {}
PrintSetup()707 	virtual void PrintSetup() {}
UserStripShow(const char *)708 	void UserStripShow(const char * /* description */) override {}
UserStripSet(int,const char *)709 	void UserStripSet(int /* control */, const char * /* value */) override {}
UserStripSetList(int,const char *)710 	void UserStripSetList(int /* control */, const char * /* value */) override {}
UserStripValue(int)711 	std::string UserStripValue(int /* control */) override { return std::string(); }
ShowBackgroundProgress(const GUI::gui_string &,size_t,size_t)712 	virtual void ShowBackgroundProgress(const GUI::gui_string & /* explanation */, size_t /* size */, size_t /* progress */) {}
713 	SA::Range GetSelection();
714 	SelectedRange GetSelectedRange();
715 	void SetSelection(SA::Position anchor, SA::Position currentPos);
716 	std::string GetCTag();
717 	virtual std::string GetRangeInUIEncoding(GUI::ScintillaWindow &win, SA::Range range);
718 	static std::string GetLine(GUI::ScintillaWindow &win, SA::Line line);
719 	void RangeExtend(GUI::ScintillaWindow &wCurrent, SA::Range &range,
720 			 bool (SciTEBase::*ischarforsel)(char ch));
721 	std::string RangeExtendAndGrab(GUI::ScintillaWindow &wCurrent, SA::Range &range,
722 				       bool (SciTEBase::*ischarforsel)(char ch), bool stripEol = true);
723 	std::string SelectionExtend(bool (SciTEBase::*ischarforsel)(char ch), bool stripEol = true);
724 	std::string SelectionWord(bool stripEol = true);
725 	std::string SelectionFilename();
726 	void SelectionIntoProperties();
727 	void SelectionIntoFind(bool stripEol = true);
728 	enum AddSelection { addNext, addEach };
729 	void SelectionAdd(AddSelection add);
730 	virtual std::string EncodeString(const std::string &s);
731 	virtual void Find() = 0;
732 	enum MessageBoxChoice {
733 		mbOK,
734 		mbCancel,
735 		mbYes,
736 		mbNo
737 	};
738 	typedef int MessageBoxStyle;
739 	enum {
740 		// Same as Win32 MB_*
741 		mbsOK = 0,
742 		mbsYesNo = 4,
743 		mbsYesNoCancel = 3,
744 		mbsIconQuestion = 0x20,
745 		mbsIconWarning = 0x30
746 	};
747 	virtual MessageBoxChoice WindowMessageBox(GUI::Window &w, const GUI::gui_string &msg, MessageBoxStyle style = mbsIconWarning) = 0;
748 	void FailedSaveMessageBox(const FilePath &filePathSaving);
749 	virtual void FindMessageBox(const std::string &msg, const std::string *findItem = nullptr) = 0;
750 	bool FindReplaceAdvanced() const;
751 	SA::Position FindInTarget(const std::string &findWhatText, SA::Range range);
752 	// Implement Searcher
753 	void SetFindText(const char *sFind) override;
754 	void SetFind(const char *sFind) override;
755 	bool FindHasText() const noexcept override;
756 	void SetReplace(const char *sReplace) override;
757 	void SetCaretAsStart() override;
758 	void MoveBack() override;
759 	void ScrollEditorIfNeeded() override;
760 	SA::Position FindNext(bool reverseDirection, bool showWarnings=true, bool allowRegExp=true) override;
761 	void HideMatch() override;
762 	virtual void FindIncrement() = 0;
763 	int IncrementSearchMode();
764 	virtual void FindInFiles() = 0;
765 	virtual void Replace() = 0;
766 	void ReplaceOnce(bool showWarnings=true) override;
767 	intptr_t DoReplaceAll(bool inSelection); // returns number of replacements or negative value if error
768 	intptr_t ReplaceAll(bool inSelection) override;
769 	intptr_t ReplaceInBuffers();
770 	void SetFindInFilesOptions();
771 	void UIClosed() override;
772 	void UIHasFocus() override;
773 	virtual void DestroyFindReplace() = 0;
774 	virtual void GoLineDialog() = 0;
775 	virtual bool AbbrevDialog() = 0;
776 	virtual void TabSizeDialog() = 0;
777 	virtual bool ParametersOpen() = 0;
778 	virtual void ParamGrab() = 0;
779 	virtual bool ParametersDialog(bool modal) = 0;
780 	bool HandleXml(char ch);
781 	static std::string FindOpenXmlTag(const char sel[], SA::Position nSize);
782 	void GoMatchingBrace(bool select);
783 	void GoMatchingPreprocCond(int direction, bool select);
784 	virtual void FindReplace(bool replace) = 0;
785 	void OutputAppendString(const char *s, SA::Position len = -1);
786 	virtual void OutputAppendStringSynchronised(const char *s, SA::Position len = -1);
787 	virtual void Execute();
788 	virtual void StopExecute() = 0;
789 	void ShowMessages(SA::Line line);
790 	void GoMessage(int dir);
791 	virtual bool StartCallTip();
792 	std::string GetNearestWords(const char *wordStart, size_t searchLen,
793 				    const char *separators, bool ignoreCase=false, bool exactLen=false);
794 	virtual void FillFunctionDefinition(SA::Position pos = -1);
795 	void ContinueCallTip();
796 	std::string EliminateDuplicateWords(const std::string &words);
797 	virtual bool StartAutoComplete();
798 	virtual bool StartAutoCompleteWord(bool onlyOneWord);
799 	virtual bool StartExpandAbbreviation();
800 	bool PerformInsertAbbreviation();
801 	virtual bool StartInsertAbbreviation();
802 	virtual bool StartBlockComment();
803 	virtual bool StartBoxComment();
804 	virtual bool StartStreamComment();
805 	std::vector<std::string> GetLinePartsInStyle(SA::Line line, const StyleAndWords &saw);
806 	void SetLineIndentation(SA::Line line, int indent);
807 	int GetLineIndentation(SA::Line line);
808 	SA::Position GetLineIndentPosition(SA::Line line);
809 	void ConvertIndentation(int tabSize, int useTabs);
810 	bool RangeIsAllWhitespace(SA::Position start, SA::Position end);
811 	IndentationStatus GetIndentState(SA::Line line);
812 	int IndentOfBlock(SA::Line line);
813 	void MaintainIndentation(char ch);
814 	void AutomaticIndentation(char ch);
815 	void CharAdded(int utf32);
816 	void CharAddedOutput(int ch);
817 	void SetTextProperties(PropSetFile &ps);
818 	virtual void SetFileProperties(PropSetFile &ps) = 0;
819 	void UpdateStatusBar(bool bUpdateSlowData) override;
820 	SA::Position GetLineLength(SA::Line line);
821 	SA::Line GetCurrentLineNumber();
822 	SA::Position GetCurrentColumnNumber();
823 	SA::Line GetCurrentScrollPosition();
824 	virtual void AddCommand(const std::string &cmd, const std::string &dir,
825 				JobSubsystem jobType, const std::string &input = "",
826 				int flags = 0);
827 	virtual void AboutDialog() = 0;
828 	virtual void QuitProgram() = 0;
829 	void CloseTab(int tab);
830 	void CloseAllBuffers(bool loadingSession = false);
831 	SaveResult SaveAllBuffers(bool alwaysYes);
832 	void SaveTitledBuffers();
CopyAsRTF()833 	virtual void CopyAsRTF() {}
CopyPath()834 	virtual void CopyPath() {}
835 	void SetLineNumberWidth();
836 	void MenuCommand(int cmdID, int source = 0);
837 	void FoldChanged(SA::Line line, SA::FoldLevel levelNow, SA::FoldLevel levelPrev);
838 	void ExpandFolds(SA::Line line, bool expand, SA::FoldLevel level);
839 	void FoldAll();
840 	void ToggleFoldRecursive(SA::Line line, SA::FoldLevel level);
841 	void EnsureAllChildrenVisible(SA::Line line, SA::FoldLevel level);
842 	static void EnsureRangeVisible(GUI::ScintillaWindow &win, SA::Range range, bool enforcePolicy = true);
843 	void GotoLineEnsureVisible(SA::Line line);
844 	bool MarginClick(SA::Position position, int modifiers);
845 	void NewLineInOutput();
846 	virtual void SetStatusBarText(const char *s) = 0;
847 	void UpdateUI(const SCNotification *notification);
848 	void Modified(const SCNotification *notification);
849 	virtual void Notify(SCNotification *notification);
850 	virtual void ShowToolBar() = 0;
851 	virtual void ShowTabBar() = 0;
852 	virtual void ShowStatusBar() = 0;
853 	virtual void ActivateWindow(const char *timestamp) = 0;
854 
855 	void RemoveFindMarks();
856 	SA::FindOption SearchFlags(bool regularExpressions) const;
857 	void MarkAll(MarkPurpose purpose=markWithBookMarks) override;
858 	void BookmarkAdd(SA::Line lineno = -1);
859 	void BookmarkDelete(SA::Line lineno = -1);
860 	bool BookmarkPresent(SA::Line lineno = -1);
861 	void BookmarkToggle(SA::Line lineno = -1);
862 	void BookmarkNext(bool forwardScan = true, bool select = false);
863 	void BookmarkSelectAll();
864 	void SetOutputVisibility(bool show);
865 	virtual void ShowOutputOnMainThread();
866 	void ToggleOutputVisible();
867 	virtual void SizeContentWindows() = 0;
868 	virtual void SizeSubWindows() = 0;
869 
870 	virtual void SetMenuItem(int menuNumber, int position, int itemID,
871 				 const GUI::gui_char *text, const GUI::gui_char *mnemonic = nullptr) = 0;
RedrawMenu()872 	virtual void RedrawMenu() {}
873 	virtual void DestroyMenuItem(int menuNumber, int itemID) = 0;
874 	virtual void CheckAMenuItem(int wIDCheckItem, bool val) = 0;
875 	virtual void EnableAMenuItem(int wIDCheckItem, bool val) = 0;
876 	virtual void CheckMenusClipboard();
877 	virtual void CheckMenus();
878 	virtual void AddToPopUp(const char *label, int cmd = 0, bool enabled = true) = 0;
879 	void ContextMenu(GUI::ScintillaWindow &wSource, GUI::Point pt, GUI::Window wCmd);
880 
881 	void DeleteFileStackMenu();
882 	void SetFileStackMenu();
883 	bool AddFileToBuffer(const BufferState &bufferState);
884 	void AddFileToStack(const RecentFile &file);
885 	void RemoveFileFromStack(const FilePath &file);
886 	RecentFile GetFilePosition();
887 	void DisplayAround(const RecentFile &rf);
888 	void StackMenu(int pos);
889 	void StackMenuNext();
890 	void StackMenuPrev();
891 
892 	void RemoveToolsMenu();
893 	void SetMenuItemLocalised(int menuNumber, int position, int itemID,
894 				  const char *text, const char *mnemonic);
895 	bool ToolIsImmediate(int item);
896 	void SetToolsMenu();
897 	JobSubsystem SubsystemType(const char *cmd);
898 	void ToolsMenu(int item);
899 
900 	void AssignKey(SA::Keys key, SA::KeyMod mods, int cmd);
901 	void ViewWhitespace(bool view);
902 	void SetAboutMessage(GUI::ScintillaWindow &wsci, const char *appTitle);
903 	void SetImportMenu();
904 	void ImportMenu(int pos);
905 	void SetLanguageMenu();
906 	void SetPropertiesInitial();
907 	GUI::gui_string LocaliseMessage(const char *s,
908 					const GUI::gui_char *param0 = nullptr, const GUI::gui_char *param1 = nullptr, const GUI::gui_char *param2 = nullptr);
909 	virtual void ReadLocalization();
910 	std::string GetFileNameProperty(const char *name);
911 	virtual void ReadPropertiesInitial();
912 	void ReadFontProperties();
913 	void SetOverrideLanguage(int cmdID);
914 	StyleAndWords GetStyleAndWords(const char *base);
915 	std::string ExtensionFileName() const;
916 	static const char *GetNextPropItem(const char *pStart, char *pPropItem, int maxLen);
917 	void ForwardPropertyToEditor(const char *key);
918 	void DefineMarker(SA::MarkerOutline marker, SA::MarkerSymbol markerType, SA::Colour fore, SA::Colour back, SA::Colour backSelected);
919 	void ReadAPI(const std::string &fileNameForExtension);
920 	std::string FindLanguageProperty(const char *pattern, const char *defaultValue = "");
921 	virtual void ReadProperties();
922 	std::string StyleString(const char *lang, int style) const;
923 	StyleDefinition StyleDefinitionFor(int style);
924 	void SetOneStyle(GUI::ScintillaWindow &win, int style, const StyleDefinition &sd);
925 	void SetStyleBlock(GUI::ScintillaWindow &win, const char *lang, int start, int last);
926 	void SetStyleFor(GUI::ScintillaWindow &win, const char *lang);
927 	static void SetOneIndicator(GUI::ScintillaWindow &win, int indicator, const IndicatorDefinition &ind);
928 	void ReloadProperties();
929 
930 	void CheckReload();
931 	void Activate(bool activeApp);
932 	GUI::Rectangle GetClientRectangle();
933 	void Redraw();
934 	int NormaliseSplit(int splitPos);
935 	void MoveSplit(GUI::Point ptNewDrag);
936 
937 	virtual void TimerStart(int mask);
938 	virtual void TimerEnd(int mask);
939 	void OnTimer();
940 	virtual void SetIdler(bool on);
941 	void OnIdle();
942 
943 	void SetHomeProperties();
944 	void UIAvailable();
945 	void PerformOne(char *action);
946 	void StartRecordMacro();
947 	void StopRecordMacro();
948 	void StartPlayMacro();
949 	bool RecordMacroCommand(const SCNotification *notification);
950 	void ExecuteMacroCommand(const char *command);
951 	void AskMacroList();
952 	bool StartMacroList(const char *words);
953 	void ContinueMacroList(const char *stext);
954 	bool ProcessCommandLine(const GUI::gui_string &args, int phase);
955 	virtual bool IsStdinBlocked();
956 	void OpenFromStdin(bool UseOutputPane);
957 	void OpenFilesFromStdin();
958 	enum GrepFlags {
959 		grepNone = 0, grepWholeWord = 1, grepMatchCase = 2, grepStdOut = 4,
960 		grepDot = 8, grepBinary = 16, grepScroll = 32
961 	};
962 	virtual bool GrepIntoDirectory(const FilePath &directory);
963 	void GrepRecursive(GrepFlags gf, const FilePath &baseDir, const char *searchString, const GUI::gui_char *fileTypes);
964 	void InternalGrep(GrepFlags gf, const GUI::gui_char *directory, const GUI::gui_char *fileTypes,
965 			  const char *search, SA::Position &originalEnd);
966 	void EnumProperties(const char *propkind);
967 	void SendOneProperty(const char *kind, const char *key, const char *val);
968 	void PropertyFromDirector(const char *arg);
969 	void PropertyToDirector(const char *arg);
970 	// ExtensionAPI
971 	intptr_t Send(Pane p, SA::Message msg, uintptr_t wParam = 0, intptr_t lParam = 0) override;
972 	std::string Range(Pane p, SA::Range range) override;
973 	void Remove(Pane p, SA::Position start, SA::Position end) override;
974 	void Insert(Pane p, SA::Position pos, const char *s) override;
975 	void Trace(const char *s) override;
976 	std::string Property(const char *key) override;
977 	void SetProperty(const char *key, const char *val) override;
978 	void UnsetProperty(const char *key) override;
979 	uintptr_t GetInstance() override;
980 	void ShutDown() override;
981 	void Perform(const char *actionList) override;
982 	void DoMenuCommand(int cmdID) override;
983 	SA::ScintillaCall &PaneCaller(Pane p) noexcept override;
984 
985 	// Valid CurrentWord characters
986 	bool iswordcharforsel(char ch);
987 	bool isfilenamecharforsel(char ch);
988 	bool islexerwordcharforsel(char ch);
989 
990 	CurrentWordHighlight currentWordHighlight;
991 	void HighlightCurrentWord(bool highlight);
992 	MatchMarker matchMarker;
993 	MatchMarker findMarker;
994 public:
995 
996 	enum { maxParam = 4 };
997 
998 	explicit SciTEBase(Extension *ext = 0);
999 	// Deleted copy-constructor and assignment operator.
1000 	SciTEBase(const SciTEBase &) = delete;
1001 	SciTEBase(SciTEBase &&) = delete;
1002 	void operator=(const SciTEBase &) = delete;
1003 	void operator=(SciTEBase &&) = delete;
1004 	~SciTEBase() override;
1005 
1006 	void Finalise();
1007 
GetID()1008 	GUI::WindowID GetID() const noexcept { return wSciTE.GetID(); }
1009 
1010 	bool PerformOnNewThread(Worker *pWorker);
1011 	// WorkerListener
1012 	void PostOnMainThread(int cmd, Worker *pWorker) override = 0;
1013 	virtual void WorkerCommand(int cmd, Worker *pWorker);
1014 };
1015 
1016 int ControlIDOfCommand(unsigned long) noexcept;
1017 SA::Colour ColourOfProperty(const PropSetFile &props, const char *key, SA::Colour colourDefault);
1018 void WindowSetFocus(GUI::ScintillaWindow &w);
1019 
1020 // Test if an enum class value has the bit flag(s) of test set.
1021 template <typename T>
FlagIsSet(T value,T test)1022 constexpr bool FlagIsSet(T value, T test) {
1023 	return (static_cast<int>(value) & static_cast<int>(test)) == static_cast<int>(test);
1024 }
1025 
1026 #endif
1027