Можно ли обнаружить клавишу Esc с помощью функции Ask? - PullRequest
0 голосов
/ 20 ноября 2010

Хотел бы обнаружить клавишу esc для выхода из цикла forever в псевдокоде:

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

Isэто возможно?

Ответы [ 2 ]

1 голос
/ 21 ноября 2010

Простого ответа не существует, вы должны использовать собственный консольный порт для правильной обработки, вот его часть, взятая из одного из моих старых проектов:

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
    ]
]

Возможно, вы захотите изменить функции ctx-console / on-escape и ctx-console / on-enter .

1 голос
/ 21 ноября 2010

Как чистое консольное приложение, я уверен, что ответ нет .

esc используется для отмены выполнения скрипта.

Вы можете отключить использование esc ....

 system/console/break: false

.... А теперь клавиша esc ничего не делает.

Если вы переключитесь на REBOL / VIEW и будете рады использовать всплывающее окно текст запроса вместо строки ask , то выможет быть в состоянии перехватить esc , используя insert-event-func .

...