From bdd76fe5e677cd4079cdb5681f25b1929c925822 Mon Sep 17 00:00:00 2001 From: blu3mania Date: Mon, 28 Aug 2023 23:02:38 -0400 Subject: [PATCH] Added configs to support the use of the new NPPM_ALLOCATEINDICATOR messages to automatically allocate indicator IDs for keyword matcher and error annotator. --- Configuration.md | 25 +++-- src/Plugin/Common/NotepadPlusPlus.cpp | 20 ++++ src/Plugin/Common/NotepadPlusPlus.hpp | 6 ++ src/Plugin/Common/Resources.hpp | 2 + .../ErrorAnnotator.cpp | 99 ++++++++++--------- .../ErrorAnnotator.hpp | 16 ++- .../ErrorAnnotatorSettings.hpp | 3 +- src/Plugin/KeywordMatcher/KeywordMatcher.cpp | 62 +++++++++--- src/Plugin/KeywordMatcher/KeywordMatcher.hpp | 13 ++- .../KeywordMatcher/KeywordMatcherSettings.hpp | 3 +- src/Plugin/Plugin.cpp | 21 ++-- src/Plugin/Plugin.hpp | 5 +- src/Plugin/Resources.rc | 8 +- src/Plugin/Settings/Settings.cpp | 56 ++++++++--- src/Plugin/Settings/SettingsDialog.cpp | 32 ++++-- 15 files changed, 250 insertions(+), 121 deletions(-) diff --git a/Configuration.md b/Configuration.md index 0522faa..22759a4 100644 --- a/Configuration.md +++ b/Configuration.md @@ -74,10 +74,17 @@ In the rare case when a keyword cannot be matched, like when there is a typo, or definition, unmatched style will be used to highlight. It is configurable as well and by default it is a red rectangle. -Usually the default indicator ID (17) won't conflict with other plugins. However, there is no guarantee that -will never happen, so this plugin allows you to choose a different indicator if there is a conflict. The -valid numbers are between 9 and 20. Keep in mind other plugins may use indicator IDs as well, for example, -DSpellCheck uses 19. Make sure you **do not** change this ID if everything works fine. +For the indicator ID, it is recommended to ask Notepad++ to auto allocate indicator ID. If all plugins are +doing it this way then there will not be conflicts. Though, due to the limited number of indicator IDs (only +between 9 and 20), if many plugins are using indicators then the pool could be drained by the time this plugin +asks for an allocation. In such a case this plugin will fall back to the configured default indicator ID (by +default 17). Of course it means there will be conflicts but there really isn't a good solution. Try to remove +some unused plugins, and see if the issue is solved. Also, there might be plugins that are still using +hardcoded indicator IDs, and in that case there is no guarantee that the indicator ID allocated by Notepad++ +won't conflict with those plugins. In either case, this plugin allows you to choose a default indicator ID +for fallback, or to avoid conflict with plugins using hardcoded indicator IDs. The valid numbers are between +9 and 20. Keep in mind other plugins may use indicator IDs as well, for example, DSpellCheck uses 19. Make +sure you **do not** turn off auto allocation or change this ID if default settings work fine. ## Error Annotator tab @@ -94,11 +101,11 @@ in the same annotation box. Show indications where errors happen. By default, the indicator is a red squiggly line under the word or operator where error is, similar to what a spell checker does. There are many styles to choose from. -Similar to Keyword Matcher's indicator ID, Error Annotator's indicator ID can be changed as well. The -default ID (18) should not cause conflict usually, but if it does, follow the same instructions provided -in [Keyword Matcher tab](#keyword-matcher-tab) section. *Note*, after changing it, existing indications -may be rendered incorrectly if edits have been made. You can recompile the script to make them show -correctly again, or simply fix all bugs reported against your script. 😀 +Similar to Keyword Matcher's indicator ID, Error Annotator's indicator ID can be changed as well. Follow +the same instructions provided in [Keyword Matcher tab](#keyword-matcher-tab) section. *Note*, after +changing indicator ID, existing indications may be rendered incorrectly if edits have been made. You can +recompile the script to make them show correctly again, or simply fix all bugs reported against your +script. 😀 ## Compiler tab diff --git a/src/Plugin/Common/NotepadPlusPlus.cpp b/src/Plugin/Common/NotepadPlusPlus.cpp index 8176430..0b00fb9 100644 --- a/src/Plugin/Common/NotepadPlusPlus.cpp +++ b/src/Plugin/Common/NotepadPlusPlus.cpp @@ -19,8 +19,11 @@ along with this program. If not, see . #include "NotepadPlusPlus.hpp" +#include "StringUtil.hpp" + #include "..\..\external\gsl\include\gsl\util" #include "..\..\external\npp\Notepad_plus_msgs.h" +#include "..\..\external\npp\PluginInterface.h" namespace utility { @@ -51,4 +54,21 @@ namespace utility { return bufferID; } + std::wstring getApplicableFilePathOnView(HWND nppHandle, npp_view_t view) { + // Make sure it is a Papyrus script + std::wstring filePath = getActiveFilePathOnView(nppHandle, view); + if (endsWith(filePath, L".psc") || endsWith(filePath, L".pas")) { + return filePath; + } + + return std::wstring(); + } + + void clearIndications(HWND handle, int indicatorID) { + // Need to specify which indicator to be cleared. + ::SendMessage(handle, SCI_SETINDICATORCURRENT, indicatorID, 0); + npp_length_t docLength = ::SendMessage(handle, SCI_GETLENGTH, 0, 0); + ::SendMessage(handle, SCI_INDICATORCLEARRANGE, 0, docLength); + } + } // namespace diff --git a/src/Plugin/Common/NotepadPlusPlus.hpp b/src/Plugin/Common/NotepadPlusPlus.hpp index 869af56..9b10ca0 100644 --- a/src/Plugin/Common/NotepadPlusPlus.hpp +++ b/src/Plugin/Common/NotepadPlusPlus.hpp @@ -59,4 +59,10 @@ namespace utility { return (bufferID != 0 ? getFilePathFromBuffer(nppHandle, bufferID) : std::wstring()); } + // Retrieve the full file path of the active document on a given view, if it is a Papyrus script + std::wstring getApplicableFilePathOnView(HWND nppHandle, npp_view_t view); + + // Clear existing indications drawn with a given indicator + void clearIndications(HWND handle, int indicatorID); + } // namespace diff --git a/src/Plugin/Common/Resources.hpp b/src/Plugin/Common/Resources.hpp index eda51dc..14b5ceb 100644 --- a/src/Plugin/Common/Resources.hpp +++ b/src/Plugin/Common/Resources.hpp @@ -123,6 +123,7 @@ along with this program. If not, see . #define IDC_SETTINGS_MATCHER_INDICATOR_ID_LABEL (IDC_SETTINGS_MATCHER + 21) #define IDC_SETTINGS_MATCHER_INDICATOR_ID (IDC_SETTINGS_MATCHER_INDICATOR_ID_LABEL + 1) #define IDS_SETTINGS_MATCHER_INDICATOR_ID_TOOLTIP (IDC_SETTINGS_MATCHER_INDICATOR_ID + 1) +#define IDC_SETTINGS_MATCHER_INDICATOR_ID_AUTO_ALLOCATE (IDC_SETTINGS_MATCHER_INDICATOR_ID + 2) #define IDC_SETTINGS_MATCHER_MATCHED_STYLE_LABEL (IDC_SETTINGS_MATCHER + 31) #define IDC_SETTINGS_MATCHER_MATCHED_STYLE_DROPDOWN (IDC_SETTINGS_MATCHER_MATCHED_STYLE_LABEL + 1) #define IDC_SETTINGS_MATCHER_MATCHED_FGCOLOR_LABEL (IDC_SETTINGS_MATCHER_MATCHED_STYLE_LABEL + 2) @@ -144,6 +145,7 @@ along with this program. If not, see . #define IDC_SETTINGS_ANNOTATOR_INDICATOR_ID_LABEL (IDC_SETTINGS_ANNOTATOR_ENABLE_INDICATION + 2) #define IDC_SETTINGS_ANNOTATOR_INDICATOR_ID (IDC_SETTINGS_ANNOTATOR_INDICATOR_ID_LABEL + 1) #define IDS_SETTINGS_ANNOTATOR_INDICATOR_ID_TOOLTIP (IDC_SETTINGS_ANNOTATOR_INDICATOR_ID + 1) +#define IDC_SETTINGS_ANNOTATOR_INDICATOR_ID_AUTO_ALLOCATE (IDC_SETTINGS_ANNOTATOR_INDICATOR_ID + 2) #define IDC_SETTINGS_ANNOTATOR_INDICATOR_STYLE_LABEL (IDC_SETTINGS_ANNOTATOR_ENABLE_INDICATION + 11) #define IDC_SETTINGS_ANNOTATOR_INDICATOR_STYLE_DROPDOWN (IDC_SETTINGS_ANNOTATOR_INDICATOR_STYLE_LABEL + 1) #define IDC_SETTINGS_ANNOTATOR_INDICATOR_FGCOLOR_LABEL (IDC_SETTINGS_ANNOTATOR_INDICATOR_STYLE_LABEL + 2) diff --git a/src/Plugin/CompilationErrorHandling/ErrorAnnotator.cpp b/src/Plugin/CompilationErrorHandling/ErrorAnnotator.cpp index 6a72d15..9ede952 100644 --- a/src/Plugin/CompilationErrorHandling/ErrorAnnotator.cpp +++ b/src/Plugin/CompilationErrorHandling/ErrorAnnotator.cpp @@ -21,6 +21,7 @@ along with this program. If not, see . #include "ErrorAnnotator.hpp" +#include "..\Common\Logger.hpp" #include "..\Common\StringUtil.hpp" #include "..\..\external\gsl\include\gsl\util" @@ -43,7 +44,8 @@ namespace papyrus { subscribableSettings.isAnnotationBold.subscribe([&](auto) { updateAnnotationStyle(); }); subscribableSettings.enableIndication.subscribe([&](auto) { updateIndicatorStyle(); }); - subscribableSettings.indicatorID.subscribe([&](auto eventData) { changeIndicator(eventData.oldValue); }); + subscribableSettings.autoAllocateIndicatorID.subscribe([&](auto) { changeIndicator(); }); + subscribableSettings.defaultIndicatorID.subscribe([&](auto) { changeIndicator(); }); subscribableSettings.indicatorStyle.subscribe([&](auto) { updateIndicatorStyle(); }); subscribableSettings.indicatorForegroundColor.subscribe([&](auto) { updateIndicatorStyle(); }); } @@ -62,11 +64,11 @@ namespace papyrus { errors.clear(); // Check and clear all annotations from both views. - if (!getApplicableFilePathOnView(MAIN_VIEW).empty()) { + if (!utility::getApplicableFilePathOnView(nppData._nppHandle, MAIN_VIEW).empty()) { clearAnnotations(nppData._scintillaMainHandle); clearIndications(nppData._scintillaMainHandle); } - if (!getApplicableFilePathOnView(SUB_VIEW).empty()) { + if (!utility::getApplicableFilePathOnView(nppData._nppHandle, SUB_VIEW).empty()) { clearAnnotations(nppData._scintillaSecondHandle); clearIndications(nppData._scintillaSecondHandle); } @@ -131,19 +133,9 @@ namespace papyrus { // Private methods // - std::wstring ErrorAnnotator::getApplicableFilePathOnView(npp_view_t view) const { - // Make sure it is a Papyrus script - std::wstring filePath = utility::getActiveFilePathOnView(nppData._nppHandle, view); - if (utility::endsWith(filePath, L".psc") || utility::endsWith(filePath, L".pas")) { - return filePath; - } - - return std::wstring(); - } - void ErrorAnnotator::annotate(npp_view_t view) { // Annotate current file on the given view if it's Papyrus script. - std::wstring filePath = getApplicableFilePathOnView(view); + std::wstring filePath = utility::getApplicableFilePathOnView(nppData._nppHandle, view); if (!filePath.empty()) { annotate(view, filePath); } else { @@ -158,14 +150,7 @@ namespace papyrus { } void ErrorAnnotator::clearIndications(HWND handle) const { - clearIndications(handle, settings.indicatorID); - } - - void ErrorAnnotator::clearIndications(HWND handle, int indicator) const { - // Need to specify which indicator to be cleared. - ::SendMessage(handle, SCI_SETINDICATORCURRENT, indicator, 0); - npp_length_t docLength = ::SendMessage(handle, SCI_GETLENGTH, 0, 0); - ::SendMessage(handle, SCI_INDICATORCLEARRANGE, 0, docLength); + utility::clearIndications(handle, indicatorID); } void ErrorAnnotator::showAnnotations(HWND handle) const { @@ -177,19 +162,19 @@ namespace papyrus { } void ErrorAnnotator::showIndications(HWND handle) const { - ::SendMessage(handle, SCI_INDICSETSTYLE, settings.indicatorID, settings.indicatorStyle); + ::SendMessage(handle, SCI_INDICSETSTYLE, indicatorID, settings.indicatorStyle); } void ErrorAnnotator::hideIndications(HWND handle) const { - ::SendMessage(handle, SCI_INDICSETSTYLE, settings.indicatorID, INDIC_HIDDEN); + ::SendMessage(handle, SCI_INDICSETSTYLE, indicatorID, INDIC_HIDDEN); } void ErrorAnnotator::updateAnnotationStyle() { // Update annotation style of the current file on the given view if it's Papyrus script. - if (!getApplicableFilePathOnView(MAIN_VIEW).empty()) { + if (!utility::getApplicableFilePathOnView(nppData._nppHandle, MAIN_VIEW).empty()) { updateAnnotationStyle(MAIN_VIEW, nppData._scintillaMainHandle); } - if (!getApplicableFilePathOnView(SUB_VIEW).empty()) { + if (!utility::getApplicableFilePathOnView(nppData._nppHandle, SUB_VIEW).empty()) { updateAnnotationStyle(SUB_VIEW, nppData._scintillaSecondHandle); } } @@ -217,40 +202,62 @@ namespace papyrus { } // Since indication locations are not tracked after they were draw, calling this method could cause newly rendered indications to be off. - void ErrorAnnotator::changeIndicator(int oldIndicator) { - // Clear indications from both views if they are Papyrus scripts. - std::wstring mainViewFilePath = getApplicableFilePathOnView(MAIN_VIEW); - if (!mainViewFilePath.empty()) { - clearIndications(nppData._scintillaMainHandle, oldIndicator); - } - std::wstring secondViewFilePath = getApplicableFilePathOnView(SUB_VIEW); - if (!secondViewFilePath.empty()) { - clearIndications(nppData._scintillaSecondHandle, oldIndicator); - } + void ErrorAnnotator::changeIndicator() { + int oldIndicatorID = indicatorID; + if (settings.autoAllocateIndicatorID) { + if (allocatedIndicatorID == 0) { + if (!static_cast(::SendMessage(nppData._nppHandle, NPPM_ALLOCATEINDICATOR, 1, reinterpret_cast(&allocatedIndicatorID)))) { + // Likely no available indicator ID left. + allocatedIndicatorID = -1; + } + //utility::logger.log(L"Allocated error annotator indicator ID: " + std::to_wstring(allocatedIndicatorID)); + } - // Draw new indications if needed. - if (!mainViewFilePath.empty()) { - updateIndicatorStyleOnFile(nppData._scintillaMainHandle, mainViewFilePath); + if (allocatedIndicatorID > 0) { + indicatorID = allocatedIndicatorID; + } else if (settings.defaultIndicatorID > 0) { + indicatorID = settings.defaultIndicatorID; + } + } else if (settings.defaultIndicatorID > 0) { + indicatorID = settings.defaultIndicatorID; } - if (!secondViewFilePath.empty()) { - updateIndicatorStyleOnFile(nppData._scintillaSecondHandle, secondViewFilePath); + //utility::logger.log(L"Error annotator uses indicator ID: " + std::to_wstring(indicatorID)); + + if (indicatorID != oldIndicatorID) { + // Clear indications from both views if they are Papyrus scripts. + std::wstring mainViewFilePath = utility::getApplicableFilePathOnView(nppData._nppHandle, MAIN_VIEW); + if (!mainViewFilePath.empty()) { + utility::clearIndications(nppData._scintillaMainHandle, oldIndicatorID); + } + std::wstring secondViewFilePath = utility::getApplicableFilePathOnView(nppData._nppHandle, SUB_VIEW); + if (!secondViewFilePath.empty()) { + utility::clearIndications(nppData._scintillaSecondHandle, oldIndicatorID); + } + + // Draw new indications if needed. + if (!mainViewFilePath.empty()) { + updateIndicatorStyleOnFile(nppData._scintillaMainHandle, mainViewFilePath); + } + if (!secondViewFilePath.empty()) { + updateIndicatorStyleOnFile(nppData._scintillaSecondHandle, secondViewFilePath); + } } } void ErrorAnnotator::updateIndicatorStyle() { // Update indicator style of the current file on the given view if it's Papyrus script. - if (!getApplicableFilePathOnView(MAIN_VIEW).empty()) { + if (!utility::getApplicableFilePathOnView(nppData._nppHandle, MAIN_VIEW).empty()) { updateIndicatorStyle(nppData._scintillaMainHandle); } - if (!getApplicableFilePathOnView(SUB_VIEW).empty()) { + if (!utility::getApplicableFilePathOnView(nppData._nppHandle, SUB_VIEW).empty()) { updateIndicatorStyle(nppData._scintillaSecondHandle); } } void ErrorAnnotator::updateIndicatorStyle(HWND handle) const { - ::SendMessage(handle, SCI_INDICSETFORE, settings.indicatorID, settings.indicatorForegroundColor); - ::SendMessage(handle, SCI_SETINDICATORCURRENT, settings.indicatorID, 0); - ::SendMessage(handle, SCI_INDICSETOUTLINEALPHA, settings.indicatorID, 255); // Always make indicator's outline opaque + ::SendMessage(handle, SCI_INDICSETFORE, indicatorID, settings.indicatorForegroundColor); + ::SendMessage(handle, SCI_SETINDICATORCURRENT, indicatorID, 0); + ::SendMessage(handle, SCI_INDICSETOUTLINEALPHA, indicatorID, 255); // Always make indicator's outline opaque settings.enableIndication ? showIndications(handle) : hideIndications(handle); } diff --git a/src/Plugin/CompilationErrorHandling/ErrorAnnotator.hpp b/src/Plugin/CompilationErrorHandling/ErrorAnnotator.hpp index 8f65b10..51648b8 100644 --- a/src/Plugin/CompilationErrorHandling/ErrorAnnotator.hpp +++ b/src/Plugin/CompilationErrorHandling/ErrorAnnotator.hpp @@ -53,15 +53,11 @@ namespace papyrus { using FileErrors = std::list; - // Get current file path on the given view, if it's a applicable - std::wstring getApplicableFilePathOnView(npp_view_t view) const; - // Annotate current buffer on a given view, if it has errors void annotate(npp_view_t view); void clearAnnotations(HWND handle) const; void clearIndications(HWND handle) const; - void clearIndications(HWND handle, int indicator) const; void showAnnotations(HWND handle) const; void hideAnnotations(HWND handle) const; @@ -73,11 +69,10 @@ namespace papyrus { void drawAnnotations(HWND handle, const LineError& lineError) const; - // Change indiator ID. - // Scintilla reserves indicator 8-31 for containers. Notepad++ itself uses 8, and SciLexher.h defines most - // of IDs above 20, which NPP uses. - // By default 18 is used ny this plugin, but other plugins could cause conflicts, e.g. DSpellCheck uses 19. - void changeIndicator(int oldIndicator); + // Change indicator ID. + // Scintilla reserves indicator 8-31 for containers. Notepad++ itself uses 8, and SciLexher.h defines most of IDs above 20, which NPP uses. + // By default 18 is used for error annotation, but other plugins could cause conflicts, e.g. DSpellCheck uses 19. It is recommended to auto allocate. + void changeIndicator(); void updateIndicatorStyle(); void updateIndicatorStyle(HWND handle) const; @@ -91,6 +86,9 @@ namespace papyrus { const ErrorAnnotatorSettings& settings; std::map errors; + int indicatorID {0}; + int allocatedIndicatorID {0}; + int mainViewStyleAssigned {0}; int secondViewStyleAssigned {0}; }; diff --git a/src/Plugin/CompilationErrorHandling/ErrorAnnotatorSettings.hpp b/src/Plugin/CompilationErrorHandling/ErrorAnnotatorSettings.hpp index e6eb8d0..c82f9d7 100644 --- a/src/Plugin/CompilationErrorHandling/ErrorAnnotatorSettings.hpp +++ b/src/Plugin/CompilationErrorHandling/ErrorAnnotatorSettings.hpp @@ -36,7 +36,8 @@ namespace papyrus { utility::PrimitiveTypeValueMonitor isAnnotationItalic; utility::PrimitiveTypeValueMonitor isAnnotationBold; utility::PrimitiveTypeValueMonitor enableIndication; - utility::PrimitiveTypeValueMonitor indicatorID; + utility::PrimitiveTypeValueMonitor autoAllocateIndicatorID; + utility::PrimitiveTypeValueMonitor defaultIndicatorID; utility::PrimitiveTypeValueMonitor indicatorStyle; utility::PrimitiveTypeValueMonitor indicatorForegroundColor; }; diff --git a/src/Plugin/KeywordMatcher/KeywordMatcher.cpp b/src/Plugin/KeywordMatcher/KeywordMatcher.cpp index 541db06..f376925 100644 --- a/src/Plugin/KeywordMatcher/KeywordMatcher.cpp +++ b/src/Plugin/KeywordMatcher/KeywordMatcher.cpp @@ -19,6 +19,7 @@ along with this program. If not, see . #include "KeywordMatcher.hpp" +#include "..\Common\Logger.hpp" #include "..\Common\StringUtil.hpp" #include "..\Lexer\Lexer.hpp" @@ -51,13 +52,14 @@ namespace papyrus { ::SendMessage(handle, SCI_SETSEARCHFLAGS, flags, 0); } - KeywordMatcher::KeywordMatcher(const KeywordMatcherSettings& settings) - : settings(settings) { + KeywordMatcher::KeywordMatcher(const NppData& nppData, const KeywordMatcherSettings& settings) + : nppData(nppData), settings(settings) { // Subscribe to settings changes KeywordMatcherSettings& subscribableSettings = const_cast(settings); subscribableSettings.enableKeywordMatching.subscribe([&](auto) { match(); }); subscribableSettings.enabledKeywords.subscribe([&](auto) { match(); }); - subscribableSettings.indicatorID.subscribe([&](auto eventData) { changeIndicator(eventData.oldValue); }); + subscribableSettings.autoAllocateIndicatorID.subscribe([&](auto) { changeIndicator(); }); + subscribableSettings.defaultIndicatorID.subscribe([&](auto) { changeIndicator(); }); subscribableSettings.matchedIndicatorStyle.subscribe([&](auto) { if (handle != 0 && matched) { setupIndicator(); } }); subscribableSettings.matchedIndicatorForegroundColor.subscribe([&](auto) { if (handle != 0 && matched) { setupIndicator(); } }); subscribableSettings.unmatchedIndicatorStyle.subscribe([&](auto) { if (handle != 0 && !matched) { setupIndicator(); } }); @@ -73,7 +75,7 @@ namespace papyrus { void KeywordMatcher::clear() { if (handle != 0) { docLength = static_cast(::SendMessage(handle, SCI_GETLENGTH, 0, 0)); - ::SendMessage(handle, SCI_SETINDICATORCURRENT, settings.indicatorID, 0); + ::SendMessage(handle, SCI_SETINDICATORCURRENT, indicatorID, 0); ::SendMessage(handle, SCI_INDICATORCLEARRANGE, 0, docLength); matched = false; @@ -340,25 +342,57 @@ namespace papyrus { } void KeywordMatcher::setupIndicator() { - ::SendMessage(handle, SCI_INDICSETFORE, settings.indicatorID, matched ? settings.matchedIndicatorForegroundColor : settings.unmatchedIndicatorForegroundColor); - ::SendMessage(handle, SCI_SETINDICATORCURRENT, settings.indicatorID, 0); - ::SendMessage(handle, SCI_INDICSETOUTLINEALPHA, settings.indicatorID, 255); // Always make indicator's outline opaque + ::SendMessage(handle, SCI_INDICSETFORE, indicatorID, matched ? settings.matchedIndicatorForegroundColor : settings.unmatchedIndicatorForegroundColor); + ::SendMessage(handle, SCI_SETINDICATORCURRENT, indicatorID, 0); + ::SendMessage(handle, SCI_INDICSETOUTLINEALPHA, indicatorID, 255); // Always make indicator's outline opaque settings.enableKeywordMatching ? showIndicator() : hideIndicator(); } void KeywordMatcher::showIndicator() { - ::SendMessage(handle, SCI_INDICSETSTYLE, settings.indicatorID, matched ? settings.matchedIndicatorStyle : settings.unmatchedIndicatorStyle); + ::SendMessage(handle, SCI_INDICSETSTYLE, indicatorID, matched ? settings.matchedIndicatorStyle : settings.unmatchedIndicatorStyle); } void KeywordMatcher::hideIndicator() { - ::SendMessage(handle, SCI_INDICSETSTYLE, settings.indicatorID, INDIC_HIDDEN); + ::SendMessage(handle, SCI_INDICSETSTYLE, indicatorID, INDIC_HIDDEN); } - void KeywordMatcher::changeIndicator(int oldIndicator) { - if (handle != 0) { - ::SendMessage(handle, SCI_SETINDICATORCURRENT, oldIndicator, 0); - ::SendMessage(handle, SCI_INDICATORCLEARRANGE, 0, docLength); - match(); + void KeywordMatcher::changeIndicator() { + int oldIndicatorID = indicatorID; + if (settings.autoAllocateIndicatorID) { + if (allocatedIndicatorID == 0) { + if (!static_cast(::SendMessage(nppData._nppHandle, NPPM_ALLOCATEINDICATOR, 1, reinterpret_cast(&allocatedIndicatorID)))) { + // Likely no available indicator ID left. + allocatedIndicatorID = -1; + } + //utility::logger.log(L"Allocated keyword matcher indicator ID: " + std::to_wstring(allocatedIndicatorID)); + } + + if (allocatedIndicatorID > 0) { + indicatorID = allocatedIndicatorID; + } else if (settings.defaultIndicatorID > 0) { + indicatorID = settings.defaultIndicatorID; + } + } else if (settings.defaultIndicatorID > 0) { + indicatorID = settings.defaultIndicatorID; + } + //utility::logger.log(L"Keyword matcher uses indicator ID: " + std::to_wstring(indicatorID)); + + if (indicatorID != oldIndicatorID) { + // Clear indications from both views if they are Papyrus scripts. + std::wstring mainViewFilePath = utility::getApplicableFilePathOnView(nppData._nppHandle, MAIN_VIEW); + if (!mainViewFilePath.empty()) { + utility::clearIndications(nppData._scintillaMainHandle, oldIndicatorID); + } + std::wstring secondViewFilePath = utility::getApplicableFilePathOnView(nppData._nppHandle, SUB_VIEW); + if (!secondViewFilePath.empty()) { + utility::clearIndications(nppData._scintillaSecondHandle, oldIndicatorID); + } + + if (handle != 0) { + ::SendMessage(handle, SCI_SETINDICATORCURRENT, indicatorID, 0); + ::SendMessage(handle, SCI_INDICATORCLEARRANGE, 0, docLength); + match(); + } } } diff --git a/src/Plugin/KeywordMatcher/KeywordMatcher.hpp b/src/Plugin/KeywordMatcher/KeywordMatcher.hpp index 530a73f..9870c9e 100644 --- a/src/Plugin/KeywordMatcher/KeywordMatcher.hpp +++ b/src/Plugin/KeywordMatcher/KeywordMatcher.hpp @@ -45,7 +45,7 @@ namespace papyrus { int flags; }; - KeywordMatcher(const KeywordMatcherSettings& settings); + KeywordMatcher(const NppData& nppData, const KeywordMatcherSettings& settings); bool match(HWND scintillaHandle); inline void goToMatchedPos() const { @@ -71,13 +71,22 @@ namespace papyrus { void setupIndicator(); void showIndicator(); void hideIndicator(); - void changeIndicator(int oldIndicator); + + // Change indicator ID. + // Scintilla reserves indicator 8-31 for containers. Notepad++ itself uses 8, and SciLexher.h defines most of IDs above 20, which NPP uses. + // By default 17 is used for keyword matcher, but other plugins could cause conflicts, e.g. DSpellCheck uses 19. It is recommended to auto allocate. + void changeIndicator(); // Private members // + const NppData& nppData; const KeywordMatcherSettings& settings; HWND handle {0}; Sci_PositionCR docLength {0}; + + int indicatorID {0}; + int allocatedIndicatorID {0}; + bool matched {false}; Sci_PositionCR matchedPos {0}; }; diff --git a/src/Plugin/KeywordMatcher/KeywordMatcherSettings.hpp b/src/Plugin/KeywordMatcher/KeywordMatcherSettings.hpp index 963b273..d631f1e 100644 --- a/src/Plugin/KeywordMatcher/KeywordMatcherSettings.hpp +++ b/src/Plugin/KeywordMatcher/KeywordMatcherSettings.hpp @@ -44,7 +44,8 @@ namespace papyrus { struct KeywordMatcherSettings { utility::PrimitiveTypeValueMonitor enableKeywordMatching; utility::PrimitiveTypeValueMonitor enabledKeywords; - utility::PrimitiveTypeValueMonitor indicatorID; + utility::PrimitiveTypeValueMonitor autoAllocateIndicatorID; + utility::PrimitiveTypeValueMonitor defaultIndicatorID; utility::PrimitiveTypeValueMonitor matchedIndicatorStyle; utility::PrimitiveTypeValueMonitor matchedIndicatorForegroundColor; utility::PrimitiveTypeValueMonitor unmatchedIndicatorStyle; diff --git a/src/Plugin/Plugin.cpp b/src/Plugin/Plugin.cpp index 5393743..457d993 100644 --- a/src/Plugin/Plugin.cpp +++ b/src/Plugin/Plugin.cpp @@ -77,7 +77,7 @@ namespace papyrus { FuncItem{ L"Advanced", advancedMenuFunc, 0, false, nullptr }, FuncItem{}, // Separator2 FuncItem{ L"About...", aboutMenuFunc, 0, false, nullptr } - }, keywordMatcher(settings.keywordMatcherSettings) { + } { } void Plugin::onInit(HINSTANCE instance) { @@ -212,6 +212,7 @@ namespace papyrus { lexerData = std::make_unique(nppData, settings.lexerSettings); errorsWindow = std::make_unique(myInstance, nppData._nppHandle, messageWindow); errorAnnotator = std::make_unique(nppData, settings.errorAnnotatorSettings); + keywordMatcher = std::make_unique(nppData, settings.keywordMatcherSettings); settingsDialog.init(myInstance, nppData._nppHandle); aboutDialog.init(myInstance, nppData._nppHandle); @@ -377,17 +378,19 @@ namespace papyrus { ::SendMessage(nppData._nppHandle, NPPM_SETSTATUSBAR, STATUSBAR_DOC_TYPE, reinterpret_cast(gameSpecificStatus.c_str())); } - keywordMatched = keywordMatcher.match(scintillaHandle); - } else if (isPapyrusScriptFile && fromLangChange) { + if (keywordMatcher) { + keywordMatched = keywordMatcher->match(scintillaHandle); + } + } else if (isPapyrusScriptFile && fromLangChange && keywordMatcher) { // Papyrus script file changed to other language, clear keyword matching. - keywordMatcher.clear(); + keywordMatcher->clear(); } HMENU menu = reinterpret_cast(::SendMessage(nppData._nppHandle, NPPM_GETMENUHANDLE, 0, 0)); ::EnableMenuItem(menu, funcs[std::to_underlying(Menu::GoToMatch)]._cmdID, MF_BYCOMMAND | (keywordMatched ? MF_ENABLED : MF_DISABLED)); // Only Papyrus script and assembly files can be annotated. - if (errorAnnotator && (isPapyrusScriptFile || utility::endsWith(filePath, L".pas")) && !fromLangChange) { + if ((isPapyrusScriptFile || utility::endsWith(filePath, L".pas")) && !fromLangChange && errorAnnotator) { errorAnnotator->annotate(currentView, filePath); } @@ -449,8 +452,8 @@ namespace papyrus { void Plugin::handleSelectionChange(SCNotification* notification) { // Only handle selection change if it's from a document buffer shown on current view and is managed by this plugin's lexer. bool keywordMatched = false; - if (isCurrentBufferManaged(static_cast(notification->nmhdr.hwndFrom))) { - keywordMatched = keywordMatcher.match(static_cast(notification->nmhdr.hwndFrom)); + if (isCurrentBufferManaged(static_cast(notification->nmhdr.hwndFrom)) && keywordMatcher) { + keywordMatched = keywordMatcher->match(static_cast(notification->nmhdr.hwndFrom)); } HMENU menu = reinterpret_cast(::SendMessage(nppData._nppHandle, NPPM_GETMENUHANDLE, 0, 0)); @@ -912,7 +915,9 @@ namespace papyrus { } void Plugin::goToMatch() { - keywordMatcher.goToMatchedPos(); + if (keywordMatcher) { + keywordMatcher->goToMatchedPos(); + } } void Plugin::settingsMenuFunc() { diff --git a/src/Plugin/Plugin.hpp b/src/Plugin/Plugin.hpp index 62143a8..fbe55d1 100644 --- a/src/Plugin/Plugin.hpp +++ b/src/Plugin/Plugin.hpp @@ -172,15 +172,14 @@ namespace papyrus { CompilationRequest activeCompilationRequest; bool isCompilingCurrentFile {false}; - std::unique_ptr errorAnnotator; std::unique_ptr errorsWindow; + std::unique_ptr errorAnnotator; + std::unique_ptr keywordMatcher; std::list activatedErrorsTrackingList; std::unique_ptr jumpToErrorLineTimer; npp_lang_type_t scriptLangID {0}; - KeywordMatcher keywordMatcher; - AboutDialog aboutDialog; bool isShuttingDown {false}; diff --git a/src/Plugin/Resources.rc b/src/Plugin/Resources.rc index a310989..6129a26 100644 --- a/src/Plugin/Resources.rc +++ b/src/Plugin/Resources.rc @@ -143,6 +143,7 @@ FONT 8, "MS Shell Dlg", FW_DONTCARE, FALSE, DEFAULT_CHARSET CONTROL "While/EndWhile", IDC_SETTINGS_MATCHER_KEYWORD_WHILE, "Button", BS_AUTOCHECKBOX | BS_NOTIFY | WS_TABSTOP, 228, SETTINGS_TAB_BASE_Y + 60, 88, 12, WS_EX_TRANSPARENT LTEXT "Indicator ID:", IDC_SETTINGS_MATCHER_INDICATOR_ID_LABEL, 24, SETTINGS_TAB_BASE_Y + 80, 64, 12, SS_NOTIFY, WS_EX_TRANSPARENT EDITTEXT IDC_SETTINGS_MATCHER_INDICATOR_ID, 96, SETTINGS_TAB_BASE_Y + 78, 24, 12, ES_LEFT | ES_AUTOHSCROLL + CONTROL "Try auto allocation first", IDC_SETTINGS_MATCHER_INDICATOR_ID_AUTO_ALLOCATE, "Button", BS_AUTOCHECKBOX | BS_NOTIFY | WS_TABSTOP, 132, SETTINGS_TAB_BASE_Y + 78, 120, 12, WS_EX_TRANSPARENT LTEXT "Matched Style:", IDC_SETTINGS_MATCHER_MATCHED_STYLE_LABEL, 24, SETTINGS_TAB_BASE_Y + 100, 64, 12, SS_NOTIFY, WS_EX_TRANSPARENT COMBOBOX IDC_SETTINGS_MATCHER_MATCHED_STYLE_DROPDOWN, 96, SETTINGS_TAB_BASE_Y + 98, 112, 16, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Foreground color:", IDC_SETTINGS_MATCHER_MATCHED_FGCOLOR_LABEL, 216, SETTINGS_TAB_BASE_Y + 100, 64, 12, SS_NOTIFY, WS_EX_TRANSPARENT @@ -170,6 +171,7 @@ FONT 8, "MS Shell Dlg", FW_DONTCARE, FALSE, DEFAULT_CHARSET CONTROL "Enable error indication", IDC_SETTINGS_ANNOTATOR_ENABLE_INDICATION, "Button", BS_AUTOCHECKBOX | BS_NOTIFY | WS_TABSTOP, 20, SETTINGS_TAB_BASE_Y + 76, 120, 12, WS_EX_TRANSPARENT LTEXT "Indicator ID:", IDC_SETTINGS_ANNOTATOR_INDICATOR_ID_LABEL, 32, SETTINGS_TAB_BASE_Y + 94, 64, 12, SS_NOTIFY, WS_EX_TRANSPARENT EDITTEXT IDC_SETTINGS_ANNOTATOR_INDICATOR_ID, 104, SETTINGS_TAB_BASE_Y + 92, 24, 12, ES_LEFT | ES_AUTOHSCROLL + CONTROL "Try auto allocation first", IDC_SETTINGS_ANNOTATOR_INDICATOR_ID_AUTO_ALLOCATE, "Button", BS_AUTOCHECKBOX | BS_NOTIFY | WS_TABSTOP, 136, SETTINGS_TAB_BASE_Y + 92, 120, 12, WS_EX_TRANSPARENT LTEXT "Indicator Style:", IDC_SETTINGS_ANNOTATOR_INDICATOR_STYLE_LABEL, 32, SETTINGS_TAB_BASE_Y + 114, 64, 12, SS_NOTIFY, WS_EX_TRANSPARENT COMBOBOX IDC_SETTINGS_ANNOTATOR_INDICATOR_STYLE_DROPDOWN, 104, SETTINGS_TAB_BASE_Y + 112, 112, 16, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Foreground color:", IDC_SETTINGS_ANNOTATOR_INDICATOR_FGCOLOR_LABEL, 224, SETTINGS_TAB_BASE_Y + 114, 64, 12, SS_NOTIFY, WS_EX_TRANSPARENT @@ -259,13 +261,15 @@ When this happens, simply disable the option to force the lexer to re-check for IDS_SETTINGS_MATCHER_TOOLTIP, L"Highlight matching keyword pair when cursor is at one of the words in the pair. When matching If/EndIf pair, Else/ElseIf can also be optionally included in the match." - IDS_SETTINGS_MATCHER_INDICATOR_ID_TOOLTIP, L"Choose a number between 9 and 20. Keep in mind other plugins may use indicator IDs as well, e.g. DSpellCheck uses 19, so if there are conflicts, just choose a different number." + IDS_SETTINGS_MATCHER_INDICATOR_ID_TOOLTIP, L"Choose a number between 9 and 20. It is recommended to try auto allocation first. However, since there are only 12 possible indicator IDs, the auto allocation may fail, in which case the assigned ID here will be used.\r\n +Of course it means there will be conflicts, but there is no way to workaround it. Also, keep in mind other plugins may use hardcoded indicator IDs, so even with an auto allocated ID there is no guarantee there won't be conflicts. Try to remove unused plugins if it's a concern." IDS_SETTINGS_ANNOTATOR_ENABLE_ANNOTATION_TOOLTIP, L"Show annotations under error lines. They are inside a round box. When there are multiple errors on the same line, they are grouped in the same annotation box." IDS_SETTINGS_ANNOTATOR_ENABLE_INDICATION_TOOLTIP, L"Show indications where errors happen." - IDS_SETTINGS_ANNOTATOR_INDICATOR_ID_TOOLTIP, L"Choose a number between 9 and 20. Keep in mind other plugins may use indicator IDs as well, e.g. DSpellCheck uses 19, so if there are conflicts, just choose a different number.\r\n\ + IDS_SETTINGS_ANNOTATOR_INDICATOR_ID_TOOLTIP, L"Choose a number between 9 and 20. It is recommended to try auto allocation first. However, since there are only 12 possible indicator IDs, the auto allocation may fail, in which case the assigned ID here will be used.\r\n +Of course it means there will be conflicts, but there is no way to workaround it. Also, keep in mind other plugins may use hardcoded indicator IDs, so even with an auto allocated ID there is no guarantee there won't be conflicts. Try to remove unused plugins if it's a concern.\r\n Note, if changes have been made after indications were shown, changing ID again may cause indications to be rendered incorrectly. Trigger recompilation to fix them if needed." IDS_SETTINGS_COMPILER_RADIO_AUTO_TOOLTIP, L"In this mode, Papyrus compiler to be used is determined by the path of source script file. If it's under a detected game's directory, that game's settings will be used. Otherwise, \ diff --git a/src/Plugin/Settings/Settings.cpp b/src/Plugin/Settings/Settings.cpp index 0c13234..3c8a520 100644 --- a/src/Plugin/Settings/Settings.cpp +++ b/src/Plugin/Settings/Settings.cpp @@ -62,7 +62,8 @@ namespace papyrus { storage.putString(L"keywordMatcher.enableKeywordMatching", utility::boolToStr(keywordMatcherSettings.enableKeywordMatching)); storage.putString(L"keywordMatcher.enabledKeywords", std::to_wstring(keywordMatcherSettings.enabledKeywords)); - storage.putString(L"keywordMatcher.indicatorID", std::to_wstring(keywordMatcherSettings.indicatorID)); + storage.putString(L"keywordMatcher.autoAllocateIndicatorID", utility::boolToStr(keywordMatcherSettings.autoAllocateIndicatorID)); + storage.putString(L"keywordMatcher.defaultIndicatorID", std::to_wstring(keywordMatcherSettings.defaultIndicatorID)); storage.putString(L"keywordMatcher.matchedIndicatorStyle", std::to_wstring(keywordMatcherSettings.matchedIndicatorStyle)); storage.putString(L"keywordMatcher.matchedIndicatorForegroundColor" + themeSuffix, utility::colorToHexStr(keywordMatcherSettings.matchedIndicatorForegroundColor)); storage.putString(L"keywordMatcher.unmatchedIndicatorStyle", std::to_wstring(keywordMatcherSettings.unmatchedIndicatorStyle)); @@ -74,7 +75,8 @@ namespace papyrus { storage.putString(L"errorAnnotator.isAnnotationItalic", utility::boolToStr(errorAnnotatorSettings.isAnnotationItalic)); storage.putString(L"errorAnnotator.isAnnotationBold", utility::boolToStr(errorAnnotatorSettings.isAnnotationBold)); storage.putString(L"errorAnnotator.enableIndication", utility::boolToStr(errorAnnotatorSettings.enableIndication)); - storage.putString(L"errorAnnotator.indicatorID", std::to_wstring(errorAnnotatorSettings.indicatorID)); + storage.putString(L"errorAnnotator.autoAllocateIndicatorID", utility::boolToStr(errorAnnotatorSettings.autoAllocateIndicatorID)); + storage.putString(L"errorAnnotator.defaultIndicatorID", std::to_wstring(errorAnnotatorSettings.defaultIndicatorID)); storage.putString(L"errorAnnotator.indicatorStyle", std::to_wstring(errorAnnotatorSettings.indicatorStyle)); storage.putString(L"errorAnnotator.indicatorForegroundColor" + themeSuffix, utility::colorToHexStr(errorAnnotatorSettings.indicatorForegroundColor)); @@ -187,14 +189,25 @@ namespace papyrus { updated = true; } - if (storage.getString(L"keywordMatcher.indicatorID", value)) { - keywordMatcherSettings.indicatorID = std::stoi(value); - if (keywordMatcherSettings.indicatorID < 9 || keywordMatcherSettings.indicatorID > 20) { - keywordMatcherSettings.indicatorID = DEFAULT_MATCHER_INDICATOR; - updated = true; - } + if (storage.getString(L"keywordMatcher.autoAllocateIndicatorID", value)) { + keywordMatcherSettings.autoAllocateIndicatorID = utility::strToBool(value); } else { - keywordMatcherSettings.indicatorID = DEFAULT_MATCHER_INDICATOR; + keywordMatcherSettings.autoAllocateIndicatorID = true; + updated = true; + } + + if (storage.getString(L"keywordMatcher.defaultIndicatorID", value)) { + keywordMatcherSettings.defaultIndicatorID = std::stoi(value); + } else if (storage.getString(L"keywordMatcher.indicatorID", value)) { + keywordMatcherSettings.defaultIndicatorID = std::stoi(value); + storage.renameKey(L"keywordMatcher.indicatorID", L"keywordMatcher.defaultIndicatorID"); + updated = true; + } else { + keywordMatcherSettings.defaultIndicatorID = DEFAULT_MATCHER_INDICATOR; + updated = true; + } + if (keywordMatcherSettings.defaultIndicatorID < 9 || keywordMatcherSettings.defaultIndicatorID > 20) { + keywordMatcherSettings.defaultIndicatorID = DEFAULT_MATCHER_INDICATOR; updated = true; } @@ -250,14 +263,25 @@ namespace papyrus { updated = true; } - if (storage.getString(L"errorAnnotator.indicatorID", value)) { - errorAnnotatorSettings.indicatorID = std::stoi(value); - if (errorAnnotatorSettings.indicatorID < 9 || errorAnnotatorSettings.indicatorID > 20) { - errorAnnotatorSettings.indicatorID = DEFAULT_ERROR_INDICATOR; - updated = true; - } + if (storage.getString(L"errorAnnotator.autoAllocateIndicatorID", value)) { + errorAnnotatorSettings.autoAllocateIndicatorID = utility::strToBool(value); } else { - errorAnnotatorSettings.indicatorID = DEFAULT_ERROR_INDICATOR; + errorAnnotatorSettings.autoAllocateIndicatorID = true; + updated = true; + } + + if (storage.getString(L"errorAnnotator.defaultIndicatorID", value)) { + errorAnnotatorSettings.defaultIndicatorID = std::stoi(value); + } else if (storage.getString(L"errorAnnotator.indicatorID", value)) { + errorAnnotatorSettings.defaultIndicatorID = std::stoi(value); + storage.renameKey(L"errorAnnotator.indicatorID", L"errorAnnotator.defaultIndicatorID"); + updated = true; + } else { + errorAnnotatorSettings.defaultIndicatorID = DEFAULT_ERROR_INDICATOR; + updated = true; + } + if (errorAnnotatorSettings.defaultIndicatorID < 9 || errorAnnotatorSettings.defaultIndicatorID > 20) { + errorAnnotatorSettings.defaultIndicatorID = DEFAULT_ERROR_INDICATOR; updated = true; } diff --git a/src/Plugin/Settings/SettingsDialog.cpp b/src/Plugin/Settings/SettingsDialog.cpp index 6ec5ce1..92cdd92 100644 --- a/src/Plugin/Settings/SettingsDialog.cpp +++ b/src/Plugin/Settings/SettingsDialog.cpp @@ -173,7 +173,8 @@ namespace papyrus { setChecked(tab, IDC_SETTINGS_MATCHER_KEYWORD_WHILE, settings.keywordMatcherSettings.enabledKeywords & KEYWORD_WHILE); createToolTip(tab, IDC_SETTINGS_MATCHER_INDICATOR_ID_LABEL, IDS_SETTINGS_MATCHER_INDICATOR_ID_TOOLTIP); - setText(tab, IDC_SETTINGS_MATCHER_INDICATOR_ID, std::to_wstring(settings.keywordMatcherSettings.indicatorID)); + setText(tab, IDC_SETTINGS_MATCHER_INDICATOR_ID, std::to_wstring(settings.keywordMatcherSettings.defaultIndicatorID)); + setChecked(tab, IDC_SETTINGS_MATCHER_INDICATOR_ID_AUTO_ALLOCATE, settings.keywordMatcherSettings.autoAllocateIndicatorID); initDropdownList(tab, IDC_SETTINGS_MATCHER_MATCHED_STYLE_DROPDOWN, indicatorStyles, settings.keywordMatcherSettings.matchedIndicatorStyle); initColorPicker(tab, matchedIndicatorFgColorPicker, IDC_SETTINGS_MATCHER_MATCHED_FGCOLOR_LABEL); @@ -199,7 +200,8 @@ namespace papyrus { setChecked(tab, IDC_SETTINGS_ANNOTATOR_ENABLE_INDICATION, settings.errorAnnotatorSettings.enableIndication); createToolTip(tab, IDC_SETTINGS_ANNOTATOR_ENABLE_INDICATION, IDS_SETTINGS_ANNOTATOR_ENABLE_INDICATION_TOOLTIP); createToolTip(tab, IDC_SETTINGS_ANNOTATOR_INDICATOR_ID_LABEL, IDS_SETTINGS_ANNOTATOR_INDICATOR_ID_TOOLTIP); - setText(tab, IDC_SETTINGS_ANNOTATOR_INDICATOR_ID, std::to_wstring(settings.errorAnnotatorSettings.indicatorID)); + setText(tab, IDC_SETTINGS_ANNOTATOR_INDICATOR_ID, std::to_wstring(settings.errorAnnotatorSettings.defaultIndicatorID)); + setChecked(tab, IDC_SETTINGS_ANNOTATOR_INDICATOR_ID_AUTO_ALLOCATE, settings.errorAnnotatorSettings.autoAllocateIndicatorID); initDropdownList(tab, IDC_SETTINGS_ANNOTATOR_INDICATOR_STYLE_DROPDOWN, indicatorStyles, settings.errorAnnotatorSettings.indicatorStyle); initColorPicker(tab, errorIndicatorFgColorPicker, IDC_SETTINGS_ANNOTATOR_INDICATOR_FGCOLOR_LABEL); errorIndicatorFgColorPicker.setColour(settings.errorAnnotatorSettings.indicatorForegroundColor); @@ -312,15 +314,14 @@ namespace papyrus { return FALSE; } - case IDC_SETTINGS_ANNOTATOR_ENABLE_ANNOTATION: { - settings.errorAnnotatorSettings.enableAnnotation = getChecked(tab, IDC_SETTINGS_ANNOTATOR_ENABLE_ANNOTATION); - enableGroup(Group::Annotation, settings.errorAnnotatorSettings.enableAnnotation); + case IDC_SETTINGS_MATCHER_INDICATOR_ID_AUTO_ALLOCATE: { + settings.keywordMatcherSettings.autoAllocateIndicatorID = getChecked(tab, IDC_SETTINGS_MATCHER_INDICATOR_ID_AUTO_ALLOCATE); return FALSE; } - case IDC_SETTINGS_ANNOTATOR_ENABLE_INDICATION: { - settings.errorAnnotatorSettings.enableIndication = getChecked(tab, IDC_SETTINGS_ANNOTATOR_ENABLE_INDICATION); - enableGroup(Group::Indication, settings.errorAnnotatorSettings.enableIndication); + case IDC_SETTINGS_ANNOTATOR_ENABLE_ANNOTATION: { + settings.errorAnnotatorSettings.enableAnnotation = getChecked(tab, IDC_SETTINGS_ANNOTATOR_ENABLE_ANNOTATION); + enableGroup(Group::Annotation, settings.errorAnnotatorSettings.enableAnnotation); return FALSE; } @@ -334,6 +335,17 @@ namespace papyrus { return FALSE; } + case IDC_SETTINGS_ANNOTATOR_ENABLE_INDICATION: { + settings.errorAnnotatorSettings.enableIndication = getChecked(tab, IDC_SETTINGS_ANNOTATOR_ENABLE_INDICATION); + enableGroup(Group::Indication, settings.errorAnnotatorSettings.enableIndication); + return FALSE; + } + + case IDC_SETTINGS_ANNOTATOR_INDICATOR_ID_AUTO_ALLOCATE: { + settings.errorAnnotatorSettings.autoAllocateIndicatorID = getChecked(tab, IDC_SETTINGS_ANNOTATOR_INDICATOR_ID_AUTO_ALLOCATE); + return FALSE; + } + case IDC_SETTINGS_COMPILER_SKYRIM_TOGGLE: { toggleGame(Game::Skyrim, IDC_SETTINGS_COMPILER_SKYRIM_TOGGLE, Group::GameSkyrim); return FALSE; @@ -722,7 +734,7 @@ namespace papyrus { return false; } - settings.keywordMatcherSettings.indicatorID = matcherIndicatorID; + settings.keywordMatcherSettings.defaultIndicatorID = matcherIndicatorID; } constexpr tab_id_t errorAnnotatorTab = std::to_underlying(Tab::ErrorAnnotator); @@ -740,7 +752,7 @@ namespace papyrus { return false; } - settings.errorAnnotatorSettings.indicatorID = errorIndicatorID; + settings.errorAnnotatorSettings.defaultIndicatorID = errorIndicatorID; } constexpr tab_id_t compilerTab = std::to_underlying(Tab::Compiler);