Add multi-select commands

Add "Multi-select All" & "Multi-select Next" for 4 modes to multi-select the occurrences respectively:
1. Match Case Only
2. Match Whole Word Only
3. Match Case & Whole Word
4. Ignore Case & Whole Word

Add also 2 commands "Undo the Latest Added Multi-Select" & "Skip Current && Go to Next Multi-select" for undoing latest added slection & skipping current selection and do the next one.

Users can asign the shortcuts to these 10 commands so multi-occurrence can be easily selected via shortcuts and be modified silmutanously.

This feature is inspired by: https://github.com/notepad-plus-plus/notepad-plus-plus/issues/8203#issuecomment-623712205

Fix #8203, close #14295
pull/14298/head
Don Ho 2023-10-31 04:56:08 +01:00
parent 89278e1dc7
commit cab4d40b3f
7 changed files with 97 additions and 3 deletions

View File

@ -418,6 +418,8 @@ private:
UCHAR _mainWindowStatus = 0; //For 2 views and user dialog if docked
int _activeView = MAIN_VIEW;
int _multiSelectFlag = 0; // For sktpping current Multi-select comment
//User dialog docking
void dockUserDlg();
void undockUserDlg();

View File

@ -549,6 +549,23 @@ BEGIN
MENUITEM "Change Search Engine...", IDM_EDIT_CHANGESEARCHENGINE
END
MENUITEM SEPARATOR
POPUP "Multi-select All"
BEGIN
MENUITEM "Ignore Case && Whole Word", IDM_EDIT_MULTISELECTALL
MENUITEM "Match Case Only", IDM_EDIT_MULTISELECTALLMATCHCASE
MENUITEM "Match Whole Word Only", IDM_EDIT_MULTISELECTALLWHOLEWORD
MENUITEM "Match Case && Whole Word", IDM_EDIT_MULTISELECTALLMATCHCASEWHOLEWORD
END
POPUP "Multi-select Next"
BEGIN
MENUITEM "Ignore Case && Whole Word", IDM_EDIT_MULTISELECTNEXT
MENUITEM "Match Case Only", IDM_EDIT_MULTISELECTNEXTMATCHCASE
MENUITEM "Match Whole Word Only", IDM_EDIT_MULTISELECTNEXTWHOLEWORD
MENUITEM "Match Case && Whole Word", IDM_EDIT_MULTISELECTNEXTMATCHCASEWHOLEWORD
END
MENUITEM "Undo the Latest Added Multi-Select", IDM_EDIT_MULTISELECTUNDO
MENUITEM "Skip Current && Go to Next Multi-select",IDM_EDIT_MULTISELECTSSKIP
MENUITEM SEPARATOR
MENUITEM "Column Mode...", IDM_EDIT_COLUMNMODETIP
MENUITEM "Colum&n Editor...", IDM_EDIT_COLUMNMODE
MENUITEM "Character &Panel", IDM_EDIT_CHAR_PANEL

View File

@ -2003,6 +2003,61 @@ void Notepad_plus::command(int id)
}
break;
case IDM_EDIT_MULTISELECTALL:
case IDM_EDIT_MULTISELECTALLMATCHCASE:
case IDM_EDIT_MULTISELECTALLWHOLEWORD:
case IDM_EDIT_MULTISELECTALLMATCHCASEWHOLEWORD:
{
_multiSelectFlag = id == IDM_EDIT_MULTISELECTALL ? 0 :
(id == IDM_EDIT_MULTISELECTALLMATCHCASE ? SCFIND_MATCHCASE :
(id == IDM_EDIT_MULTISELECTALLWHOLEWORD ? SCFIND_WHOLEWORD: SCFIND_MATCHCASE| SCFIND_WHOLEWORD));
_pEditView->expandWordSelection();
_pEditView->execute(SCI_TARGETWHOLEDOCUMENT);
// Firstly do a selection of the word on which the cursor is
_pEditView->execute(SCI_SETSEARCHFLAGS, _multiSelectFlag);
_pEditView->execute(SCI_MULTIPLESELECTADDEACH);
}
break;
case IDM_EDIT_MULTISELECTNEXT:
case IDM_EDIT_MULTISELECTNEXTMATCHCASE:
case IDM_EDIT_MULTISELECTNEXTWHOLEWORD:
case IDM_EDIT_MULTISELECTNEXTMATCHCASEWHOLEWORD:
{
_multiSelectFlag = id == IDM_EDIT_MULTISELECTNEXT ? 0 :
(id == IDM_EDIT_MULTISELECTNEXTMATCHCASE ? SCFIND_MATCHCASE :
(id == IDM_EDIT_MULTISELECTNEXTWHOLEWORD ? SCFIND_WHOLEWORD : SCFIND_MATCHCASE | SCFIND_WHOLEWORD));
_pEditView->execute(SCI_TARGETWHOLEDOCUMENT);
_pEditView->execute(SCI_SETSEARCHFLAGS, _multiSelectFlag);
_pEditView->execute(SCI_MULTIPLESELECTADDNEXT);
}
break;
case IDM_EDIT_MULTISELECTUNDO:
{
LRESULT n = _pEditView->execute(SCI_GETSELECTIONS);
if (n > 0)
_pEditView->execute(SCI_DROPSELECTIONN, n - 1);
}
break;
case IDM_EDIT_MULTISELECTSSKIP:
{
_pEditView->execute(SCI_TARGETWHOLEDOCUMENT);
_pEditView->execute(SCI_SETSEARCHFLAGS, _multiSelectFlag); // use the last used flag to select the next one
_pEditView->execute(SCI_MULTIPLESELECTADDNEXT);
LRESULT n = _pEditView->execute(SCI_GETSELECTIONS);
if (n > 1)
_pEditView->execute(SCI_DROPSELECTIONN, n - 2);
}
break;
case IDM_SEARCH_CUTMARKEDLINES :
cutMarkedLines();
break;

View File

@ -92,8 +92,8 @@ static const WinMenuKeyDefinition winKeyDefs[] =
{ VK_NULL, IDM_FILE_SAVESESSION, false, false, false, nullptr },
{ VK_P, IDM_FILE_PRINT, true, false, false, nullptr },
{ VK_NULL, IDM_FILE_PRINTNOW, false, false, false, nullptr },
{ VK_F4, IDM_FILE_EXIT, false, true, false, nullptr },
{ VK_T, IDM_FILE_RESTORELASTCLOSEDFILE, true, false, true, TEXT("Restore Recent Closed File")},
{ VK_F4, IDM_FILE_EXIT, false, true, false, nullptr },
// { VK_NULL, IDM_EDIT_UNDO, false, false, false, nullptr },
// { VK_NULL, IDM_EDIT_REDO, false, false, false, nullptr },
@ -177,6 +177,16 @@ static const WinMenuKeyDefinition winKeyDefs[] =
{ VK_NULL, IDM_EDIT_OPENINFOLDER, false, false, false, nullptr },
{ VK_NULL, IDM_EDIT_SEARCHONINTERNET, false, false, false, nullptr },
{ VK_NULL, IDM_EDIT_CHANGESEARCHENGINE, false, false, false, nullptr },
{ VK_NULL, IDM_EDIT_MULTISELECTALL, false, false, false, TEXT("Multi-select All: Ignore Case and Whole Word") },
{ VK_NULL, IDM_EDIT_MULTISELECTALLMATCHCASE, false, false, false, TEXT("Multi-select All: Match Case Only") },
{ VK_NULL, IDM_EDIT_MULTISELECTALLWHOLEWORD, false, false, false, TEXT("Multi-select All: Match Whole Word Only") },
{ VK_NULL, IDM_EDIT_MULTISELECTALLMATCHCASEWHOLEWORD, false, false, false, TEXT("Multi-select All: Match Case and Whole Word") },
{ VK_NULL, IDM_EDIT_MULTISELECTNEXT, false, false, false, TEXT("Multi-select Next: Ignore Case and Whole Word") },
{ VK_NULL, IDM_EDIT_MULTISELECTNEXTMATCHCASE, false, false, false, TEXT("Multi-select Next: Match Case Only") },
{ VK_NULL, IDM_EDIT_MULTISELECTNEXTWHOLEWORD, false, false, false, TEXT("Multi-select Next: Match Whole Word Only") },
{ VK_NULL, IDM_EDIT_MULTISELECTNEXTMATCHCASEWHOLEWORD, false, false, false, TEXT("Multi-select Next: Match Case and Whole Word") },
{ VK_NULL, IDM_EDIT_MULTISELECTUNDO, false, false, false, nullptr },
{ VK_NULL, IDM_EDIT_MULTISELECTSSKIP, false, false, false, nullptr },
// { VK_NULL, IDM_EDIT_COLUMNMODETIP, false, false, false, nullptr },
{ VK_C, IDM_EDIT_COLUMNMODE, false, true, false, nullptr },
{ VK_NULL, IDM_EDIT_CHAR_PANEL, false, false, false, TEXT("Toggle Character Panel") },

View File

@ -3324,7 +3324,7 @@ pair<size_t, size_t> ScintillaEditView::getWordRange()
bool ScintillaEditView::expandWordSelection()
{
pair<size_t, size_t> wordRange = getWordRange();
pair<size_t, size_t> wordRange = getWordRange();
if (wordRange.first != wordRange.second)
{
execute(SCI_SETSELECTIONSTART, wordRange.first);

View File

@ -774,6 +774,7 @@ public:
void setPositionRestoreNeeded(bool val) { _positionRestoreNeeded = val; };
void markedTextToClipboard(int indiStyle, bool doAll = false);
void removeAnyDuplicateLines();
bool expandWordSelection();
protected:
static bool _SciInit;
@ -1183,7 +1184,6 @@ protected:
};
std::pair<size_t, size_t> getWordRange();
bool expandWordSelection();
void getFoldColor(COLORREF& fgColor, COLORREF& bgColor, COLORREF& activeFgColor);
};

View File

@ -171,6 +171,16 @@
#define IDM_EDIT_COPY_ALL_NAMES (IDM_EDIT + 87)
#define IDM_EDIT_COPY_ALL_PATHS (IDM_EDIT + 88)
#define IDM_EDIT_BEGINENDSELECT_COLUMNMODE (IDM_EDIT + 89)
#define IDM_EDIT_MULTISELECTALL (IDM_EDIT + 90)
#define IDM_EDIT_MULTISELECTALLMATCHCASE (IDM_EDIT + 91)
#define IDM_EDIT_MULTISELECTALLWHOLEWORD (IDM_EDIT + 92)
#define IDM_EDIT_MULTISELECTALLMATCHCASEWHOLEWORD (IDM_EDIT + 93)
#define IDM_EDIT_MULTISELECTNEXT (IDM_EDIT + 94)
#define IDM_EDIT_MULTISELECTNEXTMATCHCASE (IDM_EDIT + 95)
#define IDM_EDIT_MULTISELECTNEXTWHOLEWORD (IDM_EDIT + 96)
#define IDM_EDIT_MULTISELECTNEXTMATCHCASEWHOLEWORD (IDM_EDIT + 97)
#define IDM_EDIT_MULTISELECTUNDO (IDM_EDIT + 98)
#define IDM_EDIT_MULTISELECTSSKIP (IDM_EDIT + 99)
#define IDM_EDIT_AUTOCOMPLETE (50000 + 0)
#define IDM_EDIT_AUTOCOMPLETE_CURRENTFILE (50000 + 1)