AVA
AVA

Reputation: 2568

How to read keyboard inputs at every keystroke in julia?

I tried with, c::Char = read(stdin, Char);

It reads character(s) from keyboard only after hitting enter but not upon every keydown/release.

Please guide me in reading keyboard input upon key press or release!

Update 1:

function quit()
print("Press q to quit!");
opt = getc1();
    while true
       if opt = 'q'
            break;
        else
            continue;
        end
    end
end

throws error:

TypeError:non-boolean(Int64) used in boolean context.

Please help me!

Upvotes: 5

Views: 1984

Answers (2)

Jeff Fessler
Jeff Fessler

Reputation: 86

The following example may be helpful:


import REPL

function wait_for_key( ;
    io_in::IO = stdin,
    io_out::IO = stdout,
    prompt::String = "press any key [d]raw [n]odraw [q]uit : ",
)

    print(io_out, prompt)

    t = REPL.TerminalMenus.terminal
    REPL.Terminals.raw!(t, true)
    char = read(io_in, Char) 
    REPL.Terminals.raw!(t, false)

    write(io_out, char)
    write(io_out, "\n")

    return char
end

Upvotes: 2

Bogumił Kamiński
Bogumił Kamiński

Reputation: 69949

This is not that simple.

You can try this more low-level solution:

function getc1()
    ret = ccall(:jl_tty_set_mode, Int32, (Ptr{Cvoid},Int32), stdin.handle, true)
    ret == 0 || error("unable to switch to raw mode")
    c = read(stdin, Char)
    ccall(:jl_tty_set_mode, Int32, (Ptr{Cvoid},Int32), stdin.handle, false)
    c
end

or this more higher level one:

function getc2()
    t = REPL.TerminalMenus.terminal
    REPL.TerminalMenus.enableRawMode(t) || error("unable to switch to raw mode")
    c = Char(REPL.TerminalMenus.readKey(t.in_stream))
    REPL.TerminalMenus.disableRawMode(t)
    c
end

depending on what you need (or write yet another implementation using the ideas here). The key challenge is that "normal keys", like ASCII are always processed correctly. However, the solutions differ in the way how they handle characters like 'ą' (some character that is larger UNICODE) or UP_ARROW (when you press arrow up on the keyboard) - you here have to experiment and decide what you want (or maybe it is enough for you to read UInt8 values one by one and manually reconstruct what you want?).

EDIT

The problem is with your quit function. Here is how it should be defined:

function quit()
    print("Press q to quit!");
    while true
        opt = getc1();
        if opt == 'q'
            break
        else
            continue
        end
    end
end

Upvotes: 10

Related Questions