開発メモ

開発関係のメモをいろいろと。たぶん。

Rubyでcursesの実験 【キー入力編】

Rubycursesを使う実験をした時のメモ。キー入力編。

属性編はこちら。

Rubycursesの実験 【属性編】 - 開発メモ
http://seeku.hateblo.jp/entry/2013/06/28/222410

キー入力で入ってくる情報をチェック

テスト用プログラム

よくわからないことが多いので、プログラムを書いて、実際に入力される情報を確認。確認用に作ったプログラムはこんな感じ。

# encoding: utf-8
# キー入力のサンプル

require 'curses'

# ESCDELAYのエラーに対応

def set_escdelay(ms)
    Curses.ESCDELAY=ms
rescue NotImplementedError
end

# キーの情報を表示

def print_key_info(win,y,key)
    win.setpos(y,12)
    win.addstr("%s"%key.to_s)

    win.setpos(y,16)
    win.addstr("%s"%key.class)
end

# キーに対応する定数を表示

def print_key_code(win,y,key)
    s = Curses.constants.find{ |name|
        /^KEY/ =~ name && Curses.const_get(name) == key
    }

    if s
        win.setpos(y,32)
        win.addstr(s.to_s)
    end
end


# メインの処理

Curses.init_screen
Curses.raw
set_escdelay(25)

begin
    Curses.setpos(0,0)
    Curses.addstr("Press \"!\" to exit")
    Curses.refresh

    win = Curses::Window.new(Curses.lines-2,Curses.cols,2,0)
    win.scrollok(true)
    win.keypad(true)

    y = 0
    no = 0

    loop {
        win.setpos(y,0)
        win.addstr("%03d > "%no)
        win.refresh
        no += 1

        key = win.getch
        break if key == ?!

        print_key_info(win,y,key)
        print_key_code(win,y,key)

        if y < win.maxy-1
            y += 1
        else
            win.scrl(1)
        end
    }
ensure
    Curses.close_screen
end

中途半端に凝ってるけど、基本はgetchで情報を取得して、そこからわかることを画面に表示してるだけ。入力はrawモード・keypad有効の状態で確認。

実行中の画面はこんな感じ。

f:id:see_ku:20130701235936p:plain

実際に調べた結果は下記参照。それぞれ、項目の説明はこんな感じ。

  • String
    そのキーの文字コードがStringで帰ってくる。
  • Fixnum
    Fixnumでキーコード(?)が帰ってくる。
  • 27+α
    Fixnumで27が帰ってきた後、複数のStringが帰ってくる。
  • n/a
    入力できない。
  • それ以外
    それぞれのキーを表すCursesの定数。

Mac OS X

キー入力 修飾無し Shift Ctrl
a-z String String KEY_CTRL_*
0-9 String n/a n/a
記号 String n/a n/a
space String String Fixnum 0
return KEY_CTRL_J KEY_CTRL_J KEY_CTRL_J
tab KEY_CTRL_I KEY_BTAB KEY_CTRL_I
back space Fixnum 127 Fixnum 127 Fixnum 127
esc Fixnum 27 Fixnum 27 Fixnum 27
insert n/a n/a n/a
delete KEY_DC KEY_DC n/a
home n/a 27+[H n/a
end n/a 27+[F n/a
page up n/a KEY_PPAGE n/a
page down n/a KEY_NPAGE n/a
up KEY_UP KEY_UP KEY_UP
down KEY_DOWN KEY_DOWN KEY_DOWN
left KEY_LEFT KEY_LEFT 27+[5D
right KEY_RIGHT KEY_RIGHT 27+[5C
F1 KEY_F1 n/a n/a
F2 KEY_F2 n/a n/a
F3 KEY_F3 n/a n/a
F4 KEY_F4 n/a n/a
F5 KEY_F5 27+[25~ n/a
F6 KEY_F6 27+[26~ n/a
F7 KEY_F7 27+[28~ n/a
F8 KEY_F8 27+[29~ n/a
F9 KEY_F9 27+[31~ n/a
F10 KEY_F10 27+[22~ n/a
F11 KEY_F11 27+[33~ n/a
F12 KEY_F12 27+[34~ n/a

Mac OS Xで気になるところはこんな感じ。

  • returnはKEY_CTRL_J
  • Mac OS Xのdeleteは他機種のback spaceとは違う。deleteとも違う
  • insert/delete/home/end/page up/page downは当てにならない
  • F13以降は挙動がおかしい

Windows

キー入力 修飾無し Shift Ctrl
a-z String String KEY_CTRL_*
0-9 String n/a n/a
記号 String n/a n/a
space String String String
return KEY_CTRL_M KEY_CTRL_M Fixnum 529
tab KEY_CTRL_I KEY_BTAB Fixnum 482
back space KEY_CTRL_H KEY_CTRL_H Fixnum 127
esc Fixnum 27 Fixnum 27 n/a
insert KEY_IC KEY_SIC Fixnum 477
delete KEY_DC KEY_SDC Fixnum 527
home KEY_HOME KEY_SHOME Fixnum 447
end KEY_END KEY_SEND Fixnum 448
page up KEY_PPAGE KEY_SPREVIOUS Fixnum 445
page down KEY_NPAGE KEY_SNEXT Fixnum 446
up KEY_UP Fixnum 547 Fixnum 480
down KEY_DOWN KEY_MAX Fixnum 481
left KEY_LEFT KEY_SLEFT Fixnum 443
right KEY_RIGHT KEY_SRIGHT Fixnum 444
F1 KEY_F1 KEY_F13 KEY_F25
F2 KEY_F2 KEY_F14 KEY_F26
F3 KEY_F3 KEY_F15 KEY_F27
F4 KEY_F4 KEY_F16 KEY_F28
F5 KEY_F5 KEY_F17 KEY_F29
F6 KEY_F6 KEY_F18 KEY_F30
F7 KEY_F7 KEY_F19 KEY_F31
F8 KEY_F8 KEY_F20 KEY_F32
F9 KEY_F9 KEY_F21 KEY_F33
F10 KEY_F10 KEY_F22 KEY_F34
F11 KEY_F11 KEY_F23 KEY_F35
F12 KEY_F12 KEY_F24 KEY_F36

Windowsで気になるところはこんな感じ。

  • 基本的に、想像できるとおりの素直な割り当て
  • returnはKEY_CTRL_M
  • Shift+upの割り当てがおかしい?

CentOS

WindowsからPuttyで接続して確認。設定は「ESC[n~」で

キー入力 修飾無し Shift Ctrl
a-z String String KEY_CTRL_*
0-9 String n/a n/a
記号 String n/a n/a
space String String Fixnum 0
return KEY_CTRL_J KEY_CTRL_J KEY_CTRL_J
tab KEY_CTRL_I KEY_BTAB n/a
back space KEY_BACKSPACE KEY_CTRL_H KEY_BACKSPACE
esc Fixnum 27 Fixnum 27 n/a
insert KEY_IC n/a n/a
delete KEY_DC KEY_DC n/a
home 27+[1~ 27+[1~ n/a
end 27+[4~ 27+[4~ n/a
page up KEY_PPAGE n/a n/a
page down KEY_NPAGE n/a n/a
up KEY_UP 27+[A 27+[A
down KEY_DOWN 27+[B 27+[B
left KEY_LEFT 27+[D 27+[D
right KEY_RIGHT 27+[C 27+[C
F1 27+[11~ KEY_F11 27+[11~
F2 27+[12~ KEY_F12 27+[12~
F3 27+[13~ 27+[25~ 27+[13~
F4 27+[14~ 27+[26~ 27+[14~
F5 KEY_F5 27+[28~ KEY_F5
F6 KEY_F6 27+[29~ KEY_F6
F7 KEY_F7 27+[31~ KEY_F7
F8 KEY_F8 27+[32~ KEY_F8
F9 KEY_F9 27+[33~ KEY_F9
F10 KEY_F10 27+[34~ KEY_F10
F11 KEY_F11 KEY_F11 KEY_F11
F12 KEY_F12 KEY_F12 KEY_F12

CentOSで気になるところはこんな感じ。

  • returnはKEY_CTRL_J
  • home/endが当てにならない
  • F1からF4がおかしい

結論

すべての環境で安定して使えそうなのは・・・ 通常の文字で表される範囲と、上下左右ぐらい? Shiftとの同時押しすら安定してないとは。CentOSでF1からF4だけ安定しないってのも、無駄に厳しいなぁ。

すべてに共通のプログラムを書くのは大変だ。

情報元

module Curses
http://doc.ruby-lang.org/ja/2.0.0/class/Curses.html