Add command line argument for plugin, a related notification and an API

1. Add a cmd argument for plugin: -pluginMessage="SPECIFIC_PLUGIN_MESSQGE" where SPECIFIC_PLUGIN_MESSQGE is a string which can contain white space. For example: -pluginMessage="arg1 arg2 arg3".
2. NPPN_CMDLINEPLUGINMSG notification: which will be triggered by -pluginMessage and plugins will get their specific message "arg1 arg2 arg3" via idFrom field:
   //scnNotification->nmhdr.code = NPPN_CMDLINEPLUGINMSG;
   //scnNotification->nmhdr.hwndFrom = hwndNpp;
   //scnNotification->nmhdr.idFrom = pluginMessage; //where pluginMessage is pointer of type wchar_t
3. Add NPPM_GETCURRENTCMDLINE API for getting the latest command line.
4. Update command line dynamically in Debug info dialog.

Fix #11576, close #11589
This commit is contained in:
Shridhar Kumar 2022-04-26 22:32:24 -04:00 committed by Don Ho
parent 67297397d4
commit 0f8d5724af
6 changed files with 103 additions and 13 deletions

View File

@ -532,6 +532,13 @@ enum Platform { PF_UNKNOWN, PF_X86, PF_X64, PF_IA64, PF_ARM64 };
// Note: in the case of calling failure ("false" is returned), you may need to change NppDarkMode::Colors structure to: // Note: in the case of calling failure ("false" is returned), you may need to change NppDarkMode::Colors structure to:
// https://github.com/notepad-plus-plus/notepad-plus-plus/blob/master/PowerEditor/src/NppDarkMode.h#L32 // https://github.com/notepad-plus-plus/notepad-plus-plus/blob/master/PowerEditor/src/NppDarkMode.h#L32
#define NPPM_GETCURRENTCMDLINE (NPPMSG + 109)
// INT NPPM_GETCURRENTCMDLINE(size_t strLen, TCHAR *commandLineStr)
// Get the Current Command Line string.
// Returns the number of TCHAR copied/to copy.
// Users should call it with commandLineStr as NULL to get the required number of TCHAR (not including the terminating nul character),
// allocate commandLineStr buffer with the return value + 1, then call it again to get the current command line string.
#define VAR_NOT_RECOGNIZED 0 #define VAR_NOT_RECOGNIZED 0
#define FULL_CURRENT_PATH 1 #define FULL_CURRENT_PATH 1
@ -722,3 +729,8 @@ enum Platform { PF_UNKNOWN, PF_X86, PF_X64, PF_IA64, PF_ARM64 };
//scnNotification->nmhdr.hwndFrom = hwndNpp; //scnNotification->nmhdr.hwndFrom = hwndNpp;
//scnNotification->nmhdr.idFrom = 0; //scnNotification->nmhdr.idFrom = 0;
#define NPPN_CMDLINEPLUGINMSG (NPPN_FIRST + 28) // To notify plugins that the new argument for plugins (via '-pluginMessage="YOUR_PLUGIN_ARGUMENT"' in command line) is available
//scnNotification->nmhdr.code = NPPN_CMDLINEPLUGINMSG;
//scnNotification->nmhdr.hwndFrom = hwndNpp;
//scnNotification->nmhdr.idFrom = pluginMessage; //where pluginMessage is pointer of type wchar_t

View File

@ -662,6 +662,12 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa
switch (pCopyData->dwData) switch (pCopyData->dwData)
{ {
case COPYDATA_FULL_CMDLINE:
{
nppParam.setCmdLineString(static_cast<wchar_t*>(pCopyData->lpData));
break;
}
case COPYDATA_PARAMS: case COPYDATA_PARAMS:
{ {
const CmdLineParamsDTO *cmdLineParam = static_cast<const CmdLineParamsDTO *>(pCopyData->lpData); // CmdLineParams object from another instance const CmdLineParamsDTO *cmdLineParam = static_cast<const CmdLineParamsDTO *>(pCopyData->lpData); // CmdLineParams object from another instance
@ -669,6 +675,15 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa
if (sizeof(CmdLineParamsDTO) == cmdLineParamsSize) // make sure the structure is the same if (sizeof(CmdLineParamsDTO) == cmdLineParamsSize) // make sure the structure is the same
{ {
nppParam.setCmdlineParam(*cmdLineParam); nppParam.setCmdlineParam(*cmdLineParam);
generic_string pluginMessage { nppParam.getCmdLineParams()._pluginMessage };
if (!pluginMessage.empty())
{
SCNotification scnN;
scnN.nmhdr.code = NPPN_CMDLINEPLUGINMSG;
scnN.nmhdr.hwndFrom = hwnd;
scnN.nmhdr.idFrom = reinterpret_cast<uptr_t>(pluginMessage.c_str());
_pluginsManager.notify(&scnN);
}
} }
else else
{ {
@ -1356,6 +1371,21 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa
return (_macro.empty()) ? static_cast<LRESULT>(MacroStatus::Idle) : static_cast<LRESULT>(MacroStatus::RecordingStopped); return (_macro.empty()) ? static_cast<LRESULT>(MacroStatus::Idle) : static_cast<LRESULT>(MacroStatus::RecordingStopped);
} }
case NPPM_GETCURRENTCMDLINE:
{
generic_string cmdLineString = nppParam.getCmdLineString();
if (lParam != 0)
{
if (cmdLineString.length() >= static_cast<size_t>(wParam))
{
return 0;
}
lstrcpy(reinterpret_cast<TCHAR*>(lParam), cmdLineString.c_str());
}
return cmdLineString.length();
}
case WM_FRSAVE_INT: case WM_FRSAVE_INT:
{ {
_macro.push_back(recordedMacroStep(static_cast<int32_t>(wParam), 0, lParam, NULL, recordedMacroStep::mtSavedSnR)); _macro.push_back(recordedMacroStep(static_cast<int32_t>(wParam), 0, lParam, NULL, recordedMacroStep::mtSavedSnR));

View File

@ -117,6 +117,7 @@ const int LANG_INDEX_TYPE7 = 8;
const int COPYDATA_PARAMS = 0; const int COPYDATA_PARAMS = 0;
const int COPYDATA_FILENAMESA = 1; const int COPYDATA_FILENAMESA = 1;
const int COPYDATA_FILENAMESW = 2; const int COPYDATA_FILENAMESW = 2;
const int COPYDATA_FULL_CMDLINE = 3;
#define PURE_LC_NONE 0 #define PURE_LC_NONE 0
#define PURE_LC_BOL 1 #define PURE_LC_BOL 1
@ -247,6 +248,7 @@ struct CmdLineParams
LangType _langType = L_EXTERNAL; LangType _langType = L_EXTERNAL;
generic_string _localizationPath; generic_string _localizationPath;
generic_string _udlName; generic_string _udlName;
generic_string _pluginMessage;
generic_string _easterEggName; generic_string _easterEggName;
unsigned char _quoteType = 0; unsigned char _quoteType = 0;
@ -281,6 +283,8 @@ struct CmdLineParamsDTO
LangType _langType = L_EXTERNAL; LangType _langType = L_EXTERNAL;
generic_string _udlName; generic_string _udlName;
wchar_t _pluginMessage[MAX_PATH];
static CmdLineParamsDTO FromCmdLineParams(const CmdLineParams& params) static CmdLineParamsDTO FromCmdLineParams(const CmdLineParams& params)
{ {
CmdLineParamsDTO dto; CmdLineParamsDTO dto;
@ -297,6 +301,7 @@ struct CmdLineParamsDTO
dto._langType = params._langType; dto._langType = params._langType;
dto._udlName = params._udlName; dto._udlName = params._udlName;
wcsncpy(dto._pluginMessage, params._pluginMessage.c_str(), MAX_PATH);
return dto; return dto;
} }
}; };
@ -1480,6 +1485,7 @@ public:
{ {
_cmdLineParams = cmdLineParams; _cmdLineParams = cmdLineParams;
} }
const CmdLineParamsDTO & getCmdLineParams() const {return _cmdLineParams;}; const CmdLineParamsDTO & getCmdLineParams() const {return _cmdLineParams;};
const generic_string& getCmdLineString() const { return _cmdLineString; } const generic_string& getCmdLineString() const { return _cmdLineString; }

View File

@ -180,8 +180,9 @@ intptr_t CALLBACK DebugInfoDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM
_debugInfoStr += TEXT("\r\n"); _debugInfoStr += TEXT("\r\n");
// Command line as specified for program launch // Command line as specified for program launch
// The _cmdLinePlaceHolder will be replaced later by refreshDebugInfo()
_debugInfoStr += TEXT("Command Line : "); _debugInfoStr += TEXT("Command Line : ");
_debugInfoStr += nppParam.getCmdLineString(); _debugInfoStr += _cmdLinePlaceHolder;
_debugInfoStr += TEXT("\r\n"); _debugInfoStr += TEXT("\r\n");
// Administrator mode // Administrator mode
@ -308,8 +309,6 @@ intptr_t CALLBACK DebugInfoDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM
_debugInfoStr += _loadedPlugins.length() == 0 ? TEXT("none") : _loadedPlugins; _debugInfoStr += _loadedPlugins.length() == 0 ? TEXT("none") : _loadedPlugins;
_debugInfoStr += TEXT("\r\n"); _debugInfoStr += TEXT("\r\n");
::SetDlgItemText(_hSelf, IDC_DEBUGINFO_EDIT, _debugInfoStr.c_str());
_copyToClipboardLink.init(_hInst, _hSelf); _copyToClipboardLink.init(_hInst, _hSelf);
_copyToClipboardLink.create(::GetDlgItem(_hSelf, IDC_DEBUGINFO_COPYLINK), IDC_DEBUGINFO_COPYLINK); _copyToClipboardLink.create(::GetDlgItem(_hSelf, IDC_DEBUGINFO_COPYLINK), IDC_DEBUGINFO_COPYLINK);
@ -381,10 +380,31 @@ void DebugInfoDlg::doDialog()
if (!isCreated()) if (!isCreated())
create(IDD_DEBUGINFOBOX); create(IDD_DEBUGINFOBOX);
// Refresh the Debug Information.
// For example, the command line parameters may have changed since this dialog was last opened during this session.
refreshDebugInfo();
// Adjust the position of AboutBox // Adjust the position of AboutBox
goToCenter(); goToCenter();
} }
void DebugInfoDlg::refreshDebugInfo()
{
generic_string debugInfoDisplay { _debugInfoStr };
size_t replacePos = debugInfoDisplay.find(_cmdLinePlaceHolder);
if (replacePos != std::string::npos)
{
debugInfoDisplay.replace(replacePos, _cmdLinePlaceHolder.length(), NppParameters::getInstance().getCmdLineString());
}
// Set Debug Info text and leave the text in selected state
::SetDlgItemText(_hSelf, IDC_DEBUGINFO_EDIT, debugInfoDisplay.c_str());
::SendDlgItemMessage(_hSelf, IDC_DEBUGINFO_EDIT, EM_SETSEL, 0, _debugInfoStr.length() - 1);
::SetFocus(::GetDlgItem(_hSelf, IDC_DEBUGINFO_EDIT));
}
void DoSaveOrNotBox::doDialog(bool isRTL) void DoSaveOrNotBox::doDialog(bool isRTL)
{ {

View File

@ -70,6 +70,8 @@ public:
void doDialog(); void doDialog();
void refreshDebugInfo();
virtual void destroy() { virtual void destroy() {
_copyToClipboardLink.destroy(); _copyToClipboardLink.destroy();
}; };
@ -80,6 +82,7 @@ protected:
private: private:
typedef const CHAR * (__cdecl * PWINEGETVERSION)(); typedef const CHAR * (__cdecl * PWINEGETVERSION)();
generic_string _debugInfoStr; generic_string _debugInfoStr;
const generic_string _cmdLinePlaceHolder { L"$COMMAND_LINE_PLACEHOLDER$" };
bool _isAdmin = false; bool _isAdmin = false;
generic_string _loadedPlugins; generic_string _loadedPlugins;
URLCtrl _copyToClipboardLink; URLCtrl _copyToClipboardLink;

View File

@ -312,6 +312,7 @@ const TCHAR FLAG_OPEN_FOLDERS_AS_WORKSPACE[] = TEXT("-openFoldersAsWorkspace");
const TCHAR FLAG_SETTINGS_DIR[] = TEXT("-settingsDir="); const TCHAR FLAG_SETTINGS_DIR[] = TEXT("-settingsDir=");
const TCHAR FLAG_TITLEBAR_ADD[] = TEXT("-titleAdd="); const TCHAR FLAG_TITLEBAR_ADD[] = TEXT("-titleAdd=");
const TCHAR FLAG_APPLY_UDL[] = TEXT("-udl="); const TCHAR FLAG_APPLY_UDL[] = TEXT("-udl=");
const TCHAR FLAG_PLUGIN_MESSAGE[] = TEXT("-pluginMessage=");
const TCHAR FLAG_MONITOR_FILES[] = TEXT("-monitor"); const TCHAR FLAG_MONITOR_FILES[] = TEXT("-monitor");
void doException(Notepad_plus_Window & notepad_plus_plus) void doException(Notepad_plus_Window & notepad_plus_plus)
@ -451,6 +452,19 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int)
cmdLineParams._easterEggName = getEasterEggNameFromParam(params, cmdLineParams._quoteType); cmdLineParams._easterEggName = getEasterEggNameFromParam(params, cmdLineParams._quoteType);
cmdLineParams._ghostTypingSpeed = getGhostTypingSpeedFromParam(params); cmdLineParams._ghostTypingSpeed = getGhostTypingSpeedFromParam(params);
generic_string pluginMessage;
if (getParamValFromString(FLAG_PLUGIN_MESSAGE, params, pluginMessage))
{
if (pluginMessage.length() >= 2)
{
if (pluginMessage.front() == '"' && pluginMessage.back() == '"')
{
pluginMessage = pluginMessage.substr(1, pluginMessage.length() - 2);
}
}
cmdLineParams._pluginMessage = pluginMessage;
}
// getNumberFromParam should be run at the end, to not consuming the other params // getNumberFromParam should be run at the end, to not consuming the other params
cmdLineParams._line2go = getNumberFromParam('n', params, isParamePresent); cmdLineParams._line2go = getNumberFromParam('n', params, isParamePresent);
cmdLineParams._column2go = getNumberFromParam('c', params, isParamePresent); cmdLineParams._column2go = getNumberFromParam('c', params, isParamePresent);
@ -599,13 +613,18 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int)
paramData.dwData = COPYDATA_PARAMS; paramData.dwData = COPYDATA_PARAMS;
paramData.lpData = &dto; paramData.lpData = &dto;
paramData.cbData = sizeof(dto); paramData.cbData = sizeof(dto);
::SendMessage(hNotepad_plus, WM_COPYDATA, reinterpret_cast<WPARAM>(hInstance), reinterpret_cast<LPARAM>(&paramData));
COPYDATASTRUCT cmdLineData;
cmdLineData.dwData = COPYDATA_FULL_CMDLINE;
cmdLineData.lpData = (void*)cmdLineString.c_str();
cmdLineData.cbData = long(cmdLineString.length() + 1) * (sizeof(TCHAR));
::SendMessage(hNotepad_plus, WM_COPYDATA, reinterpret_cast<WPARAM>(hInstance), reinterpret_cast<LPARAM>(&cmdLineData));
COPYDATASTRUCT fileNamesData; COPYDATASTRUCT fileNamesData;
fileNamesData.dwData = COPYDATA_FILENAMES; fileNamesData.dwData = COPYDATA_FILENAMES;
fileNamesData.lpData = (void *)quotFileName.c_str(); fileNamesData.lpData = (void *)quotFileName.c_str();
fileNamesData.cbData = long(quotFileName.length() + 1)*(sizeof(TCHAR)); fileNamesData.cbData = long(quotFileName.length() + 1) * (sizeof(TCHAR));
::SendMessage(hNotepad_plus, WM_COPYDATA, reinterpret_cast<WPARAM>(hInstance), reinterpret_cast<LPARAM>(&paramData));
::SendMessage(hNotepad_plus, WM_COPYDATA, reinterpret_cast<WPARAM>(hInstance), reinterpret_cast<LPARAM>(&fileNamesData)); ::SendMessage(hNotepad_plus, WM_COPYDATA, reinterpret_cast<WPARAM>(hInstance), reinterpret_cast<LPARAM>(&fileNamesData));
} }
return 0; return 0;