Короткая версия: При использовании emacs 'xterm-mouse-mode, Somebody (emacs? Bash? Xterm?) Перехватывает управляющие последовательности xterm и заменяет их на \ 0.Это боль для широких мониторов, потому что только первые 223 столбца имеют мышь.
В чем виновник, и как я могу обойти это?
Из того, что я могу сказать, это связано с поддержкой Unicode / UTF-8, потому что это не было проблемой5-6 лет назад, когда у меня в последний раз был большой монитор.
Горы следуют подробности ...
Спасибо!
Emacs xterm-mouse-mode хорошо известенслабость обработки щелчков мыши, начиная с х = 95. Обходной путь , принятый в последних версиях emacs, устраняет проблему до x = 223.
Несколько лет назад я понял, что xterm кодирует позиции в 7-битных октетах.Для кодирования данной позиции 'x', с X = x-96, отправьте:
\40+x (x < 96)
\300+X/64 \200+X%64 (otherwise)
Мы должны добавить единицу к данной позиции x из emacs, потому что позиции в xterm начинаются с единицы, а не с нуля.Следовательно, появляется магическое число x = 95, потому что оно закодировано как «\ 300 \ 200» - первое экранированное число.Кто-то (emacs? Bash? Xterm?) Рассматривает такие, как управляющие последовательности "C0" из ISO 2022 .Начиная с x = 159, мы изменяем на последовательности "C1" (\ 301 \ 200), которые также являются частью ISO 2022.
Неисправности обращаются с последовательностями \ 302, что соответствует текущему пределу x = 223,Несколько лет назад мне удалось расширить хак до ручного перехвата последовательностей \ 302 и \ 303, что позволило решить проблему.Перенесемся на несколько лет вперед, и сегодня я обнаружил, что застрял на x = 223, потому что кто-то заменяет эти последовательности на \ 0.
Итак, где я ожидал бы щелкнуть строку 1, столбец 250производить
ESC [ M SPC \303\207 ! ESC [ M # \303\207 !
Вместо отчетов Emacs (для любого столбца> 223)
ESC [ M SPC C-@ ! ESC [ M # C-@ !
Я подозреваю, что поддержка Unicode / UTF-8 является виновником.Некоторые раскопки показывают, что стандарт Unicode допускал последовательности C0 и C1 как часть UTF-8 до ноября 2000 , и я предполагаю, что кто-то не получил памятку (к счастью).Однако, \ 302 \ 200 - \ 302 \ 237 - это Юникод управляющих последовательностей , так что Кто-то их хлюпает (делает кто-то-что с ними!) И возвращает \ 0 вместо этого.
Несколько более подробных вопросов:
- Кто это? Кто-нибудь, кто перехватывает коды до того, как они достигают буфера потерь emacs?
- Если это действительно просто управляющие последовательности, как получаются символы после \ 302 \237, которые являются UTF-8-кодировками печатаемого Unicode, также возвращаются как \ 0?
- Что заставляет emacs решить, отображать ли потери в виде символов Unicode или восьмеричных escape-последовательностей, и почему они не совпадают?Например, мой собственный сборщик cygwin emacs 23.2.1 (xterm 229) сообщает \ 301 \ 202 для столбца 161, а мой emacs 22.3.1 (xterm 215), предоставленный rhel5.5, сообщает "Â" (латинский A с дифракционным дифрагмом)что на самом деле \ 303 \ 202 в UTF-8!
Обновление:
Вот патч против xterm-261, который заставляет его генерировать позиции мыши в формате utf-8:
diff -r button.c button.utf-8-fix.c
--- a/button.c Sat Aug 14 08:23:00 2010 +0200
+++ b/button.c Thu Aug 26 16:16:48 2010 +0200
@@ -3994,1 +3994,27 @@
-#define MOUSE_LIMIT (255 - 32)
+#define MOUSE_LIMIT (2047 - 32)
+#define MOUSE_UTF_8_START (127 - 32)
+
+static unsigned
+EmitMousePosition(Char line[], unsigned count, int value)
+{
+ /* Add pointer position to key sequence
+ *
+ * Encode large positions as two-byte UTF-8
+ *
+ * NOTE: historically, it was possible to emit 256, which became
+ * zero by truncation to 8 bits. While this was arguably a bug,
+ * it's also somewhat useful as a past-end marker so we keep it.
+ */
+ if(value == MOUSE_LIMIT) {
+ line[count++] = CharOf(0);
+ }
+ else if(value < MOUSE_UTF_8_START) {
+ line[count++] = CharOf(' ' + value + 1);
+ }
+ else {
+ value += ' ' + 1;
+ line[count++] = CharOf(0xC0 + (value >> 6));
+ line[count++] = CharOf(0x80 + (value & 0x3F));
+ }
+ return count;
+}
@@ -4001,1 +4027,1 @@
- Char line[6];
+ Char line[9]; /* \e [ > M Pb Pxh Pxl Pyh Pyl */
@@ -4021,2 +4047,0 @@
- else if (row > MOUSE_LIMIT)
- row = MOUSE_LIMIT;
@@ -4028,1 +4052,5 @@
- else if (col > MOUSE_LIMIT)
+
+ /* Limit to representable mouse dimensions */
+ if (row > MOUSE_LIMIT)
+ row = MOUSE_LIMIT;
+ if (col > MOUSE_LIMIT)
@@ -4090,2 +4118,2 @@
- line[count++] = CharOf(' ' + col + 1);
- line[count++] = CharOf(' ' + row + 1);
+ count = EmitMousePosition(line, count, col);
+ count = EmitMousePosition(line, count, row);
Надеюсь, это(или что-то подобное) появится в будущей версии xterm ... патч заставляет xterm работать из коробки с emacs-23 (который предполагает ввод utf-8) и также исправляет существующие проблемы с xt-mouse.el,Чтобы использовать его с emacs-22, требуется переопределить функцию, которую он использует для декодирования позиций мыши (новое определение также отлично работает с emacs-23):
(defadvice xterm-mouse-event-read (around utf-8 compile activate)
(setq ad-return-value
(let ((c (read-char)))
(cond
;; mouse clicks outside the encodable range produce 0
((= c 0) #x800)
;; must convert UTF-8 to unicode ourselves
((and (>= c #xC2) (< emacs-major-version 23))
(logior (lsh (logand c #x1F) 6) (logand (read-char) #x3F)))
;; normal case
(c) ) )))
Распределить defun как часть .emacsна всех машинах, в которые вы входите, и исправляйте xterm на любых машинах, с которых вы работаете.Вуаля!
ПРЕДУПРЕЖДЕНИЕ: Приложения, которые используют режимы мыши xterm, но не обрабатывают их ввод как utf-8, запутаются этим патчем, потому что экранирующие последовательности мыши становятся длиннее.Тем не менее, эти приложения ужасно ломаются с текущим xterm, потому что позиции мыши с x> 95 выглядят как коды utf-8, но это не так.Я бы создал новый режим мыши для xterm, но некоторые приложения (экран gnu!) Отфильтровывают неизвестные escape-последовательности.Emacs - единственное приложение для терминальной мыши, которое я использую, поэтому я считаю, что патч - чистая победа, но YMMV.