Refactor: clean up TBuffer text format aspects#1840
Refactor: clean up TBuffer text format aspects#1840SlySven merged 14 commits intoMudlet:developmentfrom
Conversation
Adds support for SGR Reverse (swap foreground and background colours)
"7"/"27" for On/Off and SGR Overline "53"/"55" for On/Off
Remove unused cruft:
* (void) TTextEdit::drawFrame(QPainter&, const QRect&)
* (void) TTextEdit::updateLastLine
* const QChar cLF & cSPACE in TBuffer (as it happens they are completely
unused and redundant as the enum QChar::SpecialCharacter provides
QChar::LineFeed and QChar::Space to provide the same constants)
* (QTime) TBuffer::mTime
* (void) TConsole::echoUserWindow(const QString&)
* (QPoint) TBuffer::insert(QPoint&, const QString&, int, int, int,
int, int, int, bool, bool, bool, bool)
* (void) TConsole::printDebug(...) functionally the same as one type of
(void) TConsole::print(...) just with a different order of arguments.
Convert #define constants TCHAR_BOLD etc. into a QFLag/enum
TChar::AttributeFlags which is declared and capable of QFlag OR operations.
Refactor a number of methods that take lots of bools and ints as individual
formatting options and colour components to take single
TChar::AttributeFlags and one or two QColors instead.
Remove a large number of (int) colour value component values as member
variables in TBuffer as they are not needed.
Convert highly repetitive intermediate methods to setBold, setItalics etc.
to take a (combinations allowed) TChar::Attribute flag value instead.
Convert 2x3 int as colour components (r,g,b) in TColorTable defined in
TTrigger class to a pair of QColors.
Remove unused QString argument from:
* (void) mudlet::setLink(...)
* (void) TConsole::setLink(...)
Remove unused QColor argument from:
* (inline void) TTextEdit::drawCharacters(...)
Refactor arguments in:
*(QString) TBuffer::bufferToHtml(QPoint P1, QPoint P2,
bool allowedTimestamps, int spacePadding = 0)
to:
(QString) TBuffer::bufferToHtml(const bool showTimeStamp = false,
const int row = -1, const int endColumn = -1,
const int startColumn = 0, int spacePadding = 0)
Convert to const references some method arguments.
Add TBuffer::set[BF]gColor(...) overloads that take a QColor argument.
Add selection state methods select()/deselect()/isSelected() const methods
to TChar class to hide/separate the selection process from the formatting
effect. (TChar::Reverse tracks the ANSI SGR reverse colour attribute and
its effect is EX-ORed with the (bool) TChar::mIsSelected flag).
Add a new tempAnsiColorTrigger lua function that, unlike tempColorTrigger
uses the correct ANSIcolors in the range 0-15 - although the original also
handles the 256 colour range in the 16-255 correctly those first 16 values
are miss-mapped and it is not possible to change them without breakage.
Adds 256-color support to Editor GUI for color triggers - and allows
choosing the default (unmodified) fore or background colors to match one
(the previous did not) and also allows one of the fore or background color
to be ignored so only the other is considered. The ignored color case is
saved in the profile data and can exported but MAY not work in previous
Mudlet versions which cannot handle the value used! It is also reported as
an error to have a color trigger with both fore and background ignored in
both the lua functions and in the GUI.
Also:
Fixed a code structure issue in TLuaInterpreter::debug() which would not
work correctly if there was more than one value on the lua stack to print
out.
This will close issues Mudlet#477 and Mudlet#703.
Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
vadi2
left a comment
There was a problem hiding this comment.
Nice, the code improvements are great, let's iron out the issues.
There are bugs with text selection - it is no longer accurate. Left is this PR, right is the current code: https://streamable.com/g34ge
Copy to html got broken
Creating a new colour trigger and changing out of it loses your selection: https://streamable.com/ihlfu
| for (int i = sub_start; i < length; i++) { //FIXME <=substart+sub_end muss nachsehen, ob wirklich noch teilbereiche gebraucht werden | ||
| if (text.at(i) == '\n') { | ||
| for (int i = sub_start; i < length; ++i) { | ||
| //FIXME <=substart+sub_end muss nachsehen, ob wirklich noch teilbereiche gebraucht werden |
There was a problem hiding this comment.
Sure! It is: Have to check, if partial areas are really still needed.
src/TBuffer.cpp
Outdated
| if (mEchoText) { | ||
| c.flags |= TCHAR_ECHO; | ||
| for (int i = sub_start; i < length; ++i) { | ||
| //FIXME <=substart+sub_end muss nachsehen, ob wirklich noch teilbereiche gebraucht werden |
There was a problem hiding this comment.
Yep. Same text as above. But it wasn't in originally ..?!
There was a problem hiding this comment.
Copy-paste of boiler-plate IIRC.
There was a problem hiding this comment.
Maybe unintended - but until I know the translation may be relevant here as well.
src/TTrigger.cpp
Outdated
| mColorPatternList.push_back(nullptr); | ||
| if (textAnsiBg == scmIgnored && textAnsiFg == scmIgnored) { | ||
| setError(QStringLiteral("<b><font color='blue'>%1</font></b>") | ||
| .arg(tr("Error: in item %1, no colors to match were set - at least <i>one</i> of the foreground or background must not be <b>ignored</b>.") |
There was a problem hiding this comment.
I don't think emphasis is necessary here.
There was a problem hiding this comment.
I believe bold is used for other messages in this position in the Editor. I will convert the inner one to italics - as it is picking out the control settings' values that are a problem.
There was a problem hiding this comment.
Must not be ignored -- must be given?
There was a problem hiding this comment.
Ignored is the significant word in the reported settings "Foreground color ignored" cannot be set at the same time as "Background color ignored" - because then it is not a Color trigger (or rather it would fire on EVERYTHING)!
|
|
||
|
|
||
| dlgColorTrigger::dlgColorTrigger(QWidget* pF, TTrigger* pT, int mode) : QDialog(pF), mpTrigger(pT), mMode(mode) | ||
| dlgColorTrigger::dlgColorTrigger(QWidget* pF, TTrigger* pT, const bool isBackGround, const QString& title) |
There was a problem hiding this comment.
Window title like: Mudlet color selection
Add first line before the three options with the current title as explanation.
Start all 3 options with words like Select or Select from
There was a problem hiding this comment.
I haven't got ideas on how to improve this yet, but perhaps try reaching out to the community at https://ux.stackexchange.com @SlySven ?
There was a problem hiding this comment.
This is a short-term transient dialogue - and saying what it is doing is consistent with other dialogues in the application - so identifying that it is setting the foreground or background for a particular trigger's item in the title is the right thing, IMHO.
It splits the colour range into the three groups because it is not feasible to provide a push-button for every one of the 256 colours as well as the default (the colour used after an SGR0 and ignore (do not pay any attention to this fore/background - only consider the other one) settings.
Ideally I'd like to convert the three QGroupBox's checkboxes into Radio buttons so it is more obvious that one and only one is active at a time. I've partially achieved that by greying out the top set of buttons when that groupbox is deselected and by greying out the text in the other two when they, similarly, deselected (although the latter happens automatically anyhow).
It is useful to report the colour "names" for the first sixteen - because they can be reallocated so that they do not appear as what they are called - but the name is still what the MUD will be thinking is being displayed.
The current proposal means that:
- for the basic 16 colour triggers the actions are:
- (only for an existing one where one of the other 240 colours was used) - click on the group-box checkbox
- click to choose colour.
- for a 6x6x6 RxGxB colour:
- (unless an existing one where one of the other 216 was used) - click on the group-box checkbox
- click/slide three times to required red/green/blue value
- click on set button
- for a grey scale colour:
- (unless an existing grey scale one where one of the other 23 was used) - click on the group-box checkbox
- click/slide to required grey value
- click on set button
There was a problem hiding this comment.
It is all very logical but it is just way too complicated and I can certainly bet that's what people say of it and give up trying to figure it out. It does need to be simpler to be used without any explanation like the one above was.
There was a problem hiding this comment.
I have never seen instructions or explanations in window title. Some OS may display differently. Asking again to move this to the inside of the window
There was a problem hiding this comment.
There are others within this application - so far I have picked out:
... QFileDialog::getExistingDirectory(nullptr, "Where do you want to save the package?"...... QFileDialog::getExistingDirectory(this, tr("Where should Mudlet save log files?")...... QFileDialog::getOpenFileName(this, tr("choose sound file")...... QString fileName = QFileDialog::getOpenFileName(this, tr("Seclect Icon")...titleText = tr(R"(Exits for room: "%1" [*])").arg(pR->name);QString title = "Enter label text.";newSymbol = QInputDialog::getItem(this, tr("Enter room symbol") ...QString newWeightText = QInputDialog::getItem(this, tr("Enter room weight"), ...
What alternative should be put into the title bar for the dialogue if not something about what it is for? 😕
There was a problem hiding this comment.
Oh, apparently macOs applications do not take title bar texts - at least for the QMessageBox class:
void QMessageBox::setWindowTitle(const QString &title)
This function shadowsQWidget::setWindowTitle().
Sets the title of the message box totitle. On macOS, the window title is ignored (as required by the macOS Guidelines).This function was introduced in Qt 4.2.
src/dlgColorTrigger.cpp
Outdated
| // The ignore button means do not consider this fore or back ground (as per | ||
| // mIsBackground) for the colour trigger - only use the other one (which | ||
| // must be set) | ||
| connect(buttonBox->button(QDialogButtonBox::Ignore), SIGNAL(pressed()), this, SLOT(slot_resetColorClicked())); |
There was a problem hiding this comment.
Let's use the functor-based connectors here - QtCreator offers a right-click refactor option to update this.
There was a problem hiding this comment.
Does it now? I hadn't seen that but if it is there that makes things simpler...
Will see if I can do that...
There was a problem hiding this comment.
Ah, it is a feature added in Qt Creator 4.7.0...
... it does not handle code using QSignalMapper because Qt claims that is obsolete now that lambda functions can be used as slot methods. However I cannot quite get my head around that at present.
There was a problem hiding this comment.
That feature has been around for quite a while in Qt Creator. What do we need QSignalMapper for? I don't think that is used in this connect.
There was a problem hiding this comment.
I used it because it enables a single slot to be used for multiple signals from similar but distinguishable controls - i.e. you set up a mapping of the signal generators then the slot can tell which control sent the signal and can behave accordingly. In this situation it eliminated 15 of 16 previous slot methods that each handled a single colour selection button - combining all the signals into a larger single slot method.
There was a problem hiding this comment.
BTW I upgraded Qt Creator and somehow ended up enabling the Clang code model or something and then the code lit up like a blooming 🎄 with warnings all over the place.
The biggest cause in the code I am currently munging is because TBuffer stores:
- the text as a
QStringList(effectively aQList<QList<QChar>>) which usesintindexes (which are obviously capable of being signed even though Qt does not permit negative indexes to be used inoperator[#]orat(#)) - the attributes in a
std::deque<std::deque<TChar>>which usesstd::deque::size_typea.k.a.unsigned longfor indexes.
This means anywhere where the code has to index into both parts there are miss-matches between signed and unsigned integral types and also miss-matches between 32- and 64-bit integral types - it is a real mess for type safety...
There was a problem hiding this comment.
But the above post is way off topic here...
|
I think I need to put some tool-tips on some items. |
|
"There are bugs with text selection - it is no longer accurate. Left is this PR, right is the current code: https://streamable.com/g34ge" - humm, not sure about that but it is almost as if there is an off-by-one error in which character gets selected/deselected. I'll take a closer look. "Copy to html got broken" - it is a mistake I made in the original try and copied across - a missing close "Creating a new colour trigger and changing out of it loses your selection: https://streamable.com/ihlfu" - check that that only happens if you leave it in the (invalid, but initial default) both fore and background colour ignored state before moving away - all the other cases should leave the underlying |
Converted some `QObject::connect` calls to the new Qt5 compile time version. Removed "256" text from the renamed `./src/icons/mudlet_color_256.png` to `./src/icons/mudlet_color.png` icon. Fixed an off-by one error in HTML copying that missed the last character in the selection. Removed an unused `TTrigger*` argument from `dlgColorTrigger::setupBasicButtons(...)`. Removed an unused flag: * `(bool) TConsole::mSaveLayoutRequested Also spotted some dead code from abandoned attempt to support blinking, some reordering that a new version of Qt spotted as needed in the TBuffer and TChar constructor initialisation lists, and a operator precedence item that could be clarified with an addition pair of `(`...`)`s. A previous error in the prior PR that this one is attempting to replace had a problem in HTML generation that I reproduced here and which needed the same fix (a missing escaped `"` mark). An upgraded Qt Creator pointed out to me some initiliser list issues in `TBuffer` and `TConsole`; and some C-style casts in some font settings in the latter class. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
|
OK I think I have fixed the gross defects in this one now... 🙏 |
vadi2
left a comment
There was a problem hiding this comment.
Will do another QA round later tonight
Also a comment revision. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
|
Bugs seem gone now, but the colour selection dialog is still an issue.
|
Remove a debugging output line that is not useful now and will be spammy.
Modernise a triplet of QObject::connect(...) calls that will otherwise
clash harder when merged into development after "upgrade-to-qt5-connect"
PR has also been merged into the main branch.
NOTE: If merging this PR into development after the
"upgrade-to-qt5-connect" PR it will be necessary to resolve the referred to
merge clash so that the development branch's:
* (void) dlgTriggerEditor::slot_set_pattern_type_color(int type)
gets replaced by/split into:
* (QColor) dlgTriggerEditor::itemTypeColor(const int type)
* (void) dlgTriggerEditor::setupPatternControls(const int type,
dlgTriggerPatternEdit* pItem)
Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
It had been previously noted that there was a use of bold html tags inside a block of test that was already emboldened so that the inner ones did not have any effect. Fix a coding error when the initial use of (void) dlgColorTrigger::setupBasicButtons(bool, bool isFirstTime = false) was not called with the second defaulted argument supplied with a non-default argument to include some run-once code. Also: * add some explanation/help text to the dlgColorTrigger dialog. * revise the text explaining the formula (232 + grey scale value 0..23) used for colours from the 24 grey-scale part of the 256 colour range. * add some tool-tips to parts of the dlgColorTrigger dialog. * add a generic static method to the mudlet class to provide a consistent and re-usable "HTML" wrapper around text - which will be particularly useful for tool-tip generation. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
|
I had a review of most of those points but I was running a compilation on my portable development system and I set |
|
Okay I seem to have resolved the conflicts in |
Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
|
How about ditching the complicated 3x color chooser interface altogether and returning to the "click my color" way of designing that window? Here is an overview of all 256 xterm colors. This can surely be shrunk in size a little more, to result in a nice interface like this w3schools color picker example, which already incorporates 127 colors in a nice easy-to-use and easy-to-understand interface. Add their preview section, where you could also put the names of the selected color, so the actual chooser can shrink even more in size. Man I really need to set up my Qt fu so I can show practical example instead of mere ideas in text form. :) |
|
That sounds better, but the user still has to figure out which colour do they need to use. I think we should remove the guesswork entirely and go with a https://docs.gimp.org/en/gimp-tool-color-picker.html in complement to the above idea. |
|
My objection though still applies - that means a dialogue with over 250 buttons and that is going to be horrible to make - especially without using the, now I understand, Ideally for the 6x6x6 colour range we could have a 3D picture each colour in the right position with six buttons along each edge to allow the user to select the three needed for that range but we have to work in a 2D space (the user's screen)! I am taking a quick look at #1579 (merging in the current development branch and fixing a sneaky little code sequence error that I am now seeing with a different compiler/OS/PC combination) - to see if it would be feasible to report the Fore/Back ground colour numbers for each character on the analysed line - which would help the user get the right ones I suppose. |
|
I mean this may not be the most pretty UI but it does what it says on the |
|
This will need some reworking to accommodate subsequent changes to the code-base - even within the |
|
That colour picker is not going to be usable I think - the right hand side is based effectively on the user choosing from a 256x256x256 RxGxB colour space and the left on some "basic colours" but it is not obvious to me that we can pre-populate the latter and the former does not represent the 16 + 6x6x6 + 24 ranges that the ANSI-256 colour range covers... |
|
OK, what about #1840 (comment) ? |
This follows a suggestion from a peer in the review process. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
Conflicts resolved in: * src/Host.cpp * src/Host.h * src/TBuffer.cpp * src/TBuffer.h * src/TConsole.cpp * src/TLuaInterpreter.cpp * src/TLuaInterpreter.h * src/TTextEdit.cpp * src/TTextEdit.h * src/XMLexport.h * src/dlgTriggerEditor.cpp * src/mudlet.cpp * src/mudlet.h Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
… > 15 Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
Kebap
left a comment
There was a problem hiding this comment.
Commenting on some UI texts
| connect(pButton, SIGNAL(clicked()), mSignalMapper, SLOT(map())); | ||
| mSignalMapper->setMapping(pButton, ansiColor); | ||
| } | ||
| // TODO: Eliminate use of QSignalMapper and use a lambda function |
There was a problem hiding this comment.
TBH I haven't got a clue am rather uncertain as to how it would be done. Until I understand that it can be done / and how, I would not want go beyond leaving that particular reminder.
I do understand your desire to migrate as many of these as possible to become GitHub issues.
| <property name="text"> | ||
| <string comment="Ensure that "Default", "Ignore" and "Cancel" in this instruction are the same as used for the controls elsewhere on this dialog."><small>Choose:<ul><li>one of the three ranges below then follow the instructions to select a color from that part of the 256 colors supported</li> | ||
| <string comment="Ensure that "Default", "Ignore" and "Cancel" in this instruction are the same as used for the controls elsewhere on this dialog."><small>Choose:<ul><li>one of the basic 16 colors below</li> | ||
| <li>click the <i>more</i> button to get access to other colors in the 256-color set, then follow the instructions to select a color from that part of the 256 colors supported; if such a color is already in use then that part will already be showing</li> |
There was a problem hiding this comment.
<small>Choose one of the basic 16 colors below
or click <i>More colors</i> to select from all 256 ANSI colors.</small>- KISS
- Yes, there will be instructions, but we don't need to be instructed to follow instructions.
- If a users already did this before and selected an advanced color, they will understand their visibility.
- I feel the "Default" and "Ignore" options need more instructions, but not sure if this is the correct place at all, or only after having clicked them.
- The "Cancel" button sould be fairly self-explanatory, right?
Too long texts can be overwhelming for regular users and create lots of workload for translation as well.
There was a problem hiding this comment.
Above comment also references the next few lines which are not shown in github web preview
There was a problem hiding this comment.
-
That was why I broke all the different options down into separate lines to explain exactly what each one did - some of them {"Default", "Ignore", "Cancel" or one of the basic 16 colours} immediately take effect and close the dialogue; others require further interactions. The mechanism for the 6x6x6 RGB and the 24 Grey range might take a moment or more to understand - and that the "Set to RGB/Grayscale" are what commits a colour only after the user has dialled in the components needed.
-
See above (the auto-numbering here does not handle skipped numbers well!)
-
I didn't want to have to code for a only show this the first time approach.
-
They are both new options in this area and the ignore is new to the whole application - the tooltips do give an explanation and can provide that before they are clicked on. As it is the effect of the default one can be a bit subtle!
-
Yeah, but it could be be interpreted to mean - remove the effect of this element (foreground or background) from the overall colour trigger - in fact that action is assigned to the ignore action but as there is scope for confusion it is best to say it explicitly.
| <property name="text"> | ||
| <string comment="Ensure that "Default", "Ignore" and "Cancel" in this instruction are the same as used for the controls elsewhere on this dialog."><small>Choose:<ul><li>one of the three ranges below then follow the instructions to select a color from that part of the 256 colors supported</li> | ||
| <string comment="Ensure that "Default", "Ignore" and "Cancel" in this instruction are the same as used for the controls elsewhere on this dialog."><small>Choose:<ul><li>one of the basic 16 colors below</li> | ||
| <li>click the <i>more</i> button to get access to other colors in the 256-color set, then follow the instructions to select a color from that part of the 256 colors supported; if such a color is already in use then that part will already be showing</li> |
There was a problem hiding this comment.
-
That was why I broke all the different options down into separate lines to explain exactly what each one did - some of them {"Default", "Ignore", "Cancel" or one of the basic 16 colours} immediately take effect and close the dialogue; others require further interactions. The mechanism for the 6x6x6 RGB and the 24 Grey range might take a moment or more to understand - and that the "Set to RGB/Grayscale" are what commits a colour only after the user has dialled in the components needed.
-
See above (the auto-numbering here does not handle skipped numbers well!)
-
I didn't want to have to code for a only show this the first time approach.
-
They are both new options in this area and the ignore is new to the whole application - the tooltips do give an explanation and can provide that before they are clicked on. As it is the effect of the default one can be a bit subtle!
-
Yeah, but it could be be interpreted to mean - remove the effect of this element (foreground or background) from the overall colour trigger - in fact that action is assigned to the ignore action but as there is scope for confusion it is best to say it explicitly.
Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
Fix a spelling mistake in a comment. Co-Authored-By: SlySven <slysven@virginmedia.com>
No it doesn't - if you are using a dark theme - see #2132 ! |
|
Most people aren't, and this definitely is not the solution to it either. Aesthetically, it looks really off... |








Adds support for SGR Reverse (swap foreground and background colours)
7/27for On/Off and SGR Overline53/55for On/OffRemove unused cruft:
(void) TTextEdit::drawFrame(QPainter&, const QRect&)(void) TTextEdit::updateLastLineconst QChar cLF&cSPACEinTBuffer(as it happens they are completely unused and redundant as the enumQChar::SpecialCharacterprovidesQChar::LineFeedandQChar::Spaceto provide the same constants)(QTime) TBuffer::mTime(void) TConsole::echoUserWindow(const QString&)(QPoint) TBuffer::insert(QPoint&, const QString&, int, int, int, int, int, int, bool, bool, bool, bool)(void) TConsole::printDebug(...)functionally the same as one type of(void) TConsole::print(...)just with a different order of arguments.Convert
#defineconstantsTCHAR_BOLDetc. into aQFlag/enum TChar::AttributeFlagswhich is declared and capable ofQFlagOR operations.Refactor a number of methods that take lots of
bools andints as individual formatting options and colour components to take singleTChar::AttributeFlagsand one or twoQColorsinstead.Remove a large number of (int) colour value component values as member variables in
TBufferas they are not needed.Convert highly repetitive intermediate methods to
setBold,setItalicsetc. to take a (combinations allowed)TChar::Attributeflag value instead.Convert 2x3
intas colour components (r,g,b) inTColorTabledefined inTTriggerclass to a pair ofQColors.Remove unused
QStringargument from:(void) mudlet::setLink(...)(void) TConsole::setLink(...)Remove unused
QColorargument from:(inline void) TTextEdit::drawCharacters(...)Refactor arguments in:
(QString) TBuffer::bufferToHtml(QPoint P1, QPoint P2, bool allowedTimestamps, int spacePadding = 0)to:
(QString) TBuffer::bufferToHtml(const bool showTimeStamp = false, const int row = -1, const int endColumn = -1, const int startColumn = 0, int spacePadding = 0)Convert to
constreferences some method arguments.Add
TBuffer::set[BF]gColor(...)overloads that take aQColorargument.Add selection state methods
select()/deselect()/isSelected() constmethods toTCharclass to hide/separate the selection process from the formatting effect. (TChar::Reversetracks the ANSI SGR reverse colour attribute and its effect is EX-ORed with the(bool) TChar::mIsSelectedflag).Add a new
tempAnsiColorTriggerlua function that, unliketempColorTriggeruses the correct ANSI colors in the range 0-15 - although the original also handles the 256 colour range in the 16-255 correctly those first 16 values are miss-mapped and it is not possible to change them without breakage.Adds 256-color support to Editor GUI for color triggers - and allows choosing the default (unmodified) fore or background colors to match one (the previous did not) and also allows one of the fore or background color to be ignored so only the other is considered. The ignored color case is
saved in the profile data and can exported but MAY not work in previous Mudlet versions which cannot handle the value used! It is also reported as an error to have a color trigger with both fore and background ignored in both the lua functions and in the GUI.
Also:
Fixed a code structure issue in
TLuaInterpreter::debug()which would not work correctly if there was more than one value on the lua stack to print out.This will close issues #477 and #703. It is a replacement for PR #1633 but it does NOT try to implement blink support (I found that the original could not be merged into the current codebase cleanly and that there was an issue in the blink code that I could not fix either in the original PR or in this one - it initially seemed to work but broke when the console text was scrolled and the mechanism of why was not clear).
Signed-off-by: Stephen Lyons slysven@virginmedia.com