Hi Brad/Ortus Solutions,
After upgrading to 4.0, I am unable to use several ansi escape sequences, primarily ones that involve the cursor. I’m observing this behavior on MacOS High Sierra.
The easiest way to reproduce the problem I’m having is in the repl :
CFSCRIPT-REPL: var print=getInstance(“printBuffer”); print.line(‘hi’).text( chr( 27 ) & ‘[1A’ ).text( chr( 27 ) & ‘[99D’ ).text(’ there
‘).text(chr(27)&’[20D’).text(chr(27)&‘[K’).text(‘Hi’).toConsole()
hi
thereHi**[EMPTY STRING]**
CFSCRIPT-REPL:
I would expect the above command to print the text “hi” then insert a newline (due to “line()” function) then move the cursor up one row and to the front of the line and print " there" (overwriting “hi”), finally, move to the beginning of the line, delete the entire line and print “Hi”. The final output should be “Hi”
In Commandbox 3.9, the expected output is returned:
`
CFSCRIPT-REPL: var print=getInstance(“printBuffer”); print.line(‘hi’).text( chr( 27 ) & ‘[1A’ ).text( chr( 27 ) & ‘[99D’ ).text(’ there
‘).text(chr(27)&’[20D’).text(chr(27)&‘[K’).text(‘Hi’).toConsole()
Hi
`
Escape sequences that seem to work are the text decoration sequences. bold, underline, etc. Those are available by way of the printBuffer onMissingMethod function so it’s easier to use that instead of the actual escape sequence.
I know that a lot of ansi support was added to CommandBox 4.0 so I’m sure I’m just missing something. How can I manipulate the cursor position in commandBox 4.0?
UPDATE:
I found that if I inject the readerFactory and use getIntance(), I can then use the reader’s getTerminal().writer.print() function to print escape sequences.
This seems to work great so now my only question is, will this work in 3.x versions of commandbox as well?
Thanks,
Joel
The Jline library that powers all shell interactions was upgraded in CommandBox 4 to a new major version. The new JLine version was a major overhaul of the entire library and tons and tons of things were changed, added, removed, etc. So as far as “why does it work in CommandBox 3 but not CommandBox 4”, yeah who knows. There were thousands of changes in Jline3. Jline does a lot of internal translation of ANSI sequences now which likely doesn’t support cursor manipulation. If you think JLine should support this, then feel free to put in a ticket for the maintainer of that project here:
https://github.com/jline/jline3/issues
It might be useful to mention what it is you’re trying to do as their might be a better built-in way to accomplish what you want. Also, on that note, do not use the readerfactor manually like that as it will likely create a second instance of the JLine libs which will probably give you issues. If you want access to the ConsoleReader class from Jline, use the shell.getReader()
method from inside of CommandBox. The reason calling the terminal.writer.print() method directly works is probably because it’s bypassing the AttributedString class that is what most output in CommandBox now passes through which handles all sorts of things like automatic color rounding on terminals that support limited colors.
Re-reading through your original post now, it sounds like you’re trying to redraw lines on the screen. Check out how the progress bar and interactive jobs now work in CommandBox 4. There is a very nice API built into JLine3 that lets you redraw an array of lines to the screen over and over so you can have a curses implementation or just update progress. That may give you want you need.
Thank you, Brad! That JLine3 library is perfect for my needs. I appreciate the explanation and workaround.
–Joel
Actually, the interactiveJob component looks like will do all the work for me. Even better!