Skip to content

Commit ce3d15d

Browse files
CFrankCFrank
authored andcommitted
implements display console on error (feature request bruderstein#76) and
separate outputs with an empty line (feature request bruderstein#68) partially.
1 parent 1402c12 commit ce3d15d

File tree

7 files changed

+132
-14
lines changed

7 files changed

+132
-14
lines changed

PythonScript/src/ConsoleDialog.cpp

Lines changed: 78 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "WcharMbcsConverter.h"
1111
#include "MenuManager.h"
1212
#include "PythonScript.h"
13+
#include "ConfigFile.h"
1314

1415

1516
namespace NppPythonScript
@@ -27,7 +28,9 @@ ConsoleDialog::ConsoleDialog() :
2728
m_currentHistory(0),
2829
m_runButtonIsRun(true),
2930
m_hContext(NULL),
30-
m_nppData{0,0,0}
31+
m_nppData{0,0,0},
32+
m_colorOutput(false),
33+
m_user_color(-1)
3134
{
3235
m_historyIter = m_history.end();
3336
}
@@ -72,6 +75,10 @@ void ConsoleDialog::initDialog(HINSTANCE hInst, NppData& nppData, ConsoleInterfa
7275
{
7376
DockingDlgInterface::init(hInst, nppData._nppHandle);
7477

78+
m_user_color = stoi(ConfigFile::getInstance()->getSetting(_T("COLORIZEOUTPUT")));
79+
m_colorOutput = m_user_color > -1;
80+
m_prompt = ConfigFile::getInstance()->getSetting(_T("ADDEXTRALINETOOUTPUT")) == _T("1") ? m_prompt.insert(0, "\n") : m_prompt;
81+
7582
//Window::init(hInst, nppData._nppHandle);
7683
createOutputWindow(nppData._nppHandle);
7784

@@ -419,9 +426,9 @@ void ConsoleDialog::runStatement()
419426
std::shared_ptr<char> charBuffer = WcharMbcsConverter::tchar2char(buffer);
420427
delete [] buffer;
421428

422-
writeText(m_prompt.size(), m_prompt.c_str());
423-
writeText(strlen(charBuffer.get()), charBuffer.get());
424-
writeText(1, "\n");
429+
writeCmdText(m_prompt.size(), m_prompt.c_str());
430+
writeCmdText(strlen(charBuffer.get()), charBuffer.get());
431+
writeCmdText(1, "\n");
425432
SetWindowText(hText, _T(""));
426433
m_console->runStatement(charBuffer.get());
427434
}
@@ -441,9 +448,13 @@ void ConsoleDialog::stopStatement()
441448
void ConsoleDialog::setPrompt(const char *prompt)
442449
{
443450
m_prompt = prompt;
444-
::SetWindowTextA(::GetDlgItem(_hSelf, IDC_PROMPT), prompt);
451+
::SetWindowTextA(::GetDlgItem(_hSelf, IDC_PROMPT), (m_prompt.rfind('\n', 0) == 0) ? m_prompt.substr(1, m_prompt.size() - 1).c_str() : m_prompt.c_str());
445452
}
446453

454+
const char * ConsoleDialog::getPrompt()
455+
{
456+
return m_prompt.c_str();
457+
}
447458

448459
void ConsoleDialog::createOutputWindow(HWND hParentWindow)
449460
{
@@ -504,6 +515,10 @@ void ConsoleDialog::createOutputWindow(HWND hParentWindow)
504515
callScintilla(SCI_STYLESETFORE, 7, RGB(255, 128, 64)); // orange
505516
callScintilla(SCI_STYLESETUNDERLINE, 7 /* = style number */, 1 /* = underline */);
506517
callScintilla(SCI_STYLESETHOTSPOT, 7, 1);
518+
519+
// 8 is colored stdout
520+
callScintilla(SCI_STYLESETSIZE, 8 /* = style number */, 8 /* = size in points */);
521+
callScintilla(SCI_STYLESETFORE, 8, m_colorOutput ? m_user_color : 0); // green
507522

508523
callScintilla(SCI_USEPOPUP, 0);
509524
callScintilla(SCI_SETLEXER, SCLEX_CONTAINER);
@@ -529,6 +544,31 @@ LRESULT ConsoleDialog::scintillaWndProc(HWND hWnd, UINT message, WPARAM wParam,
529544
return CallWindowProc(s_originalScintillaWndProc, hWnd, message, wParam, lParam);
530545
}
531546

547+
void ConsoleDialog::writeCmdText(size_t length, const char *text)
548+
{
549+
::SendMessage(m_scintilla, SCI_SETREADONLY, 0, 0);
550+
for (idx_t i = 0; i < length; ++i)
551+
{
552+
if (text[i] == '\r')
553+
{
554+
::SendMessage(m_scintilla, SCI_APPENDTEXT, i, reinterpret_cast<LPARAM>(text));
555+
text += i + 1;
556+
length -= i + 1;
557+
i = 0;
558+
}
559+
}
560+
561+
if (length > 0)
562+
{
563+
::SendMessage(m_scintilla, SCI_APPENDTEXT, length, reinterpret_cast<LPARAM>(text));
564+
}
565+
566+
::SendMessage(m_scintilla, SCI_SETREADONLY, 1, 0);
567+
568+
::SendMessage(m_scintilla, SCI_GOTOPOS, ::SendMessage(m_scintilla, SCI_GETLENGTH, 0, 0), 0);
569+
570+
}
571+
532572
void ConsoleDialog::writeText(size_t length, const char *text)
533573
{
534574
::SendMessage(m_scintilla, SCI_SETREADONLY, 0, 0);
@@ -554,6 +594,39 @@ void ConsoleDialog::writeText(size_t length, const char *text)
554594

555595
}
556596

597+
void ConsoleDialog::writeColoredText(size_t length, const char *text)
598+
{
599+
size_t docLength = (size_t)callScintilla(SCI_GETLENGTH);
600+
size_t realLength = length;
601+
callScintilla(SCI_SETREADONLY, 0);
602+
for (idx_t i = 0; i < length; ++i)
603+
{
604+
if (text[i] == '\r')
605+
{
606+
if (i)
607+
{
608+
callScintilla(SCI_APPENDTEXT, i, reinterpret_cast<LPARAM>(text));
609+
}
610+
text += i + 1;
611+
length -= i + 1;
612+
realLength--;
613+
i = 0;
614+
}
615+
}
616+
617+
if (length > 0)
618+
{
619+
callScintilla(SCI_APPENDTEXT, length, reinterpret_cast<LPARAM>(text));
620+
}
621+
622+
callScintilla(SCI_SETREADONLY, 1);
623+
callScintilla(SCI_STARTSTYLING, docLength, 0x01);
624+
callScintilla(SCI_SETSTYLING, realLength, m_colorOutput ? 8 : 0);
625+
626+
627+
callScintilla(SCI_COLOURISE, docLength, -1);
628+
callScintilla(SCI_GOTOPOS, docLength + realLength);
629+
}
557630

558631
void ConsoleDialog::writeError(size_t length, const char *text)
559632
{

PythonScript/src/ConsoleDialog.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,13 @@ class ConsoleDialog : public DockingDlgInterface
2727
void doDialog();
2828
void hide();
2929

30+
void writeCmdText(size_t length, const char *text);
3031
void writeText(size_t length, const char *text);
32+
void writeColoredText(size_t length, const char *text);
3133
void writeError(size_t length, const char *text);
3234
void clearText();
3335
void setPrompt(const char *prompt);
36+
const char * getPrompt();
3437
HWND getScintillaHwnd() { return m_scintilla; }
3538

3639
void giveInputFocus() { SetFocus(m_hInput); }
@@ -91,6 +94,8 @@ class ConsoleDialog : public DockingDlgInterface
9194
bool m_runButtonIsRun;
9295

9396
HMENU m_hContext;
97+
bool m_colorOutput;
98+
int m_user_color;
9499

95100
};
96101

PythonScript/src/NotepadPlusWrapper.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,13 +1085,13 @@ bool NotepadPlusWrapper::isSingleView()
10851085
return !IsWindowVisible(splitter_hwnd);
10861086
}
10871087

1088-
void NotepadPlusWrapper::flashWindow(UINT count, DWORD timeout)
1088+
void NotepadPlusWrapper::flashWindow(UINT count, DWORD milliseconds)
10891089
{
10901090
FLASHWINFO flashinfo;
10911091
flashinfo.cbSize = sizeof(flashinfo);
10921092
flashinfo.hwnd = m_nppHandle;
10931093
flashinfo.dwFlags = FLASHW_ALL;
1094-
flashinfo.dwTimeout = timeout;
1094+
flashinfo.dwTimeout = milliseconds;
10951095
flashinfo.uCount = count;
10961096

10971097
FlashWindowEx(&flashinfo);

PythonScript/src/NotepadPython.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ void export_notepad()
121121
.def("triggerTabbarContextMenu", &NotepadPlusWrapper::triggerTabbarContextMenu, boost::python::args("view, index2Activate"), "Activates the context menu for provided view and tab index")
122122
.def("disableAutoUpdate", &NotepadPlusWrapper::disableAutoUpdate, "Disables notepad++ auto update functionality")
123123
.def("isSingleView", &NotepadPlusWrapper::isSingleView, "True if only one view is used, False otherwise")
124-
.def("flashWindow", &NotepadPlusWrapper::flashWindow, boost::python::args("count", "timeout"), "Flashes notepad++ for the given count and timeout");
124+
.def("flashWindow", &NotepadPlusWrapper::flashWindow, boost::python::args("count", "milliseconds"), "Flashes notepad++ for the given count and timeout");
125125
boost::python::enum_<LangType>("LANGTYPE")
126126
.value("TXT", L_TEXT)
127127
.value("PHP", L_PHP)

PythonScript/src/PythonConsole.cpp

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ PythonConsole::PythonConsole(HWND hNotepad) :
2424
m_statementRunning(CreateEvent(NULL, FALSE, TRUE, NULL)),
2525
m_hNotepad(hNotepad),
2626
m_consumerStarted(false),
27+
m_runStatementExecuted(false),
2728
m_nppData(new NppData)
2829
{
2930
}
@@ -166,7 +167,7 @@ void PythonConsole::message(const char *msg)
166167
if (mp_consoleDlg)
167168
{
168169
GILRelease release;
169-
mp_consoleDlg->writeText(strlen(msg), msg);
170+
mp_consoleDlg->writeCmdText(strlen(msg), msg);
170171
}
171172
}
172173

@@ -196,13 +197,27 @@ void PythonConsole::writeText(boost::python::object text)
196197

197198
std::string textToWrite((const char *)boost::python::extract<const char *>(utf8String), _len(utf8String));
198199
GILRelease release;
199-
mp_consoleDlg->writeText(textToWrite.size(), textToWrite.c_str());
200+
if (m_runStatementExecuted)
201+
{
202+
mp_consoleDlg->writeColoredText(textToWrite.size(), textToWrite.c_str());
203+
}
204+
else
205+
{
206+
mp_consoleDlg->writeText(textToWrite.size(), textToWrite.c_str());
207+
}
200208
}
201209
else
202210
{
203211
std::string textToWrite((const char *)boost::python::extract<const char *>(text.attr("__str__")()), _len(text));
204212
GILRelease release;
205-
mp_consoleDlg->writeText(textToWrite.size(), textToWrite.c_str());
213+
if (m_runStatementExecuted)
214+
{
215+
mp_consoleDlg->writeColoredText(textToWrite.size(), textToWrite.c_str());
216+
}
217+
else
218+
{
219+
mp_consoleDlg->writeText(textToWrite.size(), textToWrite.c_str());
220+
}
206221
}
207222
}
208223
}
@@ -248,6 +263,7 @@ void PythonConsole::runStatement(const char *statement)
248263
assert(mp_consoleDlg);
249264
if (mp_consoleDlg)
250265
{
266+
m_runStatementExecuted = true;
251267
mp_consoleDlg->runEnabled(false);
252268
}
253269

@@ -272,6 +288,7 @@ void PythonConsole::queueComplete()
272288
if (mp_consoleDlg)
273289
{
274290
mp_consoleDlg->runEnabled(true);
291+
m_runStatementExecuted = false;
275292
}
276293
}
277294

@@ -302,7 +319,7 @@ void PythonConsole::consume(std::shared_ptr<std::string> statement)
302319
assert(mp_consoleDlg);
303320
if (mp_consoleDlg)
304321
{
305-
mp_consoleDlg->setPrompt(continuePrompt ? "... " : ">>> ");
322+
mp_consoleDlg->setPrompt(continuePrompt ? "... " : mp_consoleDlg->getPrompt());
306323
mp_consoleDlg->giveInputFocus();
307324
}
308325
}

PythonScript/src/PythonConsole.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ class PythonConsole : public PyProducerConsumer<std::string>, public ConsoleInte
9191
HANDLE m_statementRunning;
9292
HWND m_hNotepad;
9393
bool m_consumerStarted;
94+
bool m_runStatementExecuted;
9495

9596
NppData* m_nppData;
9697
};

PythonScript/src/PythonHandler.cpp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,18 @@ void PythonHandler::runScriptWorker(const std::shared_ptr<RunScriptArgs>& args)
288288

289289
if (args->m_isStatement)
290290
{
291-
PyRun_SimpleString(WcharMbcsConverter::tchar2char(args->m_filename.c_str()).get());
291+
if (PyRun_SimpleString(WcharMbcsConverter::tchar2char(args->m_filename.c_str()).get()) == -1)
292+
{
293+
if (ConfigFile::getInstance()->getSetting(_T("ADDEXTRALINETOOUTPUT")) == _T("1"))
294+
{
295+
mp_console->writeText(boost::python::str("\n"));
296+
}
297+
298+
if (ConfigFile::getInstance()->getSetting(_T("OPENCONSOLEONERROR")) == _T("1"))
299+
{
300+
mp_console->pythonShowDialog();
301+
}
302+
}
292303
}
293304
else
294305
{
@@ -323,7 +334,18 @@ void PythonHandler::runScriptWorker(const std::shared_ptr<RunScriptArgs>& args)
323334

324335
if (pyFile)
325336
{
326-
PyRun_SimpleFile(PyFile_AsFile(pyFile), filenameUFT8.get());
337+
if (PyRun_SimpleFile(PyFile_AsFile(pyFile), filenameUFT8.get()) == -1)
338+
{
339+
if (ConfigFile::getInstance()->getSetting(_T("ADDEXTRALINETOOUTPUT")) == _T("1"))
340+
{
341+
mp_console->writeText(boost::python::str("\n"));
342+
}
343+
344+
if (ConfigFile::getInstance()->getSetting(_T("OPENCONSOLEONERROR")) == _T("1"))
345+
{
346+
mp_console->pythonShowDialog();
347+
}
348+
}
327349
Py_DECREF(pyFile);
328350
}
329351
}

0 commit comments

Comments
 (0)