Mengapa Emacs tidak dapat berjalan di terminal membedakan Ctrl +; dari ";"?

8

Pertanyaan ini muncul dari pertanyaan saya sebelumnya tentang emacs beta . Singkatnya saya ingin mengikat C-;fungsi Emacs di terminal, tetapi tampaknya ada sesuatu yang menangkap kunci ini sebelum mencapai Emacs: Emacs berpikir saya menekan ;.

Tersangka yang jelas adalah emulator terminal, tetapi saya telah memeriksa banyak dari mereka (xterm, terminal-gnome, terminator, terminologi) dan tidak ada satupun yang berfungsi. Kemungkinan besar saya dapat mengecualikan window manager, karena dalam versi GUI dari Emacs, kuncinya C-;berfungsi dengan baik. Saya juga mencoba dua shell yang berbeda: bash dan zsh, tetapi sekali lagi tidak berhasil.

Apa lagi yang bisa saya coba?

WeSenseASoulInSearchOfAnswers
sumber
Menurut pertanyaan Anda tentang Emacs , menekan Ctrl +; mengirim ;ke Emacs, jadi tidak ada yang menangkapnya , yang terjadi adalah Ctrl +; dan telanjang; kirim informasi yang sama. Yang mana: capture (mis. Emacs tidak menerima apa-apa), atau kehilangan informasi (mis. Emacs menerima ;)?
Gilles 'SANGAT berhenti menjadi jahat'
tidak ada kode standar untuk C-;di terminal. Apa yang terjadi jika Anda mengetikkan C-v C-;bash polos?
artm
@Gilles saya lihat ;di emacs -nwterlepas apakah aku memukul ;atau C-;.
WeSenseASoulInSearchOfAnswers
@artm bashseperti halnya emacs hanya menampilkan telanjang ;.
WeSenseASoulInSearchOfAnswers

Jawaban:

11

Mungkin kebingungan Anda muncul karena tidak menggunakan terminal yang sebenarnya. Kembali ketika komputer serius seukuran beberapa kulkas tegak, terminal berkomunikasi dengan komputer pusat melalui kabel serial menggunakan karakter dan karakter saja. Karakter adalah bagian dari beberapa rangkaian karakter standar, misalnya ASCII atau EBCDIC, tetapi biasanya ASCII. ASCII memiliki 33 karakter kontrol dan operator terminal mengirimkannya dengan menekan tombol khusus (seperti DEL) atau dengan menahan tombol CTRL dan menekan tombol lain. Komputer pusat hanya melihat karakter kontrol yang dihasilkan; tidak tahu tombol apa yang ditekan untuk menghasilkan karakter.

Program emulasi terminal seperti xterm meniru perilaku itu. Emulator terminal menyediakan cara untuk mengirim semua 33 karakter kontrol ASCII dan Emacs akan menerima karakter tersebut jika dikirim. Tetapi Emacs seperti komputer pusat dalam deskripsi di atas --- ia tidak memiliki cara untuk mengetahui tombol apa yang sebenarnya ditekan ketika Anda menjalankannya di bawah terminal emulator. Jadi, jika Anda menekan CTRL dan titik koma, kecuali program emulasi terminal telah memetakan penekanan tombol itu ke beberapa karakter ASCII, Emacs tidak akan tahu bahwa ada sesuatu yang telah diketik.

Emulator terminal biasanya menggunakan pemetaan berikut untuk menghasilkan karakter kontrol :

penekanan tombol ASCII
--------------------
ESCAPE 27
HAPUS 127
BACKSPACE 8
CTRL + SPACE 0
CTRL + @ 0
CTRL + A 1
CTRL + B 2
CTRL + C 3
dll ...
CTRL + X 24
CTRL + Y 25
CTRL + Z 26
CTRL + [27
CTRL + \ 28
CTRL +] 29
CTRL + ^ 30
CTRL + _ 31

Perhatikan bahwa CTRL +; tidak muncul dalam daftar itu. Terminal akan biasanya hanya mengirim karakter dicetak ditugaskan untuk kunci jika CTRL + kunci tidak dipetakan ke karakter kontrol. Jadi apa yang dikatakan emulator terminal Anda dengan mengirim; sendirian adalah bahwa ia tidak tahu apa yang harus dilakukan ketika Anda menekan CTRL + ;.

Semua ini hanya berlaku jika Anda menggunakan terminal atau program emulasi terminal. Jika Anda menjalankan Emacs sebagai aplikasi asli di bawah beberapa sistem jendela, maka Emacs memiliki akses penuh ke acara keystroke dan bukan hanya karakter. Jadi Emacs dapat melihat bahwa Anda menekan CTRL dan titik koma bersamaan dan memungkinkan Anda untuk menetapkan tindakan pada pasangan keystroke itu.

Terminal sering memiliki tombol fungsi dan tombol panah yang juga menghasilkan urutan karakter yang menyertakan karakter kontrol. Urutan ini biasanya dimulai dengan kode ASCII 27 (ESCAPE).

Kyle Jones
sumber
3

Terminal mengirimkan karakter (lebih tepatnya: byte), bukan kunci. Ketika Anda menekan tombol atau kunci tombol seperti Ctrl+ ;, informasi ini harus dikodekan ke dalam urutan byte. Keychords yang mewakili karakter, seperti Aatau Shift+ Aatau À, dikirim sebagai karakter yang: a, A, à(yang terakhir menjadi satu atau dua byte tergantung pada pengkodean karakter terminal).

Gantungan kunci yang melibatkan tombol fungsi tidak memiliki karakter yang sesuai, sehingga mereka dikirim sebagai urutan escape: urutan byte yang dimulai dengan karakter escape ( \edalam string Emacs, muncul sebagai cyan ^[jika dimasukkan secara harfiah dalam buffer). Beberapa tombol fungsi memiliki byte yang sesuai yang merupakan karakter kontrol .

Keychord Ctrl+ ;tidak memiliki urutan keluar standar, sehingga sebagian besar emulator terminal menghasilkan karakter ;. Ini kehilangan informasi bahwa Ctrlpengubah ditekan.

Untuk menentukan pengikatan untuk Ctrl+ ;, Anda harus mengonfigurasi emulator terminal Anda untuk mengirim urutan escape yang berbeda. Saya tidak berpikir Anda bisa melakukan ini dengan terminal Gnome (Gnome jarang dikonfigurasi). Anda dapat melakukannya dengan Xterm. Lihat Apakah ada terminal linux yang dapat menangani semua kombinasi tombol? untuk instruksi.

Shell yang Anda jalankan di terminal tidak terlibat. GUI Emacs tidak memiliki masalah karena GUI (X11) mentransmisikan peristiwa input dalam bentuk yang menyandikan tombol dan pengubah, bukan hanya sebagai rangkaian karakter.

Lihat Bagaimana cara kerja input keyboard dan output teks? untuk latar belakang yang lebih terperinci tentang bagaimana input masuk dari keyboard Anda ke aplikasi Anda.

Gilles 'SANGAT berhenti menjadi jahat'
sumber