Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Small example please of Raw console under Windows #519

Closed
Blackisher opened this issue Mar 21, 2020 · 11 comments
Closed

Small example please of Raw console under Windows #519

Blackisher opened this issue Mar 21, 2020 · 11 comments

Comments

@Blackisher
Copy link

Having problem with examples and ConsoleReader. Is it even still possible in jline3? Maybe I should go to jline2?
as I see in jline2 but not 3.
jline2/src/main/java/jline/console/ConsoleReader.java

What I am trying to do:

  1. Java program running under windows.
  2. Print out int 8 - in new clear console.
  3. By pressing a key - lets say "K" or arrow "up" console is cleaned and new number is printed out - (previous number increased by 7).
  4. NO ENTER should be pressed - console in RAW mode.
@mattirn
Copy link
Collaborator

mattirn commented Mar 21, 2020

A way to do this in JLine3 is to create widget and bid it to the key:

 % ./build repl
Launching Groovy REPL...
groovy-repl> def plus7() {
add: }     >   def buf = _buffer().toString().toInteger() + 7
add: }     >   _buffer().clear()
add: }     >   _buffer().write(buf.toString())
add: }     >   _widget 'redraw-line'
add: }     > }
groovy-repl> widget -N _plus7 plus7
groovy-repl> keymap K _plus7 
groovy-repl> 35
groovy-repl> 

Of course you can implement the widget also in your Java program (I have not tested the code below!):

    public static class MyWidgets extends org.jline.builtins.Widgets {

        public MyWidgets(LineReader reader) {
            super(reader);
            addWidget("_plus7", this::plus7);
        }

        public boolean plus7() {
            try {
                Integer num = Integer.parseInt(buffer().toString()) + 7;
                buffer().clear();
                buffer().write(num.toString());
                callWidget(LineReader.REDRAW_LINE);
            } catch (Exception e) {
                 return false;
            }
            return true;
        }
    }

    new MyWidgets(reader);
    KeyMap<Binding> keyMap = reader.getKeyMaps().get("main");
    keyMap.bind(new Reference("_plus7"), "K");

@Blackisher
Copy link
Author

2 things are not working.

  1. It looks like I still need Enter . Guessing I am using bad "reader" ?

while (true) { reader.readLine("", "", (MaskingCallback) null, null); }

Maybe that is why getting exception when reading buffor at widget.
ConsoleReader class is not detected by IDE in this setting...

  1. While using above reader buffor is only 64 bits, not whole console. Need something around 4096chars. Is it possible ?

Project: Console.
https://github.com/Blackisher/Console

Readme.md with different Java versions and how to build/run

@mattirn
Copy link
Collaborator

mattirn commented Mar 22, 2020

My example above is for the real console the JVM is running in, you should create terminal as

       TerminalBuilder
                .builder()
                .system(true)
                .build();

Buffer 64bits size is it's initial size. Buffer size is dynamically increased when needed.

@Blackisher
Copy link
Author

Blackisher commented Mar 22, 2020

Changed system to true.

Problems:
A. buffer.toString throws exception
obraz
B. How to ran in RAW mode under windows?

Goal:
I am trying to

  • clean whole console - not just one line,
  • write what was there earlier - from the top all the lines - but slightly changed (by one char) after pressing a key
  • no Enter needed after pressing a key to rewrite console

Is it possible in jline3?

Class in github https://github.com/Blackisher/Console/blob/master/src/main/java/com/Main.java
Or here below:
`package com;

import org.jline.keymap.KeyMap;
import org.jline.reader.*;
import org.jline.terminal.Terminal;
import org.jline.terminal.TerminalBuilder;

import java.io.IOException;

public class Main {
public static void main(String[] args){
Terminal terminal = null;
try {
terminal = TerminalBuilder.builder()
.system(true)
.build();
} catch (IOException e) {
e.printStackTrace();
}
LineReader reader = LineReaderBuilder.builder()
.terminal(terminal)
.build();

    MyWidgets myWidgets = new MyWidgets(reader);
    KeyMap<Binding> keyMap = reader.getKeyMaps().get("main");
    keyMap.bind(new Reference("_plus7"), "k");

    while (true) {
        reader.readLine();
    }
}

}

class MyWidgets extends org.jline.builtins.Widgets {
private LineReader reader;

public MyWidgets(LineReader reader) {
    super(reader);
    this.reader = reader;
    addWidget("_plus7", this::plus7);
}

public boolean plus7() {
    try {
        Integer num = Integer.parseInt(buffer().toString()) + 7;
        buffer().clear();
        buffer().write(num.toString());
        callWidget(LineReader.REDRAW_LINE);
    } catch (NumberFormatException e) {
        e.printStackTrace();
    }
    return true;
}

}
`

@mattirn
Copy link
Collaborator

mattirn commented Mar 22, 2020

I think that you cannot run correctly the program from your IDE. When you launch it from your command prompt it should work.... Sure you get NumberFormatException when you do not have in your buffer number string.

Screenshot from 2020-03-22 11-10-26

About the RAW mode I do not have idea, @gnodet can you comment?

@Blackisher
Copy link
Author

I was running it in windows console - as described in README.md and in IDE
They work the same. Will continue to check both.

@mattirn I see you are using linux?
Under windows 10 it looks like that
obraz

  1. Pressed enter.
  2. Wrote "ASDFGHJK" and pressed enter
  3. Wrote "k" and pressed enter
  4. Repeated 3.
  5. Wrote "ASD" and pressed enter.

I guess:
buffer is cleaned after finishing MyWidgets.
and
buffer is not whole console. Its only line that I am writing in.

What I wanted to get:
run program
obraz
Get empty console.
And Initialize it with some String... like
obraz
When user will press specific key (lets stay with "k") console is cleaned and new string is printed out
obraz
(in this example 5 was changed to 7).

Is this possible based on jline3 library?

@gnodet
Copy link
Member

gnodet commented Mar 22, 2020

On windows, you need to add jansi or jna to the classpath in order to have a working console.

@mattirn
Copy link
Collaborator

mattirn commented Mar 22, 2020

  • Buffer is not cleaned after finishing MyWidgets it has been just modified.
  • JLine supports multiline input. Yes, you can change only the current buffer with widgets as far as I know.
  • JLine has also status bar which you can use to write command info

gnodet added a commit that referenced this issue Mar 22, 2020
#519 : do not allow dumb terminal by default on windows, unless explicitely requested
@mattirn
Copy link
Collaborator

mattirn commented Mar 22, 2020

LineReader has method printAbove() which could be useful if you just want to write above the current prompt the command info.

 % ./build repl
Launching Groovy REPL...
groovy-repl> 
groovy-repl> info='''
quote      > ABCDEFGZ
quote      > 1
quote      > 2
quote      > 3
quote      > 4
quote      > 5
quote      > 6
quote      > '''
groovy-repl> def commandinfo() {
add: }     >   _widget 'clear-screen'
add: }     >   def pp = info.split('\n')
add: }     >   pp[6] = (pp[6].toInteger() + 2).toString()
add: }     >   info = String.join('\n',pp)
add: }     >   _reader.printAbove(info)
add: }     > }
groovy-repl> widget -N _commandinfo commandinfo
groovy-repl> keymap k _commandinfo
groovy-repl> 

Screenshot from 2020-03-22 15-33-55

@mattirn
Copy link
Collaborator

mattirn commented Apr 5, 2020

Terminal in RAW mode... Flappy Bird game written in Java/JLine3, which is rendered in terminal: FlappyTerminal

@mattirn
Copy link
Collaborator

mattirn commented May 26, 2020

Close because of inactivity

# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

No branches or pull requests

3 participants