mirror of
https://github.com/notepad-plus-plus/notepad-plus-plus.git
synced 2025-07-31 01:34:58 +02:00
Optimize Scintilla notification code performance
Treat only main & sub Scintilla views for the most of SCN_* notification: 1. Move all SCN_* together. 2. Add a if (!notifyView) return FALSE; in the begining of case for most of all SCN_* notification. Ref: https://github.com/notepad-plus-plus/notepad-plus-plus/pull/15981#issuecomment-2565003286 Close #15994
This commit is contained in:
parent
de9ffd2ea8
commit
f40df3cdf1
@ -46,8 +46,7 @@ BOOL Notepad_plus::notify(SCNotification *notification)
|
|||||||
{
|
{
|
||||||
case SCN_MODIFIED:
|
case SCN_MODIFIED:
|
||||||
{
|
{
|
||||||
if (!notifyView)
|
if (!notifyView) return FALSE;
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (notification->modificationType & (SC_MOD_DELETETEXT | SC_MOD_INSERTTEXT))
|
if (notification->modificationType & (SC_MOD_DELETETEXT | SC_MOD_INSERTTEXT))
|
||||||
{
|
{
|
||||||
@ -72,6 +71,8 @@ BOOL Notepad_plus::notify(SCNotification *notification)
|
|||||||
case SCN_SAVEPOINTREACHED:
|
case SCN_SAVEPOINTREACHED:
|
||||||
case SCN_SAVEPOINTLEFT:
|
case SCN_SAVEPOINTLEFT:
|
||||||
{
|
{
|
||||||
|
//if (!notifyView) return FALSE; // Could be _invisibleEditView or _fileEditView (see the following code)
|
||||||
|
|
||||||
Buffer * buf = 0;
|
Buffer * buf = 0;
|
||||||
if (isFromPrimary)
|
if (isFromPrimary)
|
||||||
{
|
{
|
||||||
@ -123,17 +124,450 @@ BOOL Notepad_plus::notify(SCNotification *notification)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SCN_MODIFYATTEMPTRO:
|
case SCN_MARGINCLICK:
|
||||||
{
|
{
|
||||||
// nothing to do
|
if (!notifyView) return FALSE;
|
||||||
|
|
||||||
|
if (notification->nmhdr.hwndFrom == _mainEditView.getHSelf())
|
||||||
|
switchEditViewTo(MAIN_VIEW);
|
||||||
|
else if (notification->nmhdr.hwndFrom == _subEditView.getHSelf())
|
||||||
|
switchEditViewTo(SUB_VIEW);
|
||||||
|
|
||||||
|
intptr_t lineClick = _pEditView->execute(SCI_LINEFROMPOSITION, notification->position);
|
||||||
|
|
||||||
|
if (notification->margin == ScintillaEditView::_SC_MARGE_FOLDER)
|
||||||
|
{
|
||||||
|
_pEditView->marginClick(notification->position, notification->modifiers);
|
||||||
|
if (_pDocMap)
|
||||||
|
_pDocMap->fold(lineClick, _pEditView->isFolded(lineClick));
|
||||||
|
|
||||||
|
ScintillaEditView* unfocusView = isFromPrimary ? &_subEditView : &_mainEditView;
|
||||||
|
|
||||||
|
_smartHighlighter.highlightView(_pEditView, unfocusView);
|
||||||
|
}
|
||||||
|
else if ((notification->margin == ScintillaEditView::_SC_MARGE_SYMBOL) && !notification->modifiers)
|
||||||
|
{
|
||||||
|
if (!_pEditView->markerMarginClick(lineClick))
|
||||||
|
bookmarkToggle(lineClick);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SCN_KEY:
|
case SCN_MARGINRIGHTCLICK:
|
||||||
{
|
{
|
||||||
|
if (!notifyView) return FALSE;
|
||||||
|
|
||||||
|
if (notification->nmhdr.hwndFrom == _mainEditView.getHSelf())
|
||||||
|
switchEditViewTo(MAIN_VIEW);
|
||||||
|
else if (notification->nmhdr.hwndFrom == _subEditView.getHSelf())
|
||||||
|
switchEditViewTo(SUB_VIEW);
|
||||||
|
|
||||||
|
if ((notification->margin == ScintillaEditView::_SC_MARGE_SYMBOL) && !notification->modifiers)
|
||||||
|
{
|
||||||
|
POINT p;
|
||||||
|
::GetCursorPos(&p);
|
||||||
|
MenuPosition& menuPos = getMenuPosition("search-bookmark");
|
||||||
|
HMENU hSearchMenu = ::GetSubMenu(_mainMenuHandle, menuPos._x);
|
||||||
|
if (hSearchMenu)
|
||||||
|
{
|
||||||
|
HMENU hBookmarkMenu = ::GetSubMenu(hSearchMenu, menuPos._y);
|
||||||
|
if (hBookmarkMenu)
|
||||||
|
{
|
||||||
|
TrackPopupMenu(hBookmarkMenu, 0, p.x, p.y, 0, _pPublicInterface->getHSelf(), NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case SCN_FOLDINGSTATECHANGED:
|
||||||
|
{
|
||||||
|
if ((notification->nmhdr.hwndFrom == _mainEditView.getHSelf()) || (notification->nmhdr.hwndFrom == _subEditView.getHSelf()))
|
||||||
|
{
|
||||||
|
size_t lineClicked = notification->line;
|
||||||
|
|
||||||
|
if (!_isFolding)
|
||||||
|
{
|
||||||
|
addHotSpot();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_pDocMap)
|
||||||
|
_pDocMap->fold(lineClicked, _pEditView->isFolded(lineClicked));
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SCN_CHARADDED:
|
||||||
|
{
|
||||||
|
if (!notifyView) return FALSE;
|
||||||
|
|
||||||
|
if (!_recordingMacro && !_playingBackMacro) // No macro recording or playing back
|
||||||
|
{
|
||||||
|
const NppGUI& nppGui = NppParameters::getInstance().getNppGUI();
|
||||||
|
if (nppGui._maintainIndent != autoIndent_none)
|
||||||
|
maintainIndentation(static_cast<wchar_t>(notification->ch));
|
||||||
|
|
||||||
|
Buffer* currentBuf = _pEditView->getCurrentBuffer();
|
||||||
|
if (currentBuf->allowAutoCompletion())
|
||||||
|
{
|
||||||
|
AutoCompletion* autoC = isFromPrimary ? &_autoCompleteMain : &_autoCompleteSub;
|
||||||
|
bool isColumnMode = _pEditView->execute(SCI_GETSELECTIONS) > 1; // Multi-Selection || Column mode)
|
||||||
|
if (nppGui._matchedPairConf.hasAnyPairsPair() && !isColumnMode)
|
||||||
|
autoC->insertMatchedChars(notification->ch, nppGui._matchedPairConf);
|
||||||
|
autoC->update(notification->ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SCN_DOUBLECLICK:
|
||||||
|
{
|
||||||
|
if (!notifyView) return FALSE;
|
||||||
|
|
||||||
|
if (notification->modifiers == SCMOD_CTRL)
|
||||||
|
{
|
||||||
|
const NppGUI& nppGUI = NppParameters::getInstance().getNppGUI();
|
||||||
|
|
||||||
|
std::string bufstring;
|
||||||
|
|
||||||
|
size_t position_of_click;
|
||||||
|
// For some reason Ctrl+DoubleClick on an empty line means that notification->position == 1.
|
||||||
|
// In that case we use SCI_GETCURRENTPOS to get the position.
|
||||||
|
if (notification->position != -1)
|
||||||
|
position_of_click = notification->position;
|
||||||
|
else
|
||||||
|
position_of_click = _pEditView->execute(SCI_GETCURRENTPOS);
|
||||||
|
|
||||||
|
// Anonymous scope to limit use of the buf pointer (much easier to deal with std::string).
|
||||||
|
{
|
||||||
|
char* buf;
|
||||||
|
|
||||||
|
if (nppGUI._delimiterSelectionOnEntireDocument)
|
||||||
|
{
|
||||||
|
// Get entire document.
|
||||||
|
auto length = notifyView->execute(SCI_GETLENGTH);
|
||||||
|
buf = new char[length + 1];
|
||||||
|
notifyView->execute(SCI_GETTEXT, length + 1, reinterpret_cast<LPARAM>(buf));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Get single line.
|
||||||
|
auto length = notifyView->execute(SCI_GETCURLINE);
|
||||||
|
buf = new char[length + 1];
|
||||||
|
notifyView->execute(SCI_GETCURLINE, length, reinterpret_cast<LPARAM>(buf));
|
||||||
|
|
||||||
|
// Compute the position of the click (relative to the beginning of the line).
|
||||||
|
const auto line_position = notifyView->execute(SCI_POSITIONFROMLINE, notifyView->getCurrentLineNumber());
|
||||||
|
position_of_click = position_of_click - line_position;
|
||||||
|
}
|
||||||
|
|
||||||
|
bufstring = buf;
|
||||||
|
delete[] buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
int leftmost_position = -1;
|
||||||
|
int rightmost_position = -1;
|
||||||
|
|
||||||
|
if (nppGUI._rightmostDelimiter == nppGUI._leftmostDelimiter)
|
||||||
|
{
|
||||||
|
// If the delimiters are the same (e.g. they are both a quotation mark), choose the ones
|
||||||
|
// which are closest to the clicked position.
|
||||||
|
for (int32_t i = static_cast<int32_t>(position_of_click); i >= 0; --i)
|
||||||
|
{
|
||||||
|
if (i >= static_cast<int32_t>(bufstring.size()))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (bufstring.at(i) == nppGUI._leftmostDelimiter)
|
||||||
|
{
|
||||||
|
// Respect escaped quotation marks.
|
||||||
|
if (nppGUI._leftmostDelimiter == '"')
|
||||||
|
{
|
||||||
|
if (!(i > 0 && bufstring.at(i - 1) == '\\'))
|
||||||
|
{
|
||||||
|
leftmost_position = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
leftmost_position = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (leftmost_position == -1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Scan for right delimiter.
|
||||||
|
for (size_t i = position_of_click; i < bufstring.length(); ++i)
|
||||||
|
{
|
||||||
|
if (bufstring.at(i) == nppGUI._rightmostDelimiter)
|
||||||
|
{
|
||||||
|
// Respect escaped quotation marks.
|
||||||
|
if (nppGUI._rightmostDelimiter == '"')
|
||||||
|
{
|
||||||
|
if (!(i > 0 && bufstring.at(i - 1) == '\\'))
|
||||||
|
{
|
||||||
|
rightmost_position = static_cast<int32_t>(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rightmost_position = static_cast<int32_t>(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Find matching pairs of delimiters (e.g. parentheses).
|
||||||
|
// The pair where the distance from the left delimiter to position_of_click is at a minimum is the one we're looking for.
|
||||||
|
// Of course position_of_click must lie between the delimiters.
|
||||||
|
|
||||||
|
// This logic is required to handle cases like this:
|
||||||
|
// (size_t i = function(); i < _buffers.size(); i++)
|
||||||
|
|
||||||
|
std::stack<unsigned int> leftmost_delimiter_positions;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < bufstring.length(); ++i)
|
||||||
|
{
|
||||||
|
if (bufstring.at(i) == nppGUI._leftmostDelimiter)
|
||||||
|
leftmost_delimiter_positions.push(i);
|
||||||
|
else if (bufstring.at(i) == nppGUI._rightmostDelimiter && !leftmost_delimiter_positions.empty())
|
||||||
|
{
|
||||||
|
unsigned int matching_leftmost = leftmost_delimiter_positions.top();
|
||||||
|
leftmost_delimiter_positions.pop();
|
||||||
|
|
||||||
|
// We have either 1) chosen neither the left- or rightmost position, or 2) chosen both left- and rightmost position.
|
||||||
|
assert((leftmost_position == -1 && rightmost_position == -1) || (leftmost_position >= 0 && rightmost_position >= 0));
|
||||||
|
|
||||||
|
// Note: cast of leftmost_position to unsigned int is safe, since if leftmost_position is not -1 then it is guaranteed to be positive.
|
||||||
|
// If it was possible, leftmost_position and rightmost_position should be of type optional<unsigned int>.
|
||||||
|
if (matching_leftmost <= position_of_click && i >= position_of_click && (leftmost_position == -1 || matching_leftmost > static_cast<unsigned int>(leftmost_position)))
|
||||||
|
{
|
||||||
|
leftmost_position = matching_leftmost;
|
||||||
|
rightmost_position = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set selection to the position we found (if any).
|
||||||
|
if (rightmost_position != -1 && leftmost_position != -1)
|
||||||
|
{
|
||||||
|
if (nppGUI._delimiterSelectionOnEntireDocument)
|
||||||
|
{
|
||||||
|
notifyView->execute(SCI_SETCURRENTPOS, rightmost_position);
|
||||||
|
notifyView->execute(SCI_SETANCHOR, leftmost_position + 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const auto line_position = notifyView->execute(SCI_POSITIONFROMLINE, notifyView->getCurrentLineNumber());
|
||||||
|
notifyView->execute(SCI_SETCURRENTPOS, line_position + rightmost_position);
|
||||||
|
notifyView->execute(SCI_SETANCHOR, line_position + leftmost_position + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // Double click with no modifiers
|
||||||
|
// Check whether cursor is within URL
|
||||||
|
auto indicMsk = notifyView->execute(SCI_INDICATORALLONFOR, notification->position);
|
||||||
|
if (!(indicMsk & (1 << URL_INDIC)))
|
||||||
|
break;
|
||||||
|
|
||||||
|
auto startPos = notifyView->execute(SCI_INDICATORSTART, URL_INDIC, notification->position);
|
||||||
|
auto endPos = notifyView->execute(SCI_INDICATOREND, URL_INDIC, notification->position);
|
||||||
|
if ((notification->position < startPos) || (notification->position > endPos))
|
||||||
|
break;
|
||||||
|
|
||||||
|
// WM_LBUTTONUP goes to opening browser instead of Scintilla here, because the mouse is not captured.
|
||||||
|
// The missing message causes mouse cursor flicker as soon as the mouse cursor is moved to a position outside the text editing area.
|
||||||
|
::PostMessage(notifyView->getHSelf(), WM_LBUTTONUP, 0, 0);
|
||||||
|
|
||||||
|
// Revert selection of current word. Best to this early, otherwise the
|
||||||
|
// selected word is visible all the time while the browser is starting
|
||||||
|
notifyView->execute(SCI_SETSEL, notification->position, notification->position);
|
||||||
|
|
||||||
|
// Open URL
|
||||||
|
wstring url = notifyView->getGenericTextAsString(static_cast<size_t>(startPos), static_cast<size_t>(endPos));
|
||||||
|
::ShellExecute(_pPublicInterface->getHSelf(), L"open", url.c_str(), NULL, NULL, SW_SHOW);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SCN_UPDATEUI:
|
||||||
|
{
|
||||||
|
if (!notifyView) return FALSE;
|
||||||
|
|
||||||
|
NppParameters& nppParam = NppParameters::getInstance();
|
||||||
|
NppGUI& nppGui = nppParam.getNppGUI();
|
||||||
|
|
||||||
|
// replacement for obsolete custom SCN_SCROLLED
|
||||||
|
if (notification->updated & SC_UPDATE_V_SCROLL)
|
||||||
|
{
|
||||||
|
addHotSpot(notifyView);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if it's searching/replacing, then do nothing
|
||||||
|
if (nppParam._isFindReplacing)
|
||||||
|
break;
|
||||||
|
|
||||||
|
Buffer* currentBuf = _pEditView->getCurrentBuffer();
|
||||||
|
if (notification->nmhdr.hwndFrom != _pEditView->getHSelf() && currentBuf->allowSmartHilite()) // notification come from unfocus view - both views ae visible
|
||||||
|
{
|
||||||
|
if (nppGui._smartHiliteOnAnotherView)
|
||||||
|
{
|
||||||
|
wchar_t selectedText[1024];
|
||||||
|
_pEditView->getGenericSelectedText(selectedText, sizeof(selectedText) / sizeof(wchar_t), false);
|
||||||
|
_smartHighlighter.highlightViewWithWord(notifyView, selectedText);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
braceMatch();
|
||||||
|
|
||||||
|
if (nppGui._enableTagsMatchHilite)
|
||||||
|
{
|
||||||
|
XmlMatchedTagsHighlighter xmlTagMatchHiliter(_pEditView);
|
||||||
|
xmlTagMatchHiliter.tagMatch(nppGui._enableTagAttrsHilite);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nppGui._enableSmartHilite && currentBuf->allowSmartHilite())
|
||||||
|
{
|
||||||
|
if (nppGui._disableSmartHiliteTmp)
|
||||||
|
nppGui._disableSmartHiliteTmp = false;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ScintillaEditView* anbotherView = isFromPrimary ? &_subEditView : &_mainEditView;
|
||||||
|
_smartHighlighter.highlightView(notifyView, anbotherView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool selectionIsChanged = (notification->updated & SC_UPDATE_SELECTION) != 0;
|
||||||
|
// note: changing insert/overwrite mode will cause Scintilla to notify with SC_UPDATE_SELECTION
|
||||||
|
bool contentIsChanged = (notification->updated & SC_UPDATE_CONTENT) != 0;
|
||||||
|
if (selectionIsChanged || contentIsChanged)
|
||||||
|
{
|
||||||
|
updateStatusBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_pFuncList && (!_pFuncList->isClosed()) && _pFuncList->isVisible())
|
||||||
|
_pFuncList->markEntry();
|
||||||
|
AutoCompletion* autoC = isFromPrimary ? &_autoCompleteMain : &_autoCompleteSub;
|
||||||
|
autoC->update(0);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SCN_ZOOM:
|
||||||
|
{
|
||||||
|
if (!notifyView) return FALSE;
|
||||||
|
|
||||||
|
ScintillaEditView* unfocusView = isFromPrimary ? &_subEditView : &_mainEditView;
|
||||||
|
_smartHighlighter.highlightView(notifyView, unfocusView);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SCN_MACRORECORD:
|
||||||
|
{
|
||||||
|
_macro.push_back(
|
||||||
|
recordedMacroStep(
|
||||||
|
notification->message,
|
||||||
|
notification->wParam,
|
||||||
|
notification->lParam
|
||||||
|
)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SCN_PAINTED:
|
||||||
|
{
|
||||||
|
if (!notifyView) return FALSE;
|
||||||
|
|
||||||
|
// Check if a restore position is needed.
|
||||||
|
// Restoring a position must done after SCN_PAINTED notification so that it works in every circumstances (including wrapped large file)
|
||||||
|
_mainEditView.restoreCurrentPosPostStep();
|
||||||
|
_subEditView.restoreCurrentPosPostStep();
|
||||||
|
|
||||||
|
// ViewMoveAtWrappingDisableFix: Disable wrapping messes up visible lines.
|
||||||
|
// Therefore save view position before in IDM_VIEW_WRAP and restore after SCN_PAINTED, as doc. says
|
||||||
|
if (_mainEditView.isWrapRestoreNeeded())
|
||||||
|
{
|
||||||
|
_mainEditView.restoreCurrentPosPreStep();
|
||||||
|
_mainEditView.setWrapRestoreNeeded(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_subEditView.isWrapRestoreNeeded())
|
||||||
|
{
|
||||||
|
_subEditView.restoreCurrentPosPreStep();
|
||||||
|
_subEditView.setWrapRestoreNeeded(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyView->updateLineNumberWidth();
|
||||||
|
|
||||||
|
if (_syncInfo.doSync())
|
||||||
|
doSynScorll(HWND(notification->nmhdr.hwndFrom));
|
||||||
|
|
||||||
|
const NppParameters& nppParam = NppParameters::getInstance();
|
||||||
|
|
||||||
|
// if it's searching/replacing, then do nothing
|
||||||
|
if ((_linkTriggered && !nppParam._isFindReplacing) || notification->wParam == LINKTRIGGERED)
|
||||||
|
{
|
||||||
|
addHotSpot();
|
||||||
|
_linkTriggered = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_pDocMap && (!_pDocMap->isClosed()) && _pDocMap->isVisible() && !_pDocMap->isTemporarilyShowing())
|
||||||
|
{
|
||||||
|
_pDocMap->wrapMap();
|
||||||
|
_pDocMap->scrollMap();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SCN_CALLTIPCLICK:
|
||||||
|
{
|
||||||
|
if (!notifyView) return FALSE;
|
||||||
|
|
||||||
|
AutoCompletion* autoC = isFromPrimary ? &_autoCompleteMain : &_autoCompleteSub;
|
||||||
|
autoC->callTipClick(notification->position);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SCN_AUTOCSELECTION:
|
||||||
|
{
|
||||||
|
if (!notifyView) return FALSE;
|
||||||
|
|
||||||
|
const NppGUI& nppGui = NppParameters::getInstance().getNppGUI();
|
||||||
|
|
||||||
|
// if autocompletion is disabled and it is triggered manually, then both ENTER & TAB will insert the selection
|
||||||
|
if (nppGui._autocStatus == NppGUI::AutocStatus::autoc_none)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (notification->listCompletionMethod == SC_AC_NEWLINE && !nppGui._autocInsertSelectedUseENTER)
|
||||||
|
{
|
||||||
|
notifyView->execute(SCI_AUTOCCANCEL);
|
||||||
|
notifyView->execute(SCI_NEWLINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (notification->listCompletionMethod == SC_AC_TAB && !nppGui._autocInsertSelectedUseTAB)
|
||||||
|
{
|
||||||
|
notifyView->execute(SCI_AUTOCCANCEL);
|
||||||
|
notifyView->execute(SCI_TAB);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// ======= End of SCN_*
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
case TCN_MOUSEHOVERING:
|
case TCN_MOUSEHOVERING:
|
||||||
case TCN_MOUSEHOVERSWITCHING:
|
case TCN_MOUSEHOVERSWITCHING:
|
||||||
{
|
{
|
||||||
@ -683,341 +1117,6 @@ BOOL Notepad_plus::notify(SCNotification *notification)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
case SCN_MARGINCLICK:
|
|
||||||
{
|
|
||||||
if (notification->nmhdr.hwndFrom == _mainEditView.getHSelf())
|
|
||||||
switchEditViewTo(MAIN_VIEW);
|
|
||||||
else if (notification->nmhdr.hwndFrom == _subEditView.getHSelf())
|
|
||||||
switchEditViewTo(SUB_VIEW);
|
|
||||||
|
|
||||||
intptr_t lineClick = _pEditView->execute(SCI_LINEFROMPOSITION, notification->position);
|
|
||||||
|
|
||||||
if (notification->margin == ScintillaEditView::_SC_MARGE_FOLDER)
|
|
||||||
{
|
|
||||||
_pEditView->marginClick(notification->position, notification->modifiers);
|
|
||||||
if (_pDocMap)
|
|
||||||
_pDocMap->fold(lineClick, _pEditView->isFolded(lineClick));
|
|
||||||
|
|
||||||
ScintillaEditView * unfocusView = isFromPrimary ? &_subEditView : &_mainEditView;
|
|
||||||
|
|
||||||
_smartHighlighter.highlightView(_pEditView, unfocusView);
|
|
||||||
}
|
|
||||||
else if ((notification->margin == ScintillaEditView::_SC_MARGE_SYMBOL) && !notification->modifiers)
|
|
||||||
{
|
|
||||||
if (!_pEditView->markerMarginClick(lineClick))
|
|
||||||
bookmarkToggle(lineClick);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SCN_MARGINRIGHTCLICK:
|
|
||||||
{
|
|
||||||
if (notification->nmhdr.hwndFrom == _mainEditView.getHSelf())
|
|
||||||
switchEditViewTo(MAIN_VIEW);
|
|
||||||
else if (notification->nmhdr.hwndFrom == _subEditView.getHSelf())
|
|
||||||
switchEditViewTo(SUB_VIEW);
|
|
||||||
|
|
||||||
if ((notification->margin == ScintillaEditView::_SC_MARGE_SYMBOL) && !notification->modifiers)
|
|
||||||
{
|
|
||||||
POINT p;
|
|
||||||
::GetCursorPos(&p);
|
|
||||||
MenuPosition& menuPos = getMenuPosition("search-bookmark");
|
|
||||||
HMENU hSearchMenu = ::GetSubMenu(_mainMenuHandle, menuPos._x);
|
|
||||||
if (hSearchMenu)
|
|
||||||
{
|
|
||||||
HMENU hBookmarkMenu = ::GetSubMenu(hSearchMenu, menuPos._y);
|
|
||||||
if (hBookmarkMenu)
|
|
||||||
{
|
|
||||||
TrackPopupMenu(hBookmarkMenu, 0, p.x, p.y, 0, _pPublicInterface->getHSelf(), NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SCN_FOLDINGSTATECHANGED :
|
|
||||||
{
|
|
||||||
if ((notification->nmhdr.hwndFrom == _mainEditView.getHSelf()) || (notification->nmhdr.hwndFrom == _subEditView.getHSelf()))
|
|
||||||
{
|
|
||||||
size_t lineClicked = notification->line;
|
|
||||||
|
|
||||||
if (!_isFolding)
|
|
||||||
{
|
|
||||||
addHotSpot();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_pDocMap)
|
|
||||||
_pDocMap->fold(lineClicked, _pEditView->isFolded(lineClicked));
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SCN_CHARADDED:
|
|
||||||
{
|
|
||||||
if (!_recordingMacro && !_playingBackMacro) // No macro recording or playing back
|
|
||||||
{
|
|
||||||
const NppGUI & nppGui = NppParameters::getInstance().getNppGUI();
|
|
||||||
if (nppGui._maintainIndent != autoIndent_none)
|
|
||||||
maintainIndentation(static_cast<wchar_t>(notification->ch));
|
|
||||||
|
|
||||||
Buffer* currentBuf = _pEditView->getCurrentBuffer();
|
|
||||||
if (currentBuf->allowAutoCompletion())
|
|
||||||
{
|
|
||||||
AutoCompletion* autoC = isFromPrimary ? &_autoCompleteMain : &_autoCompleteSub;
|
|
||||||
bool isColumnMode = _pEditView->execute(SCI_GETSELECTIONS) > 1; // Multi-Selection || Column mode)
|
|
||||||
if (nppGui._matchedPairConf.hasAnyPairsPair() && !isColumnMode)
|
|
||||||
autoC->insertMatchedChars(notification->ch, nppGui._matchedPairConf);
|
|
||||||
autoC->update(notification->ch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SCN_DOUBLECLICK:
|
|
||||||
{
|
|
||||||
if (!notifyView)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (notification->modifiers == SCMOD_CTRL)
|
|
||||||
{
|
|
||||||
const NppGUI & nppGUI = NppParameters::getInstance().getNppGUI();
|
|
||||||
|
|
||||||
std::string bufstring;
|
|
||||||
|
|
||||||
size_t position_of_click;
|
|
||||||
// For some reason Ctrl+DoubleClick on an empty line means that notification->position == 1.
|
|
||||||
// In that case we use SCI_GETCURRENTPOS to get the position.
|
|
||||||
if (notification->position != -1)
|
|
||||||
position_of_click = notification->position;
|
|
||||||
else
|
|
||||||
position_of_click = _pEditView->execute(SCI_GETCURRENTPOS);
|
|
||||||
|
|
||||||
// Anonymous scope to limit use of the buf pointer (much easier to deal with std::string).
|
|
||||||
{
|
|
||||||
char *buf;
|
|
||||||
|
|
||||||
if (nppGUI._delimiterSelectionOnEntireDocument)
|
|
||||||
{
|
|
||||||
// Get entire document.
|
|
||||||
auto length = notifyView->execute(SCI_GETLENGTH);
|
|
||||||
buf = new char[length + 1];
|
|
||||||
notifyView->execute(SCI_GETTEXT, length + 1, reinterpret_cast<LPARAM>(buf));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Get single line.
|
|
||||||
auto length = notifyView->execute(SCI_GETCURLINE);
|
|
||||||
buf = new char[length + 1];
|
|
||||||
notifyView->execute(SCI_GETCURLINE, length, reinterpret_cast<LPARAM>(buf));
|
|
||||||
|
|
||||||
// Compute the position of the click (relative to the beginning of the line).
|
|
||||||
const auto line_position = notifyView->execute(SCI_POSITIONFROMLINE, notifyView->getCurrentLineNumber());
|
|
||||||
position_of_click = position_of_click - line_position;
|
|
||||||
}
|
|
||||||
|
|
||||||
bufstring = buf;
|
|
||||||
delete [] buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
int leftmost_position = -1;
|
|
||||||
int rightmost_position = -1;
|
|
||||||
|
|
||||||
if (nppGUI._rightmostDelimiter == nppGUI._leftmostDelimiter)
|
|
||||||
{
|
|
||||||
// If the delimiters are the same (e.g. they are both a quotation mark), choose the ones
|
|
||||||
// which are closest to the clicked position.
|
|
||||||
for (int32_t i = static_cast<int32_t>(position_of_click); i >= 0; --i)
|
|
||||||
{
|
|
||||||
if (i >= static_cast<int32_t>(bufstring.size()))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (bufstring.at(i) == nppGUI._leftmostDelimiter)
|
|
||||||
{
|
|
||||||
// Respect escaped quotation marks.
|
|
||||||
if (nppGUI._leftmostDelimiter == '"')
|
|
||||||
{
|
|
||||||
if (! (i > 0 && bufstring.at(i - 1) == '\\'))
|
|
||||||
{
|
|
||||||
leftmost_position = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
leftmost_position = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (leftmost_position == -1)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Scan for right delimiter.
|
|
||||||
for (size_t i = position_of_click; i < bufstring.length(); ++i)
|
|
||||||
{
|
|
||||||
if (bufstring.at(i) == nppGUI._rightmostDelimiter)
|
|
||||||
{
|
|
||||||
// Respect escaped quotation marks.
|
|
||||||
if (nppGUI._rightmostDelimiter == '"')
|
|
||||||
{
|
|
||||||
if (! (i > 0 && bufstring.at(i - 1) == '\\'))
|
|
||||||
{
|
|
||||||
rightmost_position = static_cast<int32_t>(i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rightmost_position = static_cast<int32_t>(i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Find matching pairs of delimiters (e.g. parentheses).
|
|
||||||
// The pair where the distance from the left delimiter to position_of_click is at a minimum is the one we're looking for.
|
|
||||||
// Of course position_of_click must lie between the delimiters.
|
|
||||||
|
|
||||||
// This logic is required to handle cases like this:
|
|
||||||
// (size_t i = function(); i < _buffers.size(); i++)
|
|
||||||
|
|
||||||
std::stack<unsigned int> leftmost_delimiter_positions;
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < bufstring.length(); ++i)
|
|
||||||
{
|
|
||||||
if (bufstring.at(i) == nppGUI._leftmostDelimiter)
|
|
||||||
leftmost_delimiter_positions.push(i);
|
|
||||||
else if (bufstring.at(i) == nppGUI._rightmostDelimiter && ! leftmost_delimiter_positions.empty())
|
|
||||||
{
|
|
||||||
unsigned int matching_leftmost = leftmost_delimiter_positions.top();
|
|
||||||
leftmost_delimiter_positions.pop();
|
|
||||||
|
|
||||||
// We have either 1) chosen neither the left- or rightmost position, or 2) chosen both left- and rightmost position.
|
|
||||||
assert( (leftmost_position == -1 && rightmost_position == -1) || (leftmost_position >= 0 && rightmost_position >= 0) );
|
|
||||||
|
|
||||||
// Note: cast of leftmost_position to unsigned int is safe, since if leftmost_position is not -1 then it is guaranteed to be positive.
|
|
||||||
// If it was possible, leftmost_position and rightmost_position should be of type optional<unsigned int>.
|
|
||||||
if (matching_leftmost <= position_of_click && i >= position_of_click && (leftmost_position == -1 || matching_leftmost > static_cast<unsigned int>(leftmost_position)))
|
|
||||||
{
|
|
||||||
leftmost_position = matching_leftmost;
|
|
||||||
rightmost_position = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set selection to the position we found (if any).
|
|
||||||
if (rightmost_position != -1 && leftmost_position != -1)
|
|
||||||
{
|
|
||||||
if (nppGUI._delimiterSelectionOnEntireDocument)
|
|
||||||
{
|
|
||||||
notifyView->execute(SCI_SETCURRENTPOS, rightmost_position);
|
|
||||||
notifyView->execute(SCI_SETANCHOR, leftmost_position + 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const auto line_position = notifyView->execute(SCI_POSITIONFROMLINE, notifyView->getCurrentLineNumber());
|
|
||||||
notifyView->execute(SCI_SETCURRENTPOS, line_position + rightmost_position);
|
|
||||||
notifyView->execute(SCI_SETANCHOR, line_position + leftmost_position + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // Double click with no modifiers
|
|
||||||
// Check whether cursor is within URL
|
|
||||||
auto indicMsk = notifyView->execute(SCI_INDICATORALLONFOR, notification->position);
|
|
||||||
if (!(indicMsk & (1 << URL_INDIC)))
|
|
||||||
break;
|
|
||||||
|
|
||||||
auto startPos = notifyView->execute(SCI_INDICATORSTART, URL_INDIC, notification->position);
|
|
||||||
auto endPos = notifyView->execute(SCI_INDICATOREND, URL_INDIC, notification->position);
|
|
||||||
if ((notification->position < startPos) || (notification->position > endPos))
|
|
||||||
break;
|
|
||||||
|
|
||||||
// WM_LBUTTONUP goes to opening browser instead of Scintilla here, because the mouse is not captured.
|
|
||||||
// The missing message causes mouse cursor flicker as soon as the mouse cursor is moved to a position outside the text editing area.
|
|
||||||
::PostMessage(notifyView->getHSelf(), WM_LBUTTONUP, 0, 0);
|
|
||||||
|
|
||||||
// Revert selection of current word. Best to this early, otherwise the
|
|
||||||
// selected word is visible all the time while the browser is starting
|
|
||||||
notifyView->execute(SCI_SETSEL, notification->position, notification->position);
|
|
||||||
|
|
||||||
// Open URL
|
|
||||||
wstring url = notifyView->getGenericTextAsString(static_cast<size_t>(startPos), static_cast<size_t>(endPos));
|
|
||||||
::ShellExecute(_pPublicInterface->getHSelf(), L"open", url.c_str(), NULL, NULL, SW_SHOW);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SCN_UPDATEUI:
|
|
||||||
{
|
|
||||||
if (!notifyView)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
NppParameters& nppParam = NppParameters::getInstance();
|
|
||||||
NppGUI & nppGui = nppParam.getNppGUI();
|
|
||||||
|
|
||||||
// replacement for obsolete custom SCN_SCROLLED
|
|
||||||
if (notification->updated & SC_UPDATE_V_SCROLL)
|
|
||||||
{
|
|
||||||
addHotSpot(notifyView);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if it's searching/replacing, then do nothing
|
|
||||||
if (nppParam._isFindReplacing)
|
|
||||||
break;
|
|
||||||
|
|
||||||
Buffer* currentBuf = _pEditView->getCurrentBuffer();
|
|
||||||
if (notification->nmhdr.hwndFrom != _pEditView->getHSelf() && currentBuf->allowSmartHilite()) // notification come from unfocus view - both views ae visible
|
|
||||||
{
|
|
||||||
if (nppGui._smartHiliteOnAnotherView)
|
|
||||||
{
|
|
||||||
wchar_t selectedText[1024];
|
|
||||||
_pEditView->getGenericSelectedText(selectedText, sizeof(selectedText)/sizeof(wchar_t), false);
|
|
||||||
_smartHighlighter.highlightViewWithWord(notifyView, selectedText);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
braceMatch();
|
|
||||||
|
|
||||||
if (nppGui._enableTagsMatchHilite)
|
|
||||||
{
|
|
||||||
XmlMatchedTagsHighlighter xmlTagMatchHiliter(_pEditView);
|
|
||||||
xmlTagMatchHiliter.tagMatch(nppGui._enableTagAttrsHilite);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nppGui._enableSmartHilite && currentBuf->allowSmartHilite())
|
|
||||||
{
|
|
||||||
if (nppGui._disableSmartHiliteTmp)
|
|
||||||
nppGui._disableSmartHiliteTmp = false;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ScintillaEditView * anbotherView = isFromPrimary ? &_subEditView : &_mainEditView;
|
|
||||||
_smartHighlighter.highlightView(notifyView, anbotherView);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool selectionIsChanged = (notification->updated & SC_UPDATE_SELECTION) != 0;
|
|
||||||
// note: changing insert/overwrite mode will cause Scintilla to notify with SC_UPDATE_SELECTION
|
|
||||||
bool contentIsChanged = (notification->updated & SC_UPDATE_CONTENT) != 0;
|
|
||||||
if (selectionIsChanged || contentIsChanged)
|
|
||||||
{
|
|
||||||
updateStatusBar();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_pFuncList && (!_pFuncList->isClosed()) && _pFuncList->isVisible())
|
|
||||||
_pFuncList->markEntry();
|
|
||||||
AutoCompletion * autoC = isFromPrimary ? &_autoCompleteMain : &_autoCompleteSub;
|
|
||||||
autoC->update(0);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case TTN_GETDISPINFO:
|
case TTN_GETDISPINFO:
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -1045,7 +1144,7 @@ BOOL Notepad_plus::notify(SCNotification *notification)
|
|||||||
wcscpy_s(lpttt->szText, tipTmp.c_str());
|
wcscpy_s(lpttt->szText, tipTmp.c_str());
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BufferID idd = BUFFER_INVALID;
|
BufferID idd = BUFFER_INVALID;
|
||||||
if (hWin == _mainDocTab.getHSelf())
|
if (hWin == _mainDocTab.getHSelf())
|
||||||
@ -1061,7 +1160,7 @@ BOOL Notepad_plus::notify(SCNotification *notification)
|
|||||||
|
|
||||||
tipTmp = buf->getFullPathName();
|
tipTmp = buf->getFullPathName();
|
||||||
|
|
||||||
|
|
||||||
if (buf->isUntitled())
|
if (buf->isUntitled())
|
||||||
{
|
{
|
||||||
wstring tabCreatedTime = buf->tabCreatedTimeString();
|
wstring tabCreatedTime = buf->tabCreatedTimeString();
|
||||||
@ -1092,114 +1191,6 @@ BOOL Notepad_plus::notify(SCNotification *notification)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
case SCN_ZOOM:
|
|
||||||
{
|
|
||||||
if (!notifyView)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
ScintillaEditView * unfocusView = isFromPrimary ? &_subEditView : &_mainEditView;
|
|
||||||
_smartHighlighter.highlightView(notifyView, unfocusView);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SCN_MACRORECORD:
|
|
||||||
{
|
|
||||||
_macro.push_back(
|
|
||||||
recordedMacroStep(
|
|
||||||
notification->message,
|
|
||||||
notification->wParam,
|
|
||||||
notification->lParam
|
|
||||||
)
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SCN_PAINTED:
|
|
||||||
{
|
|
||||||
if (!notifyView)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
// Check if a restore position is needed.
|
|
||||||
// Restoring a position must done after SCN_PAINTED notification so that it works in every circumstances (including wrapped large file)
|
|
||||||
_mainEditView.restoreCurrentPosPostStep();
|
|
||||||
_subEditView.restoreCurrentPosPostStep();
|
|
||||||
|
|
||||||
// ViewMoveAtWrappingDisableFix: Disable wrapping messes up visible lines.
|
|
||||||
// Therefore save view position before in IDM_VIEW_WRAP and restore after SCN_PAINTED, as doc. says
|
|
||||||
if (_mainEditView.isWrapRestoreNeeded())
|
|
||||||
{
|
|
||||||
_mainEditView.restoreCurrentPosPreStep();
|
|
||||||
_mainEditView.setWrapRestoreNeeded(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_subEditView.isWrapRestoreNeeded())
|
|
||||||
{
|
|
||||||
_subEditView.restoreCurrentPosPreStep();
|
|
||||||
_subEditView.setWrapRestoreNeeded(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
notifyView->updateLineNumberWidth();
|
|
||||||
|
|
||||||
if (_syncInfo.doSync())
|
|
||||||
doSynScorll(HWND(notification->nmhdr.hwndFrom));
|
|
||||||
|
|
||||||
const NppParameters& nppParam = NppParameters::getInstance();
|
|
||||||
|
|
||||||
// if it's searching/replacing, then do nothing
|
|
||||||
if ((_linkTriggered && !nppParam._isFindReplacing) || notification->wParam == LINKTRIGGERED)
|
|
||||||
{
|
|
||||||
addHotSpot();
|
|
||||||
_linkTriggered = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_pDocMap && (!_pDocMap->isClosed()) && _pDocMap->isVisible() && !_pDocMap->isTemporarilyShowing())
|
|
||||||
{
|
|
||||||
_pDocMap->wrapMap();
|
|
||||||
_pDocMap->scrollMap();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SCN_NEEDSHOWN:
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SCN_CALLTIPCLICK:
|
|
||||||
{
|
|
||||||
AutoCompletion * autoC = isFromPrimary ? &_autoCompleteMain : &_autoCompleteSub;
|
|
||||||
autoC->callTipClick(notification->position);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SCN_AUTOCSELECTION:
|
|
||||||
{
|
|
||||||
if (!notifyView)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
const NppGUI& nppGui = NppParameters::getInstance().getNppGUI();
|
|
||||||
|
|
||||||
// if autocompletion is disabled and it is triggered manually, then both ENTER & TAB will insert the selection
|
|
||||||
if (nppGui._autocStatus == NppGUI::AutocStatus::autoc_none)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (notification->listCompletionMethod == SC_AC_NEWLINE && !nppGui._autocInsertSelectedUseENTER)
|
|
||||||
{
|
|
||||||
notifyView->execute(SCI_AUTOCCANCEL);
|
|
||||||
notifyView->execute(SCI_NEWLINE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (notification->listCompletionMethod == SC_AC_TAB && !nppGui._autocInsertSelectedUseTAB)
|
|
||||||
{
|
|
||||||
notifyView->execute(SCI_AUTOCCANCEL);
|
|
||||||
notifyView->execute(SCI_TAB);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case RBN_HEIGHTCHANGE:
|
case RBN_HEIGHTCHANGE:
|
||||||
{
|
{
|
||||||
SendMessage(_pPublicInterface->getHSelf(), WM_SIZE, 0, 0);
|
SendMessage(_pPublicInterface->getHSelf(), WM_SIZE, 0, 0);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user