Anda tidak dapat benar-benar mengubah C-[pengikatan di peta tingkat pengguna, seperti yang akan Anda lakukan global-set-key
. Namun, Anda dapat mengubahnya sebagai acara keyboard sebelum mencapai keymaps tersebut. Anda bisa mengatakan misalnya:
(define-key input-decode-map
(kbd "C-[")
[control-bracketleft])
dan kemudian gunakan [control-bracketleft]
diymap Anda. Cukup sederhana bukan?
Potongan direktor
Sayangnya, itu tidak sesederhana itu, dan solusi ini membutuhkan beberapa penyesuaian, yang akan tampak sangat menyakitkan. Anda sudah diperingatkan. Tapi mari kita lihat dulu mengapa peta tingkat pengguna tidak bisa menjawab pertanyaan. Berikut ini, saya merujuk pada manual Emacs Lisp untuk emacs 26.1 ketika saya mengatakan "melihat sesuatu" tanpa lebih presisi.
C-[ditafsirkan pada tahap sangat awal sebagai karakter kontrol ASCII ESC
(lihat 21.7.1 - Acara Keyboard ). Kode ini tersebar di semua tempat sebagai awalan untuk urutan yang lebih lama. Ada alasan untuk itu: ESC
sebenarnya adalah awalan meta (lihat meta-prefix-char
), dan semua binding yang membaca
M-sesuatu akan diterjemahkan ke urutan yang dimulai dengan ESC
. Dengan demikian, mengubah peta global tidak akan cukup: pertama-tama Anda perlu mengubah meta-prefix-char
, kemudian untuk memetakan kembali ESC
ke yang baru meta-prefix-char
di setiap peta yang digunakan M-sebelum Anda dapat memetakan dengan aman C-[.
Baiklah kalau begitu, tentu saja: mari kita gunakan input-decode-map
. Ada beberapa peta serupa yang mungkin kita tergoda untuk menggunakan (lihat bagian 21.8.3 dan 22.14), tetapi mari kita tetap pada yang ini. Dan yah ... ini berhasil! Anda sudah selesai, bukan?
Sebenarnya, tidak, ceritanya tidak berakhir di sini. Ini berfungsi ... selama Anda menggunakan sistem jendela. Jika karena nasib buruk Anda dipenjara di konsol linux dalam keadaan darurat, Anda menyadari betapa dramatisnya situasinya: tombol panah Home, dan tentu saja M-binding, semuanya sampah. Mengapa? Karena ketika terminal mengatakan ESC
(yang dilakukannya ketika Anda mengetik C-[), itu benar-benar berarti ESC
, dan memulai urutan dari jenis yang sama yang digunakannya untuk mengirimkan karakter non-ASCII.
Mengamati bencana, Anda mungkin menganggap bijaksana untuk melindungi input-decode-map
modifikasi di atas sedemikian rupa sehingga hanya diaktifkan jika sistem jendela mengendalikan keyboard:
(let ((frame (framep (selected-frame))))
(or (eq t frame)
(eq 'pc frame)
(define-key input-decode-map
(kbd "C-[")
[control-bracketleft])
)))
Terminal kemudian berfungsi seperti biasanya.
Sekarang, bisakah kita berurusan dengan C-[terminal? Sebenarnya, ya kita bisa, pada konsol linux dan juga pada emulator terminal lain yang bisa saya mainkan. Tapi itu membuat ceritanya cukup panjang, ketika karakter baru memasuki adegan. Karena tidak ada lagi emacs saja: terminal sekarang memiliki peran sentral.
Mari kita dengarkan apa yang dikatakan oleh konsol linux. Ketik C-vsebelum beberapa tombol untuk mendengarnya dengan jelas. C-[adalah ESC
; begitu juga Esc. Panah suara seperti ESC [ A
, sementara M-aini
ESC A
. Hmm ... Sepertinya ini keliling kunci meta di emacs bukan? Bagaimanapun.
Kecuali kita siap untuk memainkan beberapa trik berdasarkan waktu berlalu antara peristiwa karakter (yang dengan cara tidak akan membedakan
Escdari C-[), tampaknya kita tidak punya pilihan selain untuk memberitahu konsol apa yang sebenarnya kita tidak berarti ESC
saat kita mengetik C-[. Selain itu, tampaknya segera bahwa C-[itu bukan satu-satunya masalah dengan kode terminal stok: pengubah sebagian besar waktu menghapus informasi yang dikirimkan. Kita perlu menyesuaikan terminal untuk alasan yang sama seperti kita menyesuaikan emacs: akan jauh lebih praktis jika kita lakukan.
Pada titik ini, Anda harus berani melihat ke dalam mata dokumentasi terminal Anda: halaman loadkeys(1)
manual untuk konsol linux, untuk xterm
xterm(1)
di bagian Custom Key Bindings , dan apa pun-i-tidak-tahu untuk terminal lain. Di KDE konsole
, Anda dapat menentukan terjemahan khusus di Pengaturan / Edit Profil Saat Ini ...
lalu Keyboard . Berikut adalah kutipan dari ~/.local/share/konsole/Test.keytab
setelah bermain dengan dialog yang terakhir ini:
key [+Ctrl+AnyModifier : "\EO*["
Setelah Anda memiliki send terminal ESC O 5 [
untuk
C-[(seperti dalam konfigurasi di atas), Anda dapat kembali ke emacs. Tentu saja, Anda belum selesai.
Untuk menginstruksikan emacs dialek apa yang digunakan terminal tertentu, Anda dapat menyesuaikan input-decode-map
. Ya, ini kebetulan yang telah kami modifikasi di awal cerita ini, dan ini adalah yang paling
term/xterm.el
menyentuh ketika xterm terlibat. Tempat yang baik untuk penyesuaian adalah tty-setup-hook
(lihat bagian 40.1.3):
(add-hook 'tty-setup-hook
(lambda ()
(let ((term (getenv "TERM")))
(cond
(;; xterm-function-map not in doc, but in term/xterm.el
(boundp 'xterm-function-map)
(map-my-term-codes xterm-function-map))
((equal term "linux")
(map-my-term-codes input-decode-map))
)
)))
Ketahuilah bahwa kait ini hanya berfungsi jika Anda berada di terminal. Dengan demikian, Anda tidak dapat memasukkan kode inisialisasi sistem jendela di sini. Inilah fungsi terjemahannya sendiri:
(defun map-my-term-codes (map)
(define-key map (kbd "M-O 5 [")
[control-bracketleft])
)
Dan kemudian Anda dapat beristirahat: ini adalah akhir dari perjalanan. Tentu saja, jika Anda tidak peduli dengan terminal, itu cepat karena Anda akan melewati semua bagian yang menyakitkan. Tapi Anda akan mengakui itu juga agak tidak lengkap.
Dua catatan akhir:
Saya memilih ESC O 5 [
kode C-[. Ini hanya sebuah contoh: Saya tidak akan berpura-pura itu pilihan yang baik . Hanya 5
bagian, yang artinya C-, yang menuruti semacam konvensi yang sudah mapan
mengkonfigurasi konsol linux meninggalkan rasa yang tidak enak: sepertinya tidak mungkin untuk melakukan pengikatan tanpa menggunakan simbol perantara yang ada , dan yang saya perlukan
tidak ada . Saya menggunakan simbol dalam F21- F246kisaran seperti dalam kebanyakan contoh internet, tetapi tidak sangat memuaskan. Tidak apa-apa untuk beberapa ikatan yang tidak terkait, tetapi tidak akan melayani skema sistematis.
Edit
- Saya telah menyelesaikan ini dengan Esckasing - yang memiliki kepribadiannya sendiri - di pos lain: Cara menghapus binding ke kunci awalan ESC
di sini adalah bagian dari konfigurasi untuk diumpankan loadkeys
. Saya meletakkan ini di /root/custom.kmap, dan memuatnya ketika saya perlu (yang jarang terjadi). Konfigurasi aktual saya juga memetakan panah dan kombinasi pengubah yang berbeda, tetapi agak panjang, pilihan simbol dan urutan dipertanyakan, dan saya tidak yakin kode kunci untuk keyboard saya akan cocok dengan Anda. Jadi mari kita tetap pada tingkatnya: ini hanyalah ilustrasi.
keymaps 0-127
# http://tldp.org/HOWTO/Keyboard-and-Console-HOWTO-15.html
# web+man:keymaps
# web+man:loadkeys
# escape
keycode 1 = F100
alt keycode 1 = Escape # keep the Escape behavior somewhere
# keycode 26 = bracketleft
control keycode 26 = F115 # Control_bracketleft does not exist
string F100 = "\033OO" # map this to [escape] in map-my-term-codes
string F115 = "\033O5["
Solusi berikut ini agak kludky, tetapi tampaknya berhasil:
Biarkan
~/.xbindkeysrc
berisi yang berikut ini:Sekarang
xbindkeys
akan menerjemahkan C-[ke C-<f13>dan C-]ke C-<f14>, sehingga mereka dapat terikat dalam emacs secara bebas. Anda mungkin ingin mengikatabort-recursive-edit
sesuatu selain dari C-], misalnya C-S-g,.Kelemahannya adalah bahwa sekarang C-[rusak di setiap aplikasi kecuali Emacs, yang dapat diperbaiki dengan menambahkan beberapa logika untuk menguji apakah kombinasi kunci dikirim ke emacs ...
sumber
C-]
.C-]
ikatan saya berhenti bekerja setelah saya menyalakan Xbindkeys, jadi saya juga rebound itu.