Mengapa kunci END tidak memiliki entri terminfo?

8

Pada sistem Debian menekan ENDtombol menghasilkan ^[[F:

$ showkey -a

Press any keys - Ctrl-D will terminate this program

^[[F     27 0033 0x1b
         91 0133 0x5b
         70 0106 0x46

Tetapi mengapa kunci kunci ini tidak dalam terminfo ?

$ infocmp -1 | grep end
kend=\EOF,

Namun demikian, ncurses berhasil mengenalinya dengan benar KEY_END. Bagaimana?

TERM adalah xterm-256color

BTW, apa motivasi di balik memiliki kenddan endbukannya adil end? (sama untuk khomedan home)

EDIT

Seperti yang dikatakan dalam komentar Johan Myréen, khomestring adalah urutan yang menekan tombol Home menghasilkan. Tetapi pada Debian menekan tombol Home menghasilkan home. Mengapa?

$ showkey -a

Press any keys - Ctrl-D will terminate this program

^[[H     27 0033 0x1b
         91 0133 0x5b
         72 0110 0x48
$ infocmp -1 | grep home
    home=\E[H,
    khome=\EOH,
Igor Liferenko
sumber
1
Perbedaan antara homedan khomeadalah bahwa khomestring adalah urutan yang menekan tombol Home menghasilkan, sedangkan homestring adalah urutan yang harus dikirim ke terminal untuk memindahkan kursor ke posisi home. Sepengetahuan saya, terminfo tidak mendefinisikan endkemampuan, hanya saja kend.
Johan Myréen
@ JohanMyréen Bisakah Anda jelaskan apa itu "posisi asal" dari kursor dengan contoh? Dan mengapa kenddidefinisikan sebagai \EOFdalam terminfo , sedangkan terminal menghasilkan \E[F? Apakah ini bug di terminfo Debian ? Dan bagaimana ncurses berhasil mendeteksinya KEY_END?
Igor Liferenko
Posisi beranda adalah sudut kiri atas layar.
Johan Myréen

Jawaban:

10

Jawaban Johan Myréen sudah dekat, tetapi tidak persis masalahnya: sebagian besar emulator terminal yang akan Anda gunakan memiliki mode normal dan aplikasi untuk kunci khusus. Deskripsi terminal ditulis untuk satu mode, yang sesuai dengan apa yang digunakan aplikasi layar penuh. Aplikasi lain (seperti shell interaktif ) biasanya tidak menginisialisasi layar untuk menggunakan mode aplikasi . Bash adalah contohnya.

Dalam mode normal , xterm dan terminal serupa mengirim escape[(CSI) ketika dalam mode aplikasi , keypad mereka mengirim escapeO(SS3). Dalam sintaks terminfo, pelarian itu adalah \E. Jadi infocmpmenunjukkan kepada Anda bahwa deskripsi menggunakan mode aplikasi. The homekemampuan dikirim ke terminal, mengatakan itu bagaimana untuk memindahkan kursor ke rumah posisi (kiri atas), dan tidak sama dengan khome(dikirim dari terminal menggunakan keyboard).

Aplikasi layar penuh (seperti yang menggunakan ncurses) dapat mengirim string kemampuan terminal untuk menginisialisasi keypad. Beberapa deskripsi terminal menempatkan terminal ke mode aplikasi, beberapa tidak.

Penggunaan kendversus endadalah konvensi penamaan: dalam terminfo oleh konvensi, nama apa pun yang dimulai dengan k mengacu pada tombol khusus (tombol fungsi, tombol kursor, tombol-tombol) untuk memperjelas bahwa ini adalah string yang harus dibaca oleh aplikasi. Misalnya, kcub1( tombol kursor mundur ) berbeda dari cub1(pindahkan kursor ke belakang satu kolom).

ncurses mengenali kunci KEY_ENDkarena aplikasi yang Anda gunakan akan memanggil keypadfungsi untuk menginisialisasi terminal menggunakan smkx(mnemonic berarti "memulai mode transmisi keyboard"). Itu mungkin / mungkin tidak benar-benar mengaktifkan mode aplikasi. Deskripsi terminal konsol Linux tidak, sedangkan xterm.

Pada prinsipnya, Anda dapat menggunakan tputuntuk mengganti mode (dan mendapatkan hasil berbeda dari showkey):

$ showkey -a

Press any keys - Ctrl-D will terminate this program

^[[H     27 0033 0x1b
         91 0133 0x5b
         72 0110 0x48
^C        3 0003 0x03
^D        4 0004 0x04
$ tput smkx
$ showkey -a

Press any keys - Ctrl-D will terminate this program

^[OH     27 0033 0x1b
         79 0117 0x4f
         72 0110 0x48

Sebagai komplikasi, kutukan hanya akan mengenali satu nama untuk sebuah string. Beberapa terminal (seperti xterm) meniru terminal perangkat keras yang lebih tua menggunakan nama yang berbeda untuk tombol pada keypad pengeditan. Dalam FAQ xterm yang tercantum di bawah, ada kemungkinan penamaan bahwa "Beranda" kunci "Sisipkan" ...

Bacaan lebih lanjut:

Thomas Dickey
sumber
Ya, saya menggunakan keypadfungsi. Tetapi dengan pertanyaan "bagaimana ncurses berhasil mendeteksinya sebagai KEY_END" maksud saya "bagaimana keypadmenerjemahkan ^[[Fke dalam kend" (mengingat bahwa keypadmenggunakan basis data terminfo untuk menafsirkan gantungan kunci). Jika saya mengerti dengan benar, ini terjadi karena showkey -aberada dalam mode kursor, sedangkan aplikasi ncurses dalam mode aplikasi.
Igor Liferenko
showkeytidak beralih di antara mode normal / aplikasi. Ini adalah program khusus Linux, membuat asumsi tentang konsol Linux, daripada menggunakan basis data terminal
Thomas Dickey
Jika showkeytidak beralih di antara mode, maka ia menggunakan beberapa status default, apa pun namanya. Intinya adalah bahwa showkeycetakan ^[[F, bukan ^[OF, yang menyebabkan kebingungan saya. (Saya hanya digunakan showkeyuntuk secara visual mewakili keychord sebenarnya yang sedang dikirim oleh terminal dengan menekan tombol keyboard, tanpa curiga bahwa mungkin ada beberapa kehalusan yang terlibat.)
Igor Liferenko
Ya, itu mode "normal" (cara biasa merujuk ini). Anda tentu saja dapat menginisialisasi terminal Anda menggunakan tput smkxdan mendapatkan hasil yang berbeda.
Thomas Dickey
Saya pikir ada bug dalam lessutilitas: itu menempatkan dirinya ke mode aplikasi, tetapi kemudian gagal untuk menginterpretasikan tombol enter keypad. Haruskah saya mengirimkan laporan bug? (Anda dapat memeriksanya dengan memulai lessdan menekan tombol enter keypad setelah mengetik /- ini akan menampilkan ESCOM, alih-alih melakukan apa yang harus dilakukan key enter.)
Igor Liferenko
5

Masalah dengan tombol Home adalah bahwa terminal fisik dan kemudian emulator terminal yang mengemulasi mereka memiliki dua mode: Mode normal dan Aplikasi, dan urutan melarikan diri berbeda tergantung pada mode terminal. Terminfo tidak dapat mengatasi hal ini dengan baik. Dalam mode normal (alias "Mode Kursor") urutan keluar kunci End adalah ESC [ F, dalam mode Aplikasi ESC O F. Googling untuk masalah ini mengungkapkan seluruh kekacauan.

Edit Dari sumber terminfo:

maka kunci kursor diasumsikan berada dalam "Mode Kursor", dan definisi kunci kursor harus sesuai dengan asumsi itu, jika tidak aplikasi mungkin gagal. Diharapkan juga bahwa aplikasi akan selalu mengirimkan string ke terminal sebelum mereka keluar. "

Johan Myréen
sumber
Bagaimana prosedur beralih ke "mode aplikasi"? Apakah ini dilakukan oleh ncurses ?
Igor Liferenko