From 883570e6637e5c4983a5c71f6f0302169bd0aab2 Mon Sep 17 00:00:00 2001 From: Derick Payne Date: Fri, 5 Jan 2018 12:35:47 +0200 Subject: [PATCH 1/9] Releasing Build 802 --- Build/Changes.txt | 22 ++++++++++++++++++++++ Readme.md | 1 - Versions/build.txt | 2 +- res/Notepad3.exe.manifest.conf | 2 +- src/VersionEx.h | 4 ++-- 5 files changed, 26 insertions(+), 5 deletions(-) diff --git a/Build/Changes.txt b/Build/Changes.txt index 4c2f31ff8..59fec5858 100644 --- a/Build/Changes.txt +++ b/Build/Changes.txt @@ -2,6 +2,28 @@ Rizonesoft Notepad3 CHANGES ================================================== +-------------------------------------------------- +Version 3.18.105.802 (5 January 2018) +-------------------------------------------------- +- Fix: Custom toolbar images ini settings added. +- Fix: Add hints for free text style properties in "Customize Schemes...". +- Fix: Test version numbers for month Jan - Sep (mono digit). +- Fix: Redundant echo of expected version string. +- Fix: Toggle line comments were placed at line end. +- Feature: (Mark Occurences) instant word highligting. +- Added: Switch to draw all occurrences in visible area only. +- Opt: Delayed mark all occurrences for better UI response. +- Enhancement: Async mark all occurrences via timer (UI response). +- Fix: "Match Current Word" should not highlight partial word matches in other lines. +- Added: Hyperlink Hotspot Style updates on UpdateUI event (visible area only) +- Fix: Fetching wrong visible document line number in case of hidden or wrapped lines. +- Fix: Ignoring queued timer event, if timer has been killed. +- Performance: Optimizing timer handling to avoid multiple calls of complex methods. +- Fix: use current lexer's default text font size as base font size for relative sizing of other styles. +- Performance: Fixed some issuses, which eat up CPU. +- Fix: mark occurrences counter not updated in time. +- Minor performance enhancements. + -------------------------------------------------- Version 3.17.1228.783 (28 December 2017) -------------------------------------------------- diff --git a/Readme.md b/Readme.md index c8e0c2bb4..26aef9b90 100644 --- a/Readme.md +++ b/Readme.md @@ -2,7 +2,6 @@ [![Build status](https://img.shields.io/appveyor/ci/rizonesoft/notepad3/master.svg)](https://ci.appveyor.com/project/rizonesoft/notepad3/branch/master) [![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) -[![Gratipay](https://img.shields.io/gratipay/project/Notepad3.svg)](https://gratipay.com/Notepad3/) [![](https://img.shields.io/badge/Donate-PayPal-blue.svg)](https://www.paypal.me/rizonesoft) Notepad3 is a fast and light-weight Scintilla-based text editor with syntax highlighting. It has a small memory footprint, but is powerful enough to handle most programming jobs. [Download Notepad3 here](https://www.rizonesoft.com/downloads/notepad3/). diff --git a/Versions/build.txt b/Versions/build.txt index 114370ffb..227b54a06 100644 --- a/Versions/build.txt +++ b/Versions/build.txt @@ -1 +1 @@ -795 +802 diff --git a/res/Notepad3.exe.manifest.conf b/res/Notepad3.exe.manifest.conf index ceef685ba..067b6aea3 100644 --- a/res/Notepad3.exe.manifest.conf +++ b/res/Notepad3.exe.manifest.conf @@ -3,7 +3,7 @@ Notepad3 diff --git a/src/VersionEx.h b/src/VersionEx.h index 4769b32fa..4c968c78d 100644 --- a/src/VersionEx.h +++ b/src/VersionEx.h @@ -5,7 +5,7 @@ // ////////////////////////////////////////////////////////// #define VERSION_MAJOR 3 #define VERSION_MINOR 18 -#define VERSION_REV 0102 -#define VERSION_BUILD 795 +#define VERSION_REV 105 +#define VERSION_BUILD 802 #define SCINTILLA_VER 402 #define ONIGMO_REGEX_VER 6.1.3 From 2d680c833ab83828c6c66e53deb5c2d11e1586a5 Mon Sep 17 00:00:00 2001 From: Rainer Kottenhoff Date: Fri, 5 Jan 2018 13:12:46 +0100 Subject: [PATCH 2/9] + performance: redraw indicator ranges (Mark Occurrences) only if needed - avoiding recursive SCN_UPDATEUI notifications --- src/Edit.c | 98 +++++++++++++++++++++++---------- src/Edit.h | 4 +- src/Notepad3.c | 146 ++++++++++++++++++++++++++++--------------------- src/Notepad3.h | 2 +- src/SciCall.h | 15 ++++- 5 files changed, 170 insertions(+), 95 deletions(-) diff --git a/src/Edit.c b/src/Edit.c index 5ae05e59e..5ec386897 100644 --- a/src/Edit.c +++ b/src/Edit.c @@ -89,6 +89,7 @@ extern BOOL bHyperlinkHotspot; extern int iMarkOccurrences; extern int iMarkOccurrencesCount; +extern BOOL bMarkOccurrencesMatchVisible; extern NP2ENCODING mEncoding[]; @@ -4289,21 +4290,19 @@ RegExResult_t __fastcall EditFindHasMatch(HWND hwnd, LPCEDITFINDREPLACE lpefr, B char szFind[FNDRPL_BUFFER]; int slen = EditGetFindStrg(hwnd, lpefr, szFind, COUNTOF(szFind)); - const int iTextLength = SciCall_GetTextLength(); + const int iStart = bFirstMatchOnly ? SciCall_GetSelectionStart() : 0; + const int iTextLength = SciCall_GetTextLength(); - int start = bFirstMatchOnly ? (int)SendMessage(hwnd, SCI_GETSELECTIONNSTART, 0, 0) : 0; - int end = iTextLength; - - int iPos = EditFindInTarget(hwnd, szFind, slen, (int)(lpefr->fuFlags), &start, &end, FALSE); + int start = iStart; + int end = iTextLength; + int iPos = EditFindInTarget(hwnd, szFind, slen, (int)(lpefr->fuFlags), &start, &end, FALSE); if (!bFirstMatchOnly) { if (bMarkAll && (iPos >= 0)) { + EditClearAllMarks(hwnd, 0, iTextLength); EditMarkAll(hwnd, szFind, (int)(lpefr->fuFlags), 0, iTextLength, FALSE, FALSE); } - else { - EditMarkAll(hwnd, "", 0, 0, iTextLength, FALSE, FALSE); - } } return ((iPos >= 0) ? MATCH : ((iPos == -1) ? NO_MATCH : INVALID)); } @@ -4331,7 +4330,8 @@ INT_PTR CALLBACK EditFindReplaceDlgProcW(HWND hwnd,UINT umsg,WPARAM wParam,LPARA static HBRUSH hBrushGreen; static HBRUSH hBrushBlue; - static int iSaveMarkOcc = -1; + static int iSaveMarkOcc = -1; + static BOOL bSaveOccVisible = FALSE; switch(umsg) { @@ -4346,11 +4346,16 @@ INT_PTR CALLBACK EditFindReplaceDlgProcW(HWND hwnd,UINT umsg,WPARAM wParam,LPARA iSaveMarkOcc = iMarkOccurrences; EnableCmd(GetMenu(g_hwndMain), IDM_VIEW_MARKOCCUR_ONOFF, FALSE); iMarkOccurrences = 0; + bSaveOccVisible = bMarkOccurrencesMatchVisible; + EnableCmd(GetMenu(g_hwndMain), IDM_VIEW_MARKOCCUR_VISIBLE, FALSE); + bMarkOccurrencesMatchVisible = FALSE; CheckDlgButton(hwnd, IDC_ALL_OCCURRENCES, BST_CHECKED); } else { iSaveMarkOcc = -1; + bSaveOccVisible = bMarkOccurrencesMatchVisible; CheckDlgButton(hwnd, IDC_ALL_OCCURRENCES, BST_UNCHECKED); + EditClearAllMarks(g_hwndEdit, 0, -1); } // Get the current code page for Unicode conversion @@ -4540,6 +4545,9 @@ INT_PTR CALLBACK EditFindReplaceDlgProcW(HWND hwnd,UINT umsg,WPARAM wParam,LPARA SendMessage(g_hwndMain, WM_COMMAND, (WPARAM)MAKELONG(IDM_VIEW_MARKOCCUR_ONOFF, 1), 0); } } + bMarkOccurrencesMatchVisible = bSaveOccVisible; + EnableCmd(GetMenu(g_hwndMain), IDM_VIEW_MARKOCCUR_VISIBLE, bMarkOccurrencesMatchVisible); + KillTimer(hwnd, IDT_TIMER_MRKALL); } return FALSE; @@ -4614,6 +4622,9 @@ INT_PTR CALLBACK EditFindReplaceDlgProcW(HWND hwnd,UINT umsg,WPARAM wParam,LPARA iSaveMarkOcc = iMarkOccurrences; EnableCmd(GetMenu(g_hwndMain), IDM_VIEW_MARKOCCUR_ONOFF, FALSE); iMarkOccurrences = 0; + bSaveOccVisible = bMarkOccurrencesMatchVisible; + EnableCmd(GetMenu(g_hwndMain), IDM_VIEW_MARKOCCUR_VISIBLE, FALSE); + bMarkOccurrencesMatchVisible = FALSE; } else { // switched OFF lpefr->bMarkOccurences = FALSE; @@ -4624,6 +4635,10 @@ INT_PTR CALLBACK EditFindReplaceDlgProcW(HWND hwnd,UINT umsg,WPARAM wParam,LPARA } } iSaveMarkOcc = -1; + bMarkOccurrencesMatchVisible = bSaveOccVisible; + EnableCmd(GetMenu(g_hwndMain), IDM_VIEW_MARKOCCUR_VISIBLE, bMarkOccurrencesMatchVisible); + bSaveOccVisible = FALSE; + EditClearAllMarks(g_hwndEdit, 0, -1); InvalidateRect(GetDlgItem(hwnd, IDC_FINDTEXT), NULL, TRUE); } bFlagsChanged = TRUE; @@ -5454,10 +5469,16 @@ BOOL EditReplaceAllInSelection(HWND hwnd,LPCEDITFINDREPLACE lpefr,BOOL bShowInfo // // EditClearAllMarks() // -void EditClearAllMarks(HWND hwnd) +void EditClearAllMarks(HWND hwnd, int iRangeStart, int iRangeEnd) { + if (iRangeEnd <= 0) { + iRangeEnd = SciCall_GetTextLength(); + } + if (iRangeStart > iRangeEnd) { + swapi(&iRangeStart, &iRangeEnd); + } SendMessage(hwnd, SCI_SETINDICATORCURRENT, INDIC_NP3_MARK_OCCURANCE, 0); - SendMessage(hwnd, SCI_INDICATORCLEARRANGE, 0, SciCall_GetTextLength()); + SendMessage(hwnd, SCI_INDICATORCLEARRANGE, iRangeStart, iRangeEnd); iMarkOccurrencesCount = -1; // -1 ! } @@ -5479,8 +5500,6 @@ void EditMarkAll(HWND hwnd, char* pszFind, int flags, int rangeStart, int rangeE else pszText = txtBuffer; - EditClearAllMarks(hwnd); - if (pszFind == NULL) { if (SciCall_IsSelectionEmpty()) { @@ -5547,6 +5566,8 @@ void EditMarkAll(HWND hwnd, char* pszFind, int flags, int rangeStart, int rangeE int start = rangeStart; int end = rangeEnd; + SendMessage(hwnd, SCI_SETINDICATORCURRENT, INDIC_NP3_MARK_OCCURANCE, 0); + do { ++iMarkOccurrencesCount; @@ -5555,8 +5576,11 @@ void EditMarkAll(HWND hwnd, char* pszFind, int flags, int rangeStart, int rangeE if (iPos < 0) break; // not found - // mark this match - SendMessage(hwnd, SCI_INDICATORFILLRANGE, iPos, (end - start)); + // mark this match if not done before + if (!SciCall_IndicatorValueAt(INDIC_NP3_MARK_OCCURANCE, iPos)) { + SciCall_IndicatorFillRange(iPos, (end - start)); + } + start = end; end = rangeEnd; @@ -5709,8 +5733,7 @@ void EditUpdateUrlHotspots(HWND hwnd, int startPos, int endPos, BOOL bActiveHots } // 1st apply current lexer style - SciCall_StartStyling(startPos); - SendMessage(hwnd, SCI_COLOURISE, 0, (LPARAM)-1); + EditFinalizeStyling(hwnd); const char* pszUrlRegEx = "\\b(?:(?:https?|ftp|file)://|www\\.|ftp\\.)" "(?:\\([-A-Z0-9+&@#/%=~_|$?!:,.]*\\)|[-A-Z0-9+&@#/%=~_|$?!:,.])*" @@ -5747,15 +5770,11 @@ void EditUpdateUrlHotspots(HWND hwnd, int startPos, int endPos, BOOL bActiveHots } while (start < end); + if (bActiveHotspot) - { SciCall_StartStyling(endPos); - UpdateEditWndUI(); // does not apply lexer style - } - else { + else SciCall_StartStyling(startPos); - SendMessage(hwnd, SCI_COLOURISE, 0, (LPARAM)-1); - } } @@ -5795,6 +5814,32 @@ BOOL __fastcall EditHighlightIfBrace(HWND hwnd, int iPos) { } +//============================================================================= +// +// EditApplyLexerStyle() +// +void EditApplyLexerStyle(HWND hwnd, int iRangeStart, int iRangeEnd) +{ + SendMessage(hwnd, SCI_COLOURISE, (WPARAM)iRangeStart, (LPARAM)iRangeEnd); +} + + +//============================================================================= +// +// EditFinalizeStyling() +// +void EditFinalizeStyling(HWND hwnd) +{ + const int iEndStyled = SciCall_GetEndStyled(); + + if (iEndStyled < SciCall_GetTextLength()) + { + const int iLineEndStyled = SciCall_LineFromPosition(iEndStyled); + const int iStartStyling = SciCall_PositionFromLine(iLineEndStyled); + EditApplyLexerStyle(hwnd, iStartStyling, -1); + } +} + //============================================================================= // @@ -5802,12 +5847,7 @@ BOOL __fastcall EditHighlightIfBrace(HWND hwnd, int iPos) { // void EditMatchBrace(HWND hwnd) { - int iEndStyled = SciCall_GetEndStyled(); - if (iEndStyled < SciCall_GetTextLength()) { - int iLine = SciCall_LineFromPosition(iEndStyled); - iEndStyled = SciCall_PositionFromLine(iLine); - SendMessage(hwnd, SCI_COLOURISE, iEndStyled, -1); - } + EditFinalizeStyling(hwnd); int iPos = SciCall_GetCurrentPos(); diff --git a/src/Edit.h b/src/Edit.h index d80e82f6a..d6445a704 100644 --- a/src/Edit.h +++ b/src/Edit.h @@ -122,13 +122,15 @@ BOOL EditPrint(HWND,LPCWSTR,LPCWSTR); void EditPrintSetup(HWND); void EditPrintInit(); void EditMatchBrace(HWND); -void EditClearAllMarks(HWND); +void EditClearAllMarks(HWND,int,int); void EditMarkAll(HWND,char*,int,int,int,BOOL,BOOL); void EditUpdateUrlHotspots(HWND, int, int, BOOL); void EditSetAccelWordNav(HWND,BOOL); void EditCompleteWord(HWND,BOOL); void EditGetBookmarkList(HWND,LPWSTR,int); void EditSetBookmarkList(HWND,LPCWSTR); +void EditApplyLexerStyle(HWND, int, int); +void EditFinalizeStyling(HWND); //void SciInitThemes(HWND); diff --git a/src/Notepad3.c b/src/Notepad3.c index 9383c6818..871b5abff 100644 --- a/src/Notepad3.c +++ b/src/Notepad3.c @@ -324,6 +324,11 @@ static volatile LONG g_lTimerBits = 0; #define TEST_AND_SET(B) InterlockedBitTestAndSet(&g_lTimerBits, B) #define TEST_AND_RESET(B) InterlockedBitTestAndReset(&g_lTimerBits, B) + +// SCN_UPDATEUI notification +#define SC_UPDATE_NP3_INTERNAL_NOTIFY (SC_UPDATE_H_SCROLL << 1) + + //============================================================================= // // Flags @@ -1164,6 +1169,7 @@ LRESULT CALLBACK MainWndProc(HWND hwnd,UINT umsg,WPARAM wParam,LPARAM lParam) // update Scintilla colors case WM_SYSCOLORCHANGE: UpdateLineNumberWidth(); + EditClearAllMarks(g_hwndEdit, 0, -1); MarkAllOccurrences(); EditUpdateUrlHotspots(g_hwndEdit, 0, SciCall_GetTextLength(), bHyperlinkHotspot); return DefWindowProc(hwnd,umsg,wParam,lParam); @@ -1770,6 +1776,7 @@ void MsgThemeChanged(HWND hwnd,WPARAM wParam,LPARAM lParam) UpdateToolbar(); UpdateStatusbar(); UpdateLineNumberWidth(); + EditClearAllMarks(g_hwndEdit, 0, -1); MarkAllOccurrences(); EditUpdateUrlHotspots(g_hwndEdit, 0, SciCall_GetTextLength(), bHyperlinkHotspot); @@ -2533,6 +2540,8 @@ void __fastcall MarkAllOccurrencesTimer() int iPosStart = SciCall_PositionFromLine(iStartLine); int iPosEnd = SciCall_GetLineEndPosition(iEndLine); + // !!! don't clear all marks, else this method is re-called + // !!! on UpdateUI notification on drawing indicator mark EditMarkAll(g_hwndEdit, NULL, bMarkOccurrencesCurrentWord, iPosStart, iPosEnd, bMarkOccurrencesMatchCase, bMarkOccurrencesMatchWords); } else { @@ -4290,26 +4299,27 @@ LRESULT MsgCommand(HWND hwnd, WPARAM wParam, LPARAM lParam) case IDM_VIEW_ACCELWORDNAV: bAccelWordNavigation = (bAccelWordNavigation) ? FALSE : TRUE; // toggle EditSetAccelWordNav(g_hwndEdit,bAccelWordNavigation); + EditClearAllMarks(g_hwndEdit, 0, -1); MarkAllOccurrences(); break; case IDM_VIEW_MARKOCCUR_ONOFF: iMarkOccurrences = (iMarkOccurrences == 0) ? max(1, IniGetInt(L"Settings", L"MarkOccurrences", 1)) : 0; + EditClearAllMarks(g_hwndEdit, 0, -1); if (iMarkOccurrences != 0) { MarkAllOccurrences(); } - else { - EditClearAllMarks(g_hwndEdit); - } break; case IDM_VIEW_MARKOCCUR_CASE: bMarkOccurrencesMatchCase = (bMarkOccurrencesMatchCase) ? FALSE : TRUE; + EditClearAllMarks(g_hwndEdit, 0, -1); MarkAllOccurrences(); break; case IDM_VIEW_MARKOCCUR_VISIBLE: bMarkOccurrencesMatchVisible = (bMarkOccurrencesMatchVisible) ? FALSE : TRUE; + EditClearAllMarks(g_hwndEdit, 0, -1); MarkAllOccurrences(); break; @@ -4318,6 +4328,7 @@ LRESULT MsgCommand(HWND hwnd, WPARAM wParam, LPARAM lParam) if (bMarkOccurrencesMatchWords) { bMarkOccurrencesCurrentWord = FALSE; } + EditClearAllMarks(g_hwndEdit, 0, -1); MarkAllOccurrences(); break; @@ -4326,6 +4337,7 @@ LRESULT MsgCommand(HWND hwnd, WPARAM wParam, LPARAM lParam) if (bMarkOccurrencesCurrentWord) { bMarkOccurrencesMatchWords = FALSE; } + EditClearAllMarks(g_hwndEdit, 0, -1); MarkAllOccurrences(); break; @@ -4382,7 +4394,7 @@ LRESULT MsgCommand(HWND hwnd, WPARAM wParam, LPARAM lParam) case IDM_VIEW_MATCHBRACES: bMatchBraces = (bMatchBraces) ? FALSE : TRUE; if (bMatchBraces) - UpdateEditWndUI(); + EditMatchBrace(g_hwndEdit); else SendMessage(g_hwndEdit,SCI_BRACEHIGHLIGHT,(WPARAM)-1,(LPARAM)-1); break; @@ -5600,23 +5612,31 @@ LRESULT MsgNotify(HWND hwnd,WPARAM wParam,LPARAM lParam) case SCN_UPDATEUI: - if (scn->updated & SC_UPDATE_SELECTION) + //if (scn->updated & SC_UPDATE_NP3_INTERNAL_NOTIFY) { + // // special case + //} + //else + + if (scn->updated & (SC_UPDATE_SELECTION | SC_UPDATE_CONTENT)) { - // !!! SC_UPDATE_CONTENT is triggered too often, + // !!! SC_UPDATE_CONTENT is triggered very often , // even if nothing relevant has been modified // relevant modifications are handled in SCN_MODIFIED !!! //~InvalidateSelections(); // fixed in SCI ? - if (iMarkOccurrences) { - MarkAllOccurrences(); - } - // Brace Match if (bMatchBraces) { EditMatchBrace(g_hwndEdit); } + if (iMarkOccurrences) { + if (scn->updated & SC_UPDATE_SELECTION) { + EditClearAllMarks(g_hwndEdit, 0, -1); + } + MarkAllOccurrences(); + } + if (bHyperlinkHotspot) { UpdateVisibleUrlHotspot(); } @@ -5655,6 +5675,11 @@ LRESULT MsgNotify(HWND hwnd,WPARAM wParam,LPARAM lParam) } UpdateToolbar(); + + if (iMarkOccurrences) { + EditClearAllMarks(g_hwndEdit, 0, -1); + MarkAllOccurrences(); + } UpdateStatusbar(); bModified = TRUE; @@ -7121,25 +7146,6 @@ int CreateIniFileEx(LPCWSTR lpszIniFile) { } -//============================================================================= -// -// UpdateEditWndUI() -// -void UpdateEditWndUI() -{ - struct SCNotification scn; - scn.nmhdr.hwndFrom = g_hwndEdit; - scn.nmhdr.idFrom = IDC_EDIT; - scn.nmhdr.code = SCN_UPDATEUI; - scn.updated = SC_UPDATE_CONTENT; - //SendMessage(g_hwndMain, WM_NOTIFY, IDC_EDIT, (LPARAM)&scn); - PostMessage(g_hwndMain, WM_NOTIFY, IDC_EDIT, (LPARAM)&scn); - // --------------------------------------------------------------------------- - // ~~~ don't Send/Post Message(hwnd, SCI_COLOURISE, 0, (LPARAM)-1); here ! ~~~ - // --------------------------------------------------------------------------- -} - - //============================================================================= // // MarkAllOccurrences() @@ -7158,7 +7164,6 @@ void UpdateVisibleUrlHotspot() { SetTimer(g_hwndMain, IDT_TIMER_UPDATE_HOTSPOT, 100, NULL); TEST_AND_SET(TIMER_BIT_UPDATE_HYPER); - } @@ -7228,7 +7233,6 @@ void UpdateStatusbar() static WCHAR tchOcc[32] = { L'\0' }; static WCHAR tchDocPos[256] = { L'\0' }; - int iBytes; static WCHAR tchBytes[64] = { L'\0' }; static WCHAR tchDocSize[256] = { L'\0' }; @@ -7237,21 +7241,18 @@ void UpdateStatusbar() static WCHAR tchLexerName[128] = { L'\0' }; static WCHAR tchLinesSelected[32] = { L'\0' }; - if (!bShowStatusbar) - return; + if (!bShowStatusbar) { return; } - int iPos = (int)SendMessage(g_hwndEdit, SCI_GETCURRENTPOS, 0, 0); + const int iPos = SciCall_GetCurrentPos(); - int iLn = (int)SendMessage(g_hwndEdit, SCI_LINEFROMPOSITION, iPos, 0) + 1; - StringCchPrintf(tchLn, COUNTOF(tchLn), L"%i", iLn); + StringCchPrintf(tchLn, COUNTOF(tchLn), L"%i", SciCall_LineFromPosition(iPos) + 1); FormatNumberStr(tchLn); StringCchPrintf(tchLines, COUNTOF(tchLines), L"%i", SciCall_GetLineCount()); FormatNumberStr(tchLines); - int iCol = (int)SendMessage(g_hwndEdit, SCI_GETCOLUMN, iPos, 0) + 1; + int iCol = SciCall_GetColumn(iPos) + 1; iCol += (int)SendMessage(g_hwndEdit, SCI_GETSELECTIONNCARETVIRTUALSPACE, 0, 0); - StringCchPrintf(tchCol, COUNTOF(tchCol), L"%i", iCol); FormatNumberStr(tchCol); @@ -7260,18 +7261,17 @@ void UpdateStatusbar() FormatNumberStr(tchCols); } - int iSelStart = (int)SendMessage(g_hwndEdit, SCI_GETSELECTIONSTART, 0, 0); - int iSelEnd = (int)SendMessage(g_hwndEdit, SCI_GETSELECTIONEND, 0, 0); - // Print number of selected chars in statusbar + const int iSelStart = SciCall_GetSelectionStart(); + const int iSelEnd = SciCall_GetSelectionEnd(); if (SC_SEL_RECTANGLE != SendMessage(g_hwndEdit, SCI_GETSELECTIONMODE, 0, 0)) { - int iSel = (int)SendMessage(g_hwndEdit, SCI_COUNTCHARACTERS, iSelStart, iSelEnd); + const int iSel = (int)SendMessage(g_hwndEdit, SCI_COUNTCHARACTERS, iSelStart, iSelEnd); StringCchPrintf(tchSel, COUNTOF(tchSel), L"%i", iSel); FormatNumberStr(tchSel); } - else + else { StringCchCopy(tchSel, COUNTOF(tchSel), L"--"); - + } if ((iMarkOccurrencesCount > 0) && !bMarkOccurrencesMatchVisible) { StringCchPrintf(tchOcc, COUNTOF(tchOcc), L"%i", iMarkOccurrencesCount); @@ -7281,39 +7281,47 @@ void UpdateStatusbar() StringCchCopy(tchOcc, COUNTOF(tchOcc), L"--"); } - // Print number of lines selected lines in statusbar - int iLineStart = (int)SendMessage(g_hwndEdit, SCI_LINEFROMPOSITION, iSelStart, 0); - int iLineEnd = (int)SendMessage(g_hwndEdit, SCI_LINEFROMPOSITION, iSelEnd, 0); - int iStartOfLinePos = (int)SendMessage(g_hwndEdit, SCI_POSITIONFROMLINE, iLineEnd, 0); - int iLinesSelected = iLineEnd - iLineStart; - if ((iSelStart != iSelEnd) && (iStartOfLinePos != iSelEnd)) iLinesSelected += 1; + // Print number of selected lines in statusbar + + const int iLineStart = SciCall_LineFromPosition(iSelStart); + const int iLineEnd = SciCall_LineFromPosition(iSelEnd); + const int iStartOfLinePos = SciCall_PositionFromLine(iLineEnd); + int iLinesSelected = (iLineEnd - iLineStart); + if ((iSelStart != iSelEnd) && (iStartOfLinePos != iSelEnd)) { iLinesSelected += 1; } StringCchPrintf(tchLinesSelected, COUNTOF(tchLinesSelected), L"%i", iLinesSelected); FormatNumberStr(tchLinesSelected); - if (!bMarkLongLines) + if (!bMarkLongLines) { FormatString(tchDocPos, COUNTOF(tchDocPos), IDS_DOCPOS, tchLn, tchLines, tchCol, tchSel, tchLinesSelected, tchOcc); - else + } + else { FormatString(tchDocPos, COUNTOF(tchDocPos), IDS_DOCPOS2, tchLn, tchLines, tchCol, tchCols, tchSel, tchLinesSelected, tchOcc); - - iBytes = (int)SendMessage(g_hwndEdit, SCI_GETLENGTH, 0, 0); + } + const int iBytes = SciCall_GetTextLength(); StrFormatByteSize(iBytes, tchBytes, COUNTOF(tchBytes)); FormatString(tchDocSize, COUNTOF(tchDocSize), IDS_DOCSIZE, tchBytes); Encoding_GetLabel(Encoding_Current(CPI_GET)); - if (iEOLMode == SC_EOL_CR) + if (iEOLMode == SC_EOL_CR) + { StringCchCopy(tchEOLMode, COUNTOF(tchEOLMode), L" CR"); - else if (iEOLMode == SC_EOL_LF) + } + else if (iEOLMode == SC_EOL_LF) + { StringCchCopy(tchEOLMode, COUNTOF(tchEOLMode), L" LF"); - else + } + else { StringCchCopy(tchEOLMode, COUNTOF(tchEOLMode), L" CR+LF"); - - if (SendMessage(g_hwndEdit, SCI_GETOVERTYPE, 0, 0)) + } + if (SendMessage(g_hwndEdit, SCI_GETOVERTYPE, 0, 0)) + { StringCchCopy(tchOvrMode, COUNTOF(tchOvrMode), L" OVR"); - else + } + else { StringCchCopy(tchOvrMode, COUNTOF(tchOvrMode), L" INS"); - + } Style_GetCurrentLexerName(tchLexerName, COUNTOF(tchLexerName)); StatusSetText(g_hwndStatus, STATUS_DOCPOS, tchDocPos); @@ -7367,6 +7375,22 @@ void UpdateSettingsCmds() } +//============================================================================= +// +// UpdateUI() +// +void UpdateUI() +{ + struct SCNotification scn; + scn.nmhdr.hwndFrom = g_hwndEdit; + scn.nmhdr.idFrom = IDC_EDIT; + scn.nmhdr.code = SCN_UPDATEUI; + scn.updated = (SC_UPDATE_CONTENT | SC_UPDATE_NP3_INTERNAL_NOTIFY); + SendMessage(g_hwndMain, WM_NOTIFY, IDC_EDIT, (LPARAM)&scn); + //PostMessage(g_hwndMain, WM_NOTIFY, IDC_EDIT, (LPARAM)&scn); +} + + //============================================================================= // // InvalidateSelections() diff --git a/src/Notepad3.h b/src/Notepad3.h index 71ca584ab..988420655 100644 --- a/src/Notepad3.h +++ b/src/Notepad3.h @@ -140,12 +140,12 @@ int CreateIniFileEx(LPCWSTR); void MarkAllOccurrences(); -void UpdateEditWndUI(); void UpdateToolbar(); void UpdateStatusbar(); void UpdateLineNumberWidth(); void UpdateSettingsCmds(); void UpdateVisibleUrlHotspot(); +void UpdateUI(); void InvalidateSelections(); diff --git a/src/SciCall.h b/src/SciCall.h index 5e45a0546..d3dc4f698 100644 --- a/src/SciCall.h +++ b/src/SciCall.h @@ -98,6 +98,7 @@ DeclareSciCallV1(GotoPos, GOTOPOS, int, position); DeclareSciCallV1(GotoLine, GOTOLINE, int, line); DeclareSciCallR1(PositionBefore, POSITIONBEFORE, int, Sci_Position, position); DeclareSciCallR1(PositionAfter, POSITIONAFTER, int, Sci_Position, position); +DeclareSciCallR1(GetCharAt, GETCHARAT, char, Sci_Position, position); DeclareSciCallR0(GetLineCount, GETLINECOUNT, int); DeclareSciCallR0(GetTextLength, GETTEXTLENGTH, int); @@ -105,13 +106,11 @@ DeclareSciCallR1(LineLength, LINELENGTH, int, Sci_Position, line); DeclareSciCallR1(LineFromPosition, LINEFROMPOSITION, int, Sci_Position, position); DeclareSciCallR1(PositionFromLine, POSITIONFROMLINE, int, Sci_Position, line); DeclareSciCallR1(GetLineEndPosition, GETLINEENDPOSITION, int, Sci_Position, line); -DeclareSciCallR0(GetEndStyled, GETENDSTYLED, int); DeclareSciCallR1(GetColumn, GETCOLUMN, int, Sci_Position, position); DeclareSciCallR0(LinesOnScreen, LINESONSCREEN, int); DeclareSciCallR0(GetFirstVisibleLine, GETFIRSTVISIBLELINE, int); DeclareSciCallR1(DocLineFromVisible, DOCLINEFROMVISIBLE, int, Sci_Position, line); -DeclareSciCallR1(GetCharAt, GETCHARAT, char, Sci_Position, position); //============================================================================= // @@ -130,8 +129,9 @@ DeclareSciCallV2(SetYCaretPolicy, SETYCARETPOLICY, int, caretPolicy, int, caretS // DeclareSciCallR1(StyleGetFore, STYLEGETFORE, COLORREF, int, styleNumber); DeclareSciCallR1(StyleGetBack, STYLEGETBACK, COLORREF, int, styleNumber); -DeclareSciCallV1(StartStyling, STARTSTYLING, Sci_Position, position); DeclareSciCallV2(SetStyling, SETSTYLING, Sci_PositionCR, length, int, style); +DeclareSciCallV1(StartStyling, STARTSTYLING, Sci_Position, position); +DeclareSciCallR0(GetEndStyled, GETENDSTYLED, int); //============================================================================= // @@ -156,6 +156,15 @@ DeclareSciCallV2(MarkerSetFore, MARKERSETFORE, int, markerNumber, COLORREF, colo DeclareSciCallV2(MarkerSetBack, MARKERSETBACK, int, markerNumber, COLORREF, colour); +//============================================================================= +// +// Indicators +// +// +DeclareSciCallR2(IndicatorValueAt, INDICATORVALUEAT, int, int, indicatorID, Sci_Position, position); +DeclareSciCallV2(IndicatorFillRange, INDICATORFILLRANGE, Sci_Position, position, Sci_Position, length); + + //============================================================================= // // Folding From b352dd05eb96253e336c777009a475c00a010507 Mon Sep 17 00:00:00 2001 From: Rainer Kottenhoff Date: Fri, 5 Jan 2018 14:20:41 +0100 Subject: [PATCH 3/9] + fix: Mark Occurrences: force position progress in case of zero-length matches --- src/Edit.c | 9 ++++++--- src/Notepad3.c | 5 +---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Edit.c b/src/Edit.c index 5ec386897..49941d84c 100644 --- a/src/Edit.c +++ b/src/Edit.c @@ -5568,16 +5568,19 @@ void EditMarkAll(HWND hwnd, char* pszFind, int flags, int rangeStart, int rangeE SendMessage(hwnd, SCI_SETINDICATORCURRENT, INDIC_NP3_MARK_OCCURANCE, 0); + int iPos = -1; do { - ++iMarkOccurrencesCount; - int iPos = EditFindInTarget(hwnd, pszText, iFindLength, flags, &start, &end, (end == start)); + iPos = EditFindInTarget(hwnd, pszText, iFindLength, flags, &start, &end, (start == iPos)); + + ++iMarkOccurrencesCount; // -1 -> 0 if (iPos < 0) break; // not found // mark this match if not done before - if (!SciCall_IndicatorValueAt(INDIC_NP3_MARK_OCCURANCE, iPos)) { + if (!(SciCall_IndicatorValueAt(INDIC_NP3_MARK_OCCURANCE, end) && + SciCall_IndicatorValueAt(INDIC_NP3_MARK_OCCURANCE, start))) { SciCall_IndicatorFillRange(iPos, (end - start)); } diff --git a/src/Notepad3.c b/src/Notepad3.c index 871b5abff..9610b7ee0 100644 --- a/src/Notepad3.c +++ b/src/Notepad3.c @@ -5619,10 +5619,6 @@ LRESULT MsgNotify(HWND hwnd,WPARAM wParam,LPARAM lParam) if (scn->updated & (SC_UPDATE_SELECTION | SC_UPDATE_CONTENT)) { - // !!! SC_UPDATE_CONTENT is triggered very often , - // even if nothing relevant has been modified - // relevant modifications are handled in SCN_MODIFIED !!! - //~InvalidateSelections(); // fixed in SCI ? // Brace Match @@ -5631,6 +5627,7 @@ LRESULT MsgNotify(HWND hwnd,WPARAM wParam,LPARAM lParam) } if (iMarkOccurrences) { + // clear marks only, if caret/selection changed if (scn->updated & SC_UPDATE_SELECTION) { EditClearAllMarks(g_hwndEdit, 0, -1); } From bff0f82e124b2ccecc2ce128c5444446683c4012 Mon Sep 17 00:00:00 2001 From: Rainer Kottenhoff Date: Fri, 5 Jan 2018 15:47:51 +0100 Subject: [PATCH 4/9] + performance: Mark Occurrence triggers enhancements --- src/Edit.c | 54 ++++++++++++++++++++++++++++++++++---------------- src/Notepad3.c | 4 ++-- 2 files changed, 39 insertions(+), 19 deletions(-) diff --git a/src/Edit.c b/src/Edit.c index 49941d84c..b489eff21 100644 --- a/src/Edit.c +++ b/src/Edit.c @@ -110,6 +110,13 @@ static char PunctuationCharsAccelerated[1] = { '\0' }; // empty! //static WCHAR W_WhiteSpaceCharsAccelerated[DELIM_BUFFER] = { L'\0' }; +// Timer bitfield +static volatile LONG g_lEditTimerBits = 0; +#define TIMER_BIT_MARK_OCC 1L +//#define TIMER_BIT_ONOTHER_TIMER 2L +#define TEST_AND_SET(B) InterlockedBitTestAndSet(&g_lEditTimerBits, B) +#define TEST_AND_RESET(B) InterlockedBitTestAndReset(&g_lEditTimerBits, B) + enum AlignMask { ALIGN_LEFT = 0, @@ -4309,6 +4316,17 @@ RegExResult_t __fastcall EditFindHasMatch(HWND hwnd, LPCEDITFINDREPLACE lpefr, B +//============================================================================= +// +// EditFindReplaceDlgProcW() +// +static void __fastcall EditSetTimerMarkAll(HWND hwnd) +{ + TEST_AND_SET(TIMER_BIT_MARK_OCC); + SetTimer(hwnd, IDT_TIMER_MRKALL, 100, NULL); +} + + //============================================================================= // // EditFindReplaceDlgProcW() @@ -4529,7 +4547,7 @@ INT_PTR CALLBACK EditFindReplaceDlgProcW(HWND hwnd,UINT umsg,WPARAM wParam,LPARA EditSetSearchFlags(hwnd, lpefr); bFlagsChanged = TRUE; - SetTimer(hwnd, IDT_TIMER_MRKALL, 100, NULL); + EditSetTimerMarkAll(hwnd); } return TRUE; @@ -4557,8 +4575,10 @@ INT_PTR CALLBACK EditFindReplaceDlgProcW(HWND hwnd,UINT umsg,WPARAM wParam,LPARA { if (LOWORD(wParam) == IDT_TIMER_MRKALL) { - KillTimer(hwnd, IDT_TIMER_MRKALL); - PostMessage(hwnd, WM_COMMAND, MAKELONG(IDC_MARKALL_OCC, 1), 0); + if (TEST_AND_RESET(TIMER_BIT_MARK_OCC)) { + PostMessage(hwnd, WM_COMMAND, MAKELONG(IDC_MARKALL_OCC, 1), 0); + KillTimer(hwnd, IDT_TIMER_MRKALL); + } return TRUE; } } @@ -4570,7 +4590,7 @@ INT_PTR CALLBACK EditFindReplaceDlgProcW(HWND hwnd,UINT umsg,WPARAM wParam,LPARA lpefr = (LPEDITFINDREPLACE)GetWindowLongPtr(hwnd, DWLP_USER); if (lpefr->bMarkOccurences) { bFlagsChanged = TRUE; - SetTimer(hwnd, IDT_TIMER_MRKALL, 100, NULL); + EditSetTimerMarkAll(hwnd); } else { DialogEnableWindow(hwnd, IDC_REPLACEINSEL, !(BOOL)SendMessage(g_hwndEdit, SCI_GETSELECTIONEMPTY, 0, 0)); @@ -4609,7 +4629,7 @@ INT_PTR CALLBACK EditFindReplaceDlgProcW(HWND hwnd,UINT umsg,WPARAM wParam,LPARA SendDlgItemMessage(hwnd, LOWORD(wParam), CB_SETEDITSEL, 0, MAKELPARAM(lSelEnd, lSelEnd)); } bFlagsChanged = TRUE; - SetTimer(hwnd, IDT_TIMER_MRKALL, 200, NULL); + EditSetTimerMarkAll(hwnd); } break; @@ -4642,7 +4662,7 @@ INT_PTR CALLBACK EditFindReplaceDlgProcW(HWND hwnd,UINT umsg,WPARAM wParam,LPARA InvalidateRect(GetDlgItem(hwnd, IDC_FINDTEXT), NULL, TRUE); } bFlagsChanged = TRUE; - SetTimer(hwnd, IDT_TIMER_MRKALL, 100, NULL); + EditSetTimerMarkAll(hwnd); } break; @@ -4699,7 +4719,7 @@ INT_PTR CALLBACK EditFindReplaceDlgProcW(HWND hwnd,UINT umsg,WPARAM wParam,LPARA CheckDlgButton(hwnd, IDC_FINDTRANSFORMBS, (lpefr->bTransformBS) ? BST_CHECKED : BST_UNCHECKED); } bFlagsChanged = TRUE; - SetTimer(hwnd, IDT_TIMER_MRKALL, 100, NULL); + EditSetTimerMarkAll(hwnd); break; case IDC_DOT_MATCH_ALL: @@ -4712,7 +4732,7 @@ INT_PTR CALLBACK EditFindReplaceDlgProcW(HWND hwnd,UINT umsg,WPARAM wParam,LPARA lpefr->fuFlags &= ~(SCFIND_DOT_MATCH_ALL); } bFlagsChanged = TRUE; - SetTimer(hwnd, IDT_TIMER_MRKALL, 100, NULL); + EditSetTimerMarkAll(hwnd); break; case IDC_WILDCARDSEARCH: @@ -4739,7 +4759,7 @@ INT_PTR CALLBACK EditFindReplaceDlgProcW(HWND hwnd,UINT umsg,WPARAM wParam,LPARA CheckDlgButton(hwnd, IDC_FINDTRANSFORMBS, (lpefr->bTransformBS) ? BST_CHECKED : BST_UNCHECKED); } bFlagsChanged = TRUE; - SetTimer(hwnd, IDT_TIMER_MRKALL, 100, NULL); + EditSetTimerMarkAll(hwnd); break; case IDC_FINDTRANSFORMBS: @@ -4750,22 +4770,22 @@ INT_PTR CALLBACK EditFindReplaceDlgProcW(HWND hwnd,UINT umsg,WPARAM wParam,LPARA lpefr->bTransformBS = FALSE; } bFlagsChanged = TRUE; - SetTimer(hwnd, IDT_TIMER_MRKALL, 100, NULL); + EditSetTimerMarkAll(hwnd); break; case IDC_FINDCASE: bFlagsChanged = TRUE; - SetTimer(hwnd, IDT_TIMER_MRKALL, 100, NULL); + EditSetTimerMarkAll(hwnd); break; case IDC_FINDWORD: bFlagsChanged = TRUE; - SetTimer(hwnd, IDT_TIMER_MRKALL, 100, NULL); + EditSetTimerMarkAll(hwnd); break; case IDC_FINDSTART: bFlagsChanged = TRUE; - SetTimer(hwnd, IDT_TIMER_MRKALL, 100, NULL); + EditSetTimerMarkAll(hwnd); break; @@ -4902,7 +4922,7 @@ INT_PTR CALLBACK EditFindReplaceDlgProcW(HWND hwnd,UINT umsg,WPARAM wParam,LPARA } } bFlagsChanged = TRUE; - SetTimer(hwnd, IDT_TIMER_MRKALL, 100, NULL); + EditSetTimerMarkAll(hwnd); break; @@ -4920,7 +4940,7 @@ INT_PTR CALLBACK EditFindReplaceDlgProcW(HWND hwnd,UINT umsg,WPARAM wParam,LPARA SetDlgItemTextW(hwnd, IDC_FINDTEXT, wszRepl); SetDlgItemTextW(hwnd, IDC_REPLACETEXT, wszFind); bFlagsChanged = TRUE; - SetTimer(hwnd, IDT_TIMER_MRKALL, 100, NULL); + EditSetTimerMarkAll(hwnd); } break; @@ -5579,8 +5599,8 @@ void EditMarkAll(HWND hwnd, char* pszFind, int flags, int rangeStart, int rangeE break; // not found // mark this match if not done before - if (!(SciCall_IndicatorValueAt(INDIC_NP3_MARK_OCCURANCE, end) && - SciCall_IndicatorValueAt(INDIC_NP3_MARK_OCCURANCE, start))) { + if (!SciCall_IndicatorValueAt(INDIC_NP3_MARK_OCCURANCE, start) || + !SciCall_IndicatorValueAt(INDIC_NP3_MARK_OCCURANCE, end)) { SciCall_IndicatorFillRange(iPos, (end - start)); } diff --git a/src/Notepad3.c b/src/Notepad3.c index 9610b7ee0..20f3a2b9f 100644 --- a/src/Notepad3.c +++ b/src/Notepad3.c @@ -7149,8 +7149,8 @@ int CreateIniFileEx(LPCWSTR lpszIniFile) { // void MarkAllOccurrences() { - SetTimer(g_hwndMain, IDT_TIMER_MAIN_MRKALL, 100, NULL); TEST_AND_SET(TIMER_BIT_MARK_OCC); + SetTimer(g_hwndMain, IDT_TIMER_MAIN_MRKALL, 100, NULL); } //============================================================================= @@ -7159,8 +7159,8 @@ void MarkAllOccurrences() // void UpdateVisibleUrlHotspot() { - SetTimer(g_hwndMain, IDT_TIMER_UPDATE_HOTSPOT, 100, NULL); TEST_AND_SET(TIMER_BIT_UPDATE_HYPER); + SetTimer(g_hwndMain, IDT_TIMER_UPDATE_HOTSPOT, 100, NULL); } From 02ca738ea4d7a5fff3aecdfb5848e440ad1da029 Mon Sep 17 00:00:00 2001 From: Rainer Kottenhoff Date: Fri, 5 Jan 2018 16:28:01 +0100 Subject: [PATCH 5/9] + convenience: re-introduce "max mark occurrence counter" to avoid lazy UI (set .ini section [Settings2] MarkOccurrencesMaxCount=-1 for unlimited (MAX_INT)) --- src/Edit.c | 12 ++++++------ src/Notepad3.c | 24 ++++++++++++++++-------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/Edit.c b/src/Edit.c index b489eff21..1d2718029 100644 --- a/src/Edit.c +++ b/src/Edit.c @@ -87,8 +87,9 @@ extern BOOL bAccelWordNavigation; extern BOOL bDenyVirtualSpaceAccess; extern BOOL bHyperlinkHotspot; -extern int iMarkOccurrences; -extern int iMarkOccurrencesCount; +extern int iMarkOccurrences; +extern int iMarkOccurrencesCount; +extern int iMarkOccurrencesMaxCount; extern BOOL bMarkOccurrencesMatchVisible; extern NP2ENCODING mEncoding[]; @@ -5499,7 +5500,6 @@ void EditClearAllMarks(HWND hwnd, int iRangeStart, int iRangeEnd) } SendMessage(hwnd, SCI_SETINDICATORCURRENT, INDIC_NP3_MARK_OCCURANCE, 0); SendMessage(hwnd, SCI_INDICATORCLEARRANGE, iRangeStart, iRangeEnd); - iMarkOccurrencesCount = -1; // -1 ! } @@ -5586,6 +5586,8 @@ void EditMarkAll(HWND hwnd, char* pszFind, int flags, int rangeStart, int rangeE int start = rangeStart; int end = rangeEnd; + + iMarkOccurrencesCount = 0; SendMessage(hwnd, SCI_SETINDICATORCURRENT, INDIC_NP3_MARK_OCCURANCE, 0); int iPos = -1; @@ -5593,8 +5595,6 @@ void EditMarkAll(HWND hwnd, char* pszFind, int flags, int rangeStart, int rangeE iPos = EditFindInTarget(hwnd, pszText, iFindLength, flags, &start, &end, (start == iPos)); - ++iMarkOccurrencesCount; // -1 -> 0 - if (iPos < 0) break; // not found @@ -5607,7 +5607,7 @@ void EditMarkAll(HWND hwnd, char* pszFind, int flags, int rangeStart, int rangeE start = end; end = rangeEnd; - } while (start < end); // < iMarkOccurrencesMaxCount + } while ((start < end) && (++iMarkOccurrencesCount < iMarkOccurrencesMaxCount)); } } diff --git a/src/Notepad3.c b/src/Notepad3.c index 20f3a2b9f..4b2ca5a7b 100644 --- a/src/Notepad3.c +++ b/src/Notepad3.c @@ -150,6 +150,7 @@ BOOL bShowSelectionMargin; BOOL bShowLineNumbers; int iMarkOccurrences; int iMarkOccurrencesCount; +int iMarkOccurrencesMaxCount; BOOL bMarkOccurrencesMatchVisible; BOOL bMarkOccurrencesMatchCase; BOOL bMarkOccurrencesMatchWords; @@ -1043,6 +1044,7 @@ HWND InitInstance(HINSTANCE hInstance,LPSTR pszCmdLine,int nCmdShow) if (flagStartAsTrayIcon) SetNotifyIconTitle(g_hwndMain); + iMarkOccurrencesCount = 0; UpdateToolbar(); UpdateStatusbar(); UpdateLineNumberWidth(); @@ -6228,10 +6230,9 @@ void LoadSettings() iSciFontQuality = IniSectionGetInt(pIniSection,L"SciFontQuality", FontQuality[3]); iSciFontQuality = max(min(iSciFontQuality, 3), 0); - iMarkOccurrencesCount = -1; - //iMarkOccurrencesMaxCount = IniSectionGetInt(pIniSection,L"MarkOccurrencesMaxCount",2000); - //iMarkOccurrencesMaxCount = max(min(iMarkOccurrencesMaxCount,100000),2); - + iMarkOccurrencesMaxCount = IniSectionGetInt(pIniSection,L"MarkOccurrencesMaxCount",2000); + iMarkOccurrencesMaxCount = (iMarkOccurrencesMaxCount <= 0) ? INT_MAX : iMarkOccurrencesMaxCount; + bDenyVirtualSpaceAccess = IniSectionGetBool(pIniSection, L"DenyVirtualSpaceAccess", FALSE); bUseOldStyleBraceMatching = IniSectionGetBool(pIniSection, L"UseOldStyleBraceMatching", FALSE); @@ -7270,16 +7271,23 @@ void UpdateStatusbar() StringCchCopy(tchSel, COUNTOF(tchSel), L"--"); } - if ((iMarkOccurrencesCount > 0) && !bMarkOccurrencesMatchVisible) { - StringCchPrintf(tchOcc, COUNTOF(tchOcc), L"%i", iMarkOccurrencesCount); - FormatNumberStr(tchOcc); + // Print number of occurrence marks found + if ((iMarkOccurrencesCount > 0) && !bMarkOccurrencesMatchVisible) + { + if ((iMarkOccurrencesMaxCount < 0) || (iMarkOccurrencesCount < iMarkOccurrencesMaxCount)) + { + StringCchPrintf(tchOcc, COUNTOF(tchOcc), L"%i", iMarkOccurrencesCount); + FormatNumberStr(tchOcc); + } + else { + StringCchPrintf(tchOcc, COUNTOF(tchOcc), L">= %i", iMarkOccurrencesMaxCount); + } } else { StringCchCopy(tchOcc, COUNTOF(tchOcc), L"--"); } // Print number of selected lines in statusbar - const int iLineStart = SciCall_LineFromPosition(iSelStart); const int iLineEnd = SciCall_LineFromPosition(iSelEnd); const int iStartOfLinePos = SciCall_PositionFromLine(iLineEnd); From ed470325bf759c144b758e2b47735df2056cbe79 Mon Sep 17 00:00:00 2001 From: Rainer Kottenhoff Date: Fri, 5 Jan 2018 16:37:31 +0100 Subject: [PATCH 6/9] + fix: correct counting of found matches --- src/Edit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Edit.c b/src/Edit.c index 1d2718029..de86054f8 100644 --- a/src/Edit.c +++ b/src/Edit.c @@ -5607,7 +5607,7 @@ void EditMarkAll(HWND hwnd, char* pszFind, int flags, int rangeStart, int rangeE start = end; end = rangeEnd; - } while ((start < end) && (++iMarkOccurrencesCount < iMarkOccurrencesMaxCount)); + } while ((++iMarkOccurrencesCount < iMarkOccurrencesMaxCount) && (start < end)); } } From 0f69fa5c806360ab01b3df82553e106e1a641f14 Mon Sep 17 00:00:00 2001 From: Rainer Kottenhoff Date: Sat, 6 Jan 2018 01:24:38 +0100 Subject: [PATCH 7/9] + fix: broken find/replace (regex) on groups --- src/Edit.c | 69 +++++++++++++++++++----------------------------------- 1 file changed, 24 insertions(+), 45 deletions(-) diff --git a/src/Edit.c b/src/Edit.c index de86054f8..334e94367 100644 --- a/src/Edit.c +++ b/src/Edit.c @@ -2464,18 +2464,6 @@ void EditModifyLines(HWND hwnd,LPCWSTR pwszPrefix,LPCWSTR pwszAppend) } SendMessage(hwnd,SCI_ENDUNDOACTION,0,0); - //// Fix selection - //if (iSelStart != iSelEnd && SendMessage(hwnd,SCI_GETTARGETEND,0,0) > SendMessage(hwnd,SCI_GETSELECTIONEND,0,0)) - //{ - // int iCurPos = SendMessage(hwnd,SCI_GETCURRENTPOS,0,0); - // int iAnchorPos = SendMessage(hwnd,SCI_GETANCHOR,0,0); - // if (iCurPos > iAnchorPos) - // iCurPos = SendMessage(hwnd,SCI_GETTARGETEND,0,0); - // else - // iAnchorPos = SendMessage(hwnd,SCI_GETTARGETEND,0,0); - // SendMessage(hwnd,SCI_SETSEL,(WPARAM)iAnchorPos,(LPARAM)iCurPos); - //} - // extend selection to start of first line // the above code is not required when last line has been excluded if (iSelStart != iSelEnd) @@ -4588,14 +4576,13 @@ INT_PTR CALLBACK EditFindReplaceDlgProcW(HWND hwnd,UINT umsg,WPARAM wParam,LPARA case WM_ACTIVATE: { + DialogEnableWindow(hwnd, IDC_REPLACEINSEL, !SciCall_IsSelectionEmpty()); + lpefr = (LPEDITFINDREPLACE)GetWindowLongPtr(hwnd, DWLP_USER); if (lpefr->bMarkOccurences) { bFlagsChanged = TRUE; EditSetTimerMarkAll(hwnd); } - else { - DialogEnableWindow(hwnd, IDC_REPLACEINSEL, !(BOOL)SendMessage(g_hwndEdit, SCI_GETSELECTIONEMPTY, 0, 0)); - } } return FALSE; @@ -5282,16 +5269,17 @@ BOOL EditReplace(HWND hwnd, LPCEDITFINDREPLACE lpefr) { if (!pszReplace) return FALSE; // recoding of clipboard canceled + // redo find to get group ranges filled + int start = (SciCall_IsSelectionEmpty() ? SciCall_GetCurrentPos() : SciCall_GetSelectionStart()); + int end = SciCall_GetTextLength(); + int _start = start; + + int iPos = EditFindInTarget(hwnd, lpefr->szFind, StringCchLenA(lpefr->szFind, FNDRPL_BUFFER), (int)(lpefr->fuFlags), &start, &end, FALSE); + // w/o selection, replacement string is put into current position // but this mayby not intended here - if ((BOOL)SendMessage(hwnd, SCI_GETSELECTIONEMPTY, 0, 0)) { - int start = (int)SendMessage(hwnd, SCI_GETCURRENTPOS, 0, 0); - int end = (int)SendMessage(hwnd, SCI_GETTEXTLENGTH, 0, 0); - int _start = start; - int iPos = EditFindInTarget(hwnd, lpefr->szFind, - StringCchLenA(lpefr->szFind, FNDRPL_BUFFER), - (int)(lpefr->fuFlags), &start, &end, FALSE); - if ((iPos < 0) || (_start != start) || (_start != end)) { + if (SciCall_IsSelectionEmpty()) { + if ((iPos < 0) || (_start != start) || (_start != end)) { // empty-replace was not intended LocalFree(pszReplace); if (iPos < 0) @@ -5366,7 +5354,7 @@ int EditReplaceAllInRange(HWND hwnd, LPCEDITFINDREPLACE lpefr, BOOL bShowInfo, i bShowInfo = FALSE; } - // build array of matches for later replacements + // === build array of matches for later replacements === ReplPos_t posPair = { 0, 0 }; @@ -5391,15 +5379,21 @@ int EditReplaceAllInRange(HWND hwnd, LPCEDITFINDREPLACE lpefr, BOOL bShowInfo, i if (iCount > 0) SendMessage(hwnd, SCI_BEGINUNDOACTION, 0, 0); - // iterate over findings and replace strings + // === iterate over findings and replace strings === + int offset = 0; for (ReplPos_t* pPosPair = (ReplPos_t*)utarray_front(ReplPosUTArray); pPosPair != NULL; pPosPair = (ReplPos_t*)utarray_next(ReplPosUTArray, pPosPair)) { - SciCall_SetTargetRange((pPosPair->beg + offset), (pPosPair->end + offset)); - - offset += ((int)SendMessage(hwnd, iReplaceMsg, (WPARAM)-1, (LPARAM)pszReplace) - pPosPair->end + pPosPair->beg); + // redo find to get group ranges filled + start = (pPosPair->beg + offset); + end = (pPosPair->end + offset); + iPos = EditFindInTarget(hwnd, szFind, slen, (int)(lpefr->fuFlags), &start, &end, FALSE); + if (iPos >= 0) { + SciCall_SetTargetRange(start, end); + offset += ((int)SendMessage(hwnd, iReplaceMsg, (WPARAM)-1, (LPARAM)pszReplace) - pPosPair->end + pPosPair->beg); + } } EndWaitCursor(); @@ -5457,8 +5451,8 @@ BOOL EditReplaceAllInSelection(HWND hwnd,LPCEDITFINDREPLACE lpefr,BOOL bShowInfo int token = BeginSelUndoAction(); - int start = SciCall_GetSelectionStart();; - int end = SciCall_GetSelectionEnd();; + int start = SciCall_GetSelectionStart(); + int end = SciCall_GetSelectionEnd(); int iCount = EditReplaceAllInRange(hwnd, lpefr, bShowInfo, start, end); @@ -5467,21 +5461,6 @@ BOOL EditReplaceAllInSelection(HWND hwnd,LPCEDITFINDREPLACE lpefr,BOOL bShowInfo if (iCount <= 0) return FALSE; - int iTargetEnd = (int)SendMessage(hwnd, SCI_GETTARGETEND, 0, 0); - - if (SciCall_GetSelectionEnd() < iTargetEnd) { - - int iAnchorPos = SciCall_GetAnchor(); - int iCurrentPos = SciCall_GetCurrentPos(); - - if (iAnchorPos > iCurrentPos) - iAnchorPos = iTargetEnd; - else - iCurrentPos = iTargetEnd; - - EditSelectEx(hwnd,iAnchorPos,iCurrentPos); - } - return TRUE; } From 7c3b5d87970116222ad60b351da29acc31d3a572 Mon Sep 17 00:00:00 2001 From: Rainer Kottenhoff Date: Sat, 6 Jan 2018 01:41:43 +0100 Subject: [PATCH 8/9] + performance: tuning delay parameter of "Mark Occurrences" (instantly) --- src/Notepad3.c | 44 ++++++++++++++++++++++++++++---------------- src/Notepad3.h | 4 ++-- 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/Notepad3.c b/src/Notepad3.c index 4b2ca5a7b..f055aa650 100644 --- a/src/Notepad3.c +++ b/src/Notepad3.c @@ -1172,7 +1172,7 @@ LRESULT CALLBACK MainWndProc(HWND hwnd,UINT umsg,WPARAM wParam,LPARAM lParam) case WM_SYSCOLORCHANGE: UpdateLineNumberWidth(); EditClearAllMarks(g_hwndEdit, 0, -1); - MarkAllOccurrences(); + MarkAllOccurrences(0); EditUpdateUrlHotspots(g_hwndEdit, 0, SciCall_GetTextLength(), bHyperlinkHotspot); return DefWindowProc(hwnd,umsg,wParam,lParam); @@ -1779,7 +1779,7 @@ void MsgThemeChanged(HWND hwnd,WPARAM wParam,LPARAM lParam) UpdateStatusbar(); UpdateLineNumberWidth(); EditClearAllMarks(g_hwndEdit, 0, -1); - MarkAllOccurrences(); + MarkAllOccurrences(0); EditUpdateUrlHotspots(g_hwndEdit, 0, SciCall_GetTextLength(), bHyperlinkHotspot); UNUSED(lParam); @@ -4302,27 +4302,27 @@ LRESULT MsgCommand(HWND hwnd, WPARAM wParam, LPARAM lParam) bAccelWordNavigation = (bAccelWordNavigation) ? FALSE : TRUE; // toggle EditSetAccelWordNav(g_hwndEdit,bAccelWordNavigation); EditClearAllMarks(g_hwndEdit, 0, -1); - MarkAllOccurrences(); + MarkAllOccurrences(0); break; case IDM_VIEW_MARKOCCUR_ONOFF: iMarkOccurrences = (iMarkOccurrences == 0) ? max(1, IniGetInt(L"Settings", L"MarkOccurrences", 1)) : 0; EditClearAllMarks(g_hwndEdit, 0, -1); if (iMarkOccurrences != 0) { - MarkAllOccurrences(); + MarkAllOccurrences(0); } break; case IDM_VIEW_MARKOCCUR_CASE: bMarkOccurrencesMatchCase = (bMarkOccurrencesMatchCase) ? FALSE : TRUE; EditClearAllMarks(g_hwndEdit, 0, -1); - MarkAllOccurrences(); + MarkAllOccurrences(0); break; case IDM_VIEW_MARKOCCUR_VISIBLE: bMarkOccurrencesMatchVisible = (bMarkOccurrencesMatchVisible) ? FALSE : TRUE; EditClearAllMarks(g_hwndEdit, 0, -1); - MarkAllOccurrences(); + MarkAllOccurrences(0); break; case IDM_VIEW_MARKOCCUR_WORD: @@ -4331,7 +4331,7 @@ LRESULT MsgCommand(HWND hwnd, WPARAM wParam, LPARAM lParam) bMarkOccurrencesCurrentWord = FALSE; } EditClearAllMarks(g_hwndEdit, 0, -1); - MarkAllOccurrences(); + MarkAllOccurrences(0); break; case IDM_VIEW_MARKOCCUR_CURRENT: @@ -4340,7 +4340,7 @@ LRESULT MsgCommand(HWND hwnd, WPARAM wParam, LPARAM lParam) bMarkOccurrencesMatchWords = FALSE; } EditClearAllMarks(g_hwndEdit, 0, -1); - MarkAllOccurrences(); + MarkAllOccurrences(0); break; case IDM_VIEW_FOLDING: @@ -5632,12 +5632,15 @@ LRESULT MsgNotify(HWND hwnd,WPARAM wParam,LPARAM lParam) // clear marks only, if caret/selection changed if (scn->updated & SC_UPDATE_SELECTION) { EditClearAllMarks(g_hwndEdit, 0, -1); + MarkAllOccurrences(0); + } + else { + MarkAllOccurrences(50); } - MarkAllOccurrences(); } if (bHyperlinkHotspot) { - UpdateVisibleUrlHotspot(); + UpdateVisibleUrlHotspot(100); } UpdateStatusbar(); @@ -5645,10 +5648,10 @@ LRESULT MsgNotify(HWND hwnd,WPARAM wParam,LPARAM lParam) else if (scn->updated & SC_UPDATE_V_SCROLL) { if (iMarkOccurrences) { - MarkAllOccurrences(); + MarkAllOccurrences(100); } if (bHyperlinkHotspot) { - UpdateVisibleUrlHotspot(); + UpdateVisibleUrlHotspot(100); } } break; @@ -5677,7 +5680,7 @@ LRESULT MsgNotify(HWND hwnd,WPARAM wParam,LPARAM lParam) if (iMarkOccurrences) { EditClearAllMarks(g_hwndEdit, 0, -1); - MarkAllOccurrences(); + MarkAllOccurrences(0); } UpdateStatusbar(); @@ -7148,18 +7151,27 @@ int CreateIniFileEx(LPCWSTR lpszIniFile) { // // MarkAllOccurrences() // -void MarkAllOccurrences() +void MarkAllOccurrences(int delay) { + if (delay <= 0) { + MarkAllOccurrencesTimer(); + return; + } TEST_AND_SET(TIMER_BIT_MARK_OCC); - SetTimer(g_hwndMain, IDT_TIMER_MAIN_MRKALL, 100, NULL); + SetTimer(g_hwndMain, IDT_TIMER_MAIN_MRKALL, delay, NULL); } //============================================================================= // // UpdateVisibleUrlHotspot() // -void UpdateVisibleUrlHotspot() +void UpdateVisibleUrlHotspot(int delay) { + if (delay <= 0) { + MarkAllOccurrencesTimer(); + return; + } + TEST_AND_SET(TIMER_BIT_UPDATE_HYPER); SetTimer(g_hwndMain, IDT_TIMER_UPDATE_HOTSPOT, 100, NULL); } diff --git a/src/Notepad3.h b/src/Notepad3.h index 988420655..d08b30324 100644 --- a/src/Notepad3.h +++ b/src/Notepad3.h @@ -139,12 +139,12 @@ int CreateIniFile(); int CreateIniFileEx(LPCWSTR); -void MarkAllOccurrences(); +void MarkAllOccurrences(int); void UpdateToolbar(); void UpdateStatusbar(); void UpdateLineNumberWidth(); void UpdateSettingsCmds(); -void UpdateVisibleUrlHotspot(); +void UpdateVisibleUrlHotspot(int); void UpdateUI(); From fa74aac4133545c430544412cebd5a8a98809277 Mon Sep 17 00:00:00 2001 From: Rainer Kottenhoff Date: Sat, 6 Jan 2018 02:07:03 +0100 Subject: [PATCH 9/9] + performance: remove test for set already, if indicator does not change --- src/Edit.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/Edit.c b/src/Edit.c index 334e94367..62387d3e0 100644 --- a/src/Edit.c +++ b/src/Edit.c @@ -5577,11 +5577,8 @@ void EditMarkAll(HWND hwnd, char* pszFind, int flags, int rangeStart, int rangeE if (iPos < 0) break; // not found - // mark this match if not done before - if (!SciCall_IndicatorValueAt(INDIC_NP3_MARK_OCCURANCE, start) || - !SciCall_IndicatorValueAt(INDIC_NP3_MARK_OCCURANCE, end)) { - SciCall_IndicatorFillRange(iPos, (end - start)); - } + //// mark this match if not done before + SciCall_IndicatorFillRange(iPos, (end - start)); start = end; end = rangeEnd;