开发者

Is it possible to detect esc key with ask function?

开发者 https://www.devze.com 2023-01-26 06:14 出处:网络
Would开发者_开发问答 like to detect esc key to escape the forever loop in pseudo code: forever [

Would开发者_开发问答 like to detect esc key to escape the forever loop in pseudo code:

forever [ url: ask "Url: " if (url = esc) [ break ] ]

Is this possible ?


There is no simple answer, you must use own console-port to handle it correctly, here is the part of it taken from one of my old projects:

REBOL [title: "Console port"]

set 'ctx-console make object! [
    system/console/busy: none
    system/console/break: false
    buffer: make string! 512
    history: system/console/history
    prompt: "## " ;system/console/prompt
    spec-char: none
    port: none
    init: func[][
        port: open/binary [scheme: 'console]
        set 's-print get in system/words 'print
        set 's-prin  get in system/words 'prin
        set 'prin func[msg /err /inf /user user-data][
            ctx-console/clear-line
            s-prin reform msg
            ctx-console/print-line
        ]
        set 'print func[msg /err /inf /user user-data][
            prin rejoin [reform msg newline]
        ]
        s-prin prompt
    ]
    print-line: func[][
        s-prin rejoin [ prompt head buffer "^(1B)[" length? buffer "D"]
    ]
    clear-line: func[][
        s-prin rejoin [
            "^(1B)[" (
            (index? buffer) +
            (length? prompt) +
            (length? buffer))
            "D^(1B)[K"
        ]
    ]
    key-actions: make block! [
        #{08} [;BACK
            if 0 < length? head buffer [
                buffer: remove back buffer
                s-prin rejoin [
                    "^(back)^(1B)[K"
                    buffer
                    "^(1B)["
                    length? buffer "D"
                ]
            ]
        ]
        #{7E} [;HOME
            s-prin rejoin ["^(1B)[" (index? buffer) - 1 "D"]
            buffer: head buffer
        ]
        #{7F} [;DELETE
            buffer: remove buffer
            s-prin rejoin ["^(1B)[K" buffer "^(1B)[" length? buffer "D"]
        ]
        #{1B} [;ESCAPE
            spec-char: copy/part port 1
            either spec-char = #{1B} [
                print "ESCAPE"
                clear-line
                set 'print :s-print
                set 'prin  :s-prin
                system/console/break: true
                on-escape
            ][
                switch append spec-char copy/part port 1 [
                    #{5B41} [;ARROW UP
                        if not tail? history [
                            clear-line
                            clear head buffer
                            s-prin join prompt buffer: copy history/1
                            history: next history
                            buffer: tail buffer
                        ]
                    ]
                    #{5B42} [;ARROW DOWN
                        clear-line
                        buffer: head buffer
                        clear buffer
                        if all [
                            not error? try [history: back history]
                            not none? history/1
                        ] [
                            buffer: copy history/1
                        ]
                        s-prin join prompt buffer
                        buffer: tail buffer
                    ]
                    #{5B43} [;ARROW RIGHT
                        if not tail? buffer [
                            s-prin "^(1B)[C"
                            buffer: next buffer
                        ]
                    ]
                    #{5B44} [;ARROW LEFT
                        if 1 < index? buffer [
                            s-prin "^(1B)[D"
                            buffer: back buffer
                        ]
                    ]
                ]
            ]
        ]
    ]
    do-command: func[comm /local e][
        set/any 'e attempt compose [do (comm)]

        if all [
            not unset? 'e
            value? 'e
            not object? :e
            not port? :e
            not function? :e
        ][
            print head clear skip rejoin [system/console/result mold :e] 127
            if (length? mold :e) > 127 [
                print "...^/"
            ]
        ]
    ]
    on-enter: func[input-str /local e][
        print rejoin [system/console/prompt input-str]
        do-command input-str
    ]
    on-escape: func[][halt]
    process: func[/local ch c tmp spec-char err][
        ch: to-char pick port 1
        either (ch = newline) or (ch = #"^M") [;ENTER
            tmp: copy head buffer
            if empty? tmp [return none]
            history: head history
            if any [empty? history tmp <> first history ] [
                insert history tmp
            ]
            clear-line
            buffer: head buffer
            clear buffer
            print-line
            on-enter tmp
        ][
            switch/default to-binary ch key-actions [
                either tail? buffer [
                    s-prin ch ;either local-echo [ch]["*"]
                ][
                    s-prin rejoin ["^(1B)[@" ch]
                ]
                buffer: insert buffer ch
            ]
        ]
    ]
]
ctx-console/init

;and now do something with your own console:
wait-list: reduce [ctx-console/port]
forever [
    attempt [ready: wait/all wait-list]
    if ready [
        ctx-console/process
    ]
]

You will probably like to change the ctx-console/on-escape and ctx-console/on-enter functions.


As a pure console application, I'm pretty sure the answer is no.

esc is used to cancel the execution of the script.

You can disable that use of esc....

 system/console/break: false

....And the esc key now does nothing.

If you switch to REBOL/VIEW and are happy to use a pop up request-text box rather than a console ask line, then you may be able to trap esc using insert-event-func.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号