So I've finally begun my long-overdue conversion of CommandBox from Jline2 to JLine3. So far I've got the basic terminals and reader created and it's mostly working. Here's a couple questions I've run across as I got through my code interaction with JLine.---------------------------------------------------------reader.setPrompt() looks like it became a protected method. What is the correct way to set the prompt I want? I see prompt can be passed to the all of the readLine() methods. Is that the only way to do it now?
---------------------------------------------------------I used to have a lot of this just for writing output to the screenreader.println( ... );Which I was able to get working again like so:reader.getTerminal().writer().println( ... );Is there a more appropriate way for general output (possibly with ANSI escape characters mixed in) to the console?Also, what is the difference between terminal.output() and terminal.writer()?
---------------------------------------------------------Where do I look to find the equivalent of stuff like this:reader.setHandleUserInterrupt( true );
reader.setExpandEvents( false );
reader.getCompletionHandler().setPrintSpaceAfterFullCompletion( false );
---------------------------------------------------------That's it for now. I'm sure I'll have more questions later.
--Thanks!~Brad
You received this message because you are subscribed to the Google Groups "jline-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jline-users+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--
TerminalBuilder.builder()
.system(true)
.nativeSignals(true)
.signalHandler(Terminal.SignalHandler.SIG_IGN)
.build();
The completer's task is to give back a list of candidates matching the *word* being completed.
So if your line is "coldbox cre_" and you hit tab, the completer should add a candidate with "create", not "coldbox create".
And yes, the LineReader will do its own selection among candidates. The reason is that it allows typo fixing for example, which otherwise would not be easy to implement if it had to be done by each completer..
For the various fields of the Candidate, please have a look at the javadoc:
I suppose the easiest way would be to have a facade implementation that delegates to another History implementation that can be switched
reader.setVariable(LineReader.HISTORY_FILE, "the-new-file");
.signalHandler(Terminal.SignalHandler.SIG_IGN)
Thanks for the answers. I'm still unclear on most of the items however. (Would it be best if I started separate threads of each of these?)The completer's task is to give back a list of candidates matching the *word* being completed.
So if your line is "coldbox cre_" and you hit tab, the completer should add a candidate with "create", not "coldbox create".Can you show me if this is documented somewhere? Is there a way to get the old behavior back? I'd rather not have to rewrite all my custom completor logic.
And yes, the LineReader will do its own selection among candidates. The reason is that it allows typo fixing for example, which otherwise would not be easy to implement if it had to be done by each completer..This sounds like a problem then CommandBox uses a complex custom completor that can predict what the user will type even before they begin typing the word based on the context of the command and the parameters they've typed thus far. What can we do to get this regression fixed? I need all candidates to be displayed to the user since they are all valid or I wouldn't have added them as candidates. For instance, if a user types this and hits tab:rm path=myFile.txt force=_Then they should be prompted with true/false since those are the valid options for the Boolean "force" param. What's odd is that the positional version works:rm myFile.txt _Hitting tab on the above will correctly prompt true/false to the user.
For the various fields of the Candidate, please have a look at the javadoc:Perhaps I wasn't clear on this, but I've read the java docs and they don't provide enough information. Take for instance, "Candidates which have the same key will be merged together." What does that mean? What is a key? Where is an example? What do you mean by "merged"-- like actually concatenated? Why would I want that?
I suppose the easiest way would be to have a facade implementation that delegates to another History implementation that can be switchedSo this sounds like a regression then in JLine. Shall I put in a ticket for getting the old behavior back that allows me to easily switch between histories? That was very handy.
reader.setVariable(LineReader.HISTORY_FILE, "the-new-file");So, I didn't mention this earlier, but I can't get the actual file variable to work either. I'm basically doing what you have above but I'm setting it in the builder DSL. The file just never gets created and my history is gone when I re-open the CLI. What's the best way to debug this?Also, I'm unclear on whether I actually need to be setting a history object in the read builder DSL. It appears to use the DefaultHistory anyway. is that only really needed if I have a custom history implementation?reader = createObject( "java", "org.jline.reader.LineReaderBuilder" ).builder().terminal( terminal ).variables( {LineReader.HISTORY_FILE : commandHistoryFile} ).history( DefaultHistory ).completer( jCompletor ).build();
.signalHandler(Terminal.SignalHandler.SIG_IGN)Is there a doc of what all the different handlers are, and when/why I would want to set each one?
And a new question on the LineRreaderBuilder. Is there a way to provide options as part of the builder? I have this line after I get done building:reader.unsetOpt( LineReaderOption.INSERT_TAB );Is there a way that can be done as part of the builder?
I suggest we deal with those once the main completion issue is over.
Well, one can always call ((LineReaderImpl) reader).setHistory(myHistory) whenever you want.
I just added it yesterday
Thanks for the additional answers.Regarding the completors and only handing back the last "word" in the line, how should I determine what the last word is? I'm not using JLine's parsing functionality at all. CommandBox has its own parser based on our own rules for tokenizing strings and dealing with escape characters, etc. I don't know that my definition of the last token in the line is the same as what JLine is expecting. Is it safe to say that any chunks of text that don't have spaces such as force=true should be considered one "word" and always have the whole bit added as a candidate?
I suggest we deal with those once the main completion issue is over.That's fine. I really like the new completor stuff. It's slick and a much better UI so good work on that. I like where I think some of those extra options are going so I want to make sure I take advantage of everything I can.
So, about that pasing, I actually have some questions about the parser stuff built into JLine that I haven't had a chance to look at yet. I want to make sure that JLine's parser doesn't get in the way and try to eat any escape characters or anything since I do all that on my own based on CommandBox's parsing rules Is there a way to just turn off any internal parsng entirely to make sure I always get back the strings exactly as the user typed them? From my small amount of testing, I've been seeing that JLine seems to be eating by backslashes which is messing up stuff once I try to do my own parsing on the line.
For instance:CommandBox> echo brad\woodshould echo out exactly "brad\wood" since "\w" is not a CommandBox escape sequence. AndCommandBox> echo brad\nwoodshould echo outbradwoodsince "\n" is the CommandBox escape for a new line.This parser stuff is cool and I wish it were here 4 years ago when I first started using JLine, but since I've already written all of it myself I need to just be able to turn it all off.
Well, one can always call ((LineReaderImpl) reader).setHistory(myHistory) whenever you want.But that wouldn't actually do any good since the actual path for the history file is stored in the reader and not the history object, right? Honestly, in thinking about this, are you sure that was the right decision. The file for history really seems like it should be instance data of the actual history object itself. Especially since one might swap out a custom history object that doesn't even use a file! If a reader can have 1 or more history instances, then it seems like each history instance should contain its own data regarding how it stores the history internally.
If you plan to experiment, feel free to provide a javadoc PR
What I really need is for the readLine() method to just give me exactly what the user typed and nothing else. What would it take to get that behavior back?
Does JLine apply the parsing at the time the line is read? If so, I don't think I want to go down the road of trying to warp my parser into JLine's. That would be a non-trivial rewrite of CommandBox at this point. The tokenizing and parsing of the line happens later in the flow and in a completely different part of the app than where the read line happens. CommandBox already has its own implementation of variable expansions likeCommandBox> echo ${os.version}Recursive parsing of nested commands likeCommandBox> echo `cat file.txt`and special rules on piping data into a commandCommandBox> echo myFile.txt | cat | grep foo > out.logI even have special scenarios where parsing needs to not even happen for special commands where I simply pass the input along to another source like where I allow users to run commands against their native OS's shell like so:CommandBox> !java -versionWhat I really need is for the readLine() method to just give me exactly what the user typed and nothing else. What would it take to get that behavior back?
I think you'd better implement a Parser for JLine, especially if you have already one.
Could you set up a small example maybe ?
I think you'd better implement a Parser for JLine, especially if you have already one.I think you'd have to agree that it's ironic that when I've asked for the ability for JLine to tell me when an up arrow has been pressed, you've said that's not something JLine should do and I need to implement it myself, yet in this case I just need JLine to read a line and you're pushing me to use an entire inbuilt parsing system in JLine that I don't need :)
I can look into wiring up my parser, but I'm sure both of our implementations probably follow different lines of thought based on what we needed for our different projects. The resolution in CommandBox is split up into the tokenization of the input string (turning a string into an array of "words" as you call them) and then there's the resolution of a command chain.echo text="foo" > file.txt && cat file.txt | grep foo | sed s/foo/bar/ | moreThat's a valid input to the commandbox parser. It will generate 15 tokens, which will parse into a command chain of 6 separate commands, each with their own set of arguments, some of them positional and some of them named. I'm thinking maybe I only need to worry about the first tokenization step, but as there's basically no javadocs on the parser classes, I'm just guessing as to how they are used.
echo text="foo" > file.txt && cat file.txt | grep foo | less
Could you set up a small example maybe ?Probably, but it would be in CFML. Would that be useful to you?