2010-08-12 6 views
12

짧은 버전 : emacs의 xterm-mouse-mode를 사용할 때 Somebody (emacs? bash? xterm?)는 xterm의 제어 시퀀스를 가로 채고 \ 0으로 바꿉니다. 첫 번째 223 열에 만 마우스가 있기 때문에 와이드 모니터에는 고통이 있습니다.Emacs, unicode, xterm 마우스 이스케이프 시퀀스 및 와이드 터미널

범인은 무엇이며 어떻게 해결할 수 있습니까?

유니 코드/UTF-8 지원과 관련이 있다고 나는 말할 수 있습니다. 5-6 년 전에 큰 모니터를 사용했을 때 문제가되지 않았기 때문입니다.

다음 세부 정보 ...

고마워요!

이맥스 xterm-mouse-mode는 x = 95 주변에서 시작하는 잘 알려진 약점 마우스 조작을 처리합니다. 최신 버전의 emacs에서 채택한 A workaround은 문제를 x = 223으로 푸시합니다.

몇 년 전 나는 xterm이 7 비트 옥텟의 위치를 ​​인코딩한다는 것을 알아 냈습니다. X의 =의 X-96로 인코딩 할 수 지정된 위치가 'X', 전송 :

\40+x (x < 96) 
\300+X/64 \200+X%64 (otherwise) 

우리는 이맥스에서 주어진 x 위치에 하나를 추가해야 하나에서 xterm을 시작에 위치하지 제로 때문이다. 따라서 마법의 x = 95 숫자는 첫 번째 이스케이프 된 숫자 인 "\ 300 \ 200"으로 코드화되어 있기 때문에 나타납니다. 누군가 (emacs? bash? xterm?)는 ISO 2022의 "C0"제어 순서를 취급합니다. x = 159부터는 ISO 2022의 일부인 "C1"시퀀스 (\ 301 \ 200)로 변경됩니다.

현재 x = 223 제한에 해당하는 \ 302 시퀀스의 문제가 발생합니다. 몇 년 전 수동으로 문제를 해결 한 \ 302 및 \ 303 시퀀스를 가로 채기 위해 해킹을 확장 할 수있었습니다. 앞으로 몇 년 동안 빨리 감기를 걸었습니다. 오늘 저는 x = 223에 다시 붙어 있습니다. 왜냐하면 누군가 그 시퀀스를 \ 0으로 대체하기 때문입니다. 그래서,

ESC [ M SPC [email protected] ! ESC [ M # [email protected] ! 

(모든 COL> 223)

ESC [ M SPC \303\207 ! ESC [ M # \303\207 ! 

대신 이맥스 보고서를 생성 라인 1, COL 250 클릭 기대할 수있는 곳

나는 의심이 유니 코드/UTF -8 지원이 범인이다. 일부 파고는 the Unicode standard allowed C0 and C1 sequences as part of UTF-8 until Nov 2000이며, 누군가는 메모를 가져 오지 않았다고 생각합니다 (다행히도). 그러나 \ 302 \ 200 - \ 302 \ 237은 Unicode control sequences입니다. 그래서 누군가가 그들을 쑤셔 버리고 (그들과 함께하는 사람을 알고 있습니다!) 대신 \ 0을 반환합니다.

더 자세한 질문이 있습니다.
- 누구인가 이맥스의 손실 버퍼에 도달하기 전에 코드를 가로채는 사람?
- 제어 시퀀스에만 해당되는 경우 인쇄 가능한 유니 코드의 UTF-8 인코딩 인 \ 302 \ 237 뒤에 오는 문자는 어떻게 다시 \ 0로 올까요?
- 이맥스는 손실을 유니 코드 문자 또는 8 진수 이스케이프 시퀀스로 표시할지 여부를 결정하며 왜 두 문자가 일치하지 않습니까? 예를 들어, 자체 빌드 cygwin emacs 23.2.1 (xterm 229)은 컬럼 161에 대해 301 \ 202를보고하지만 rhel5.5가 제공하는 emacs 22.3.1 (xterm 215)는 "Â"(곡절 기호가있는 라틴어 A) UTF-8에서는 실제로 \ 303 \ 202입니다!

업데이트 :

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); 

희망이 (나 같은)가 나타납니다 : 여기

그것이 UTF-8 형식으로 마우스 위치를 방출하게 xterm을-261에 대한 패치입니다 xterm의 차기 버전 ...이 패치는 xterm이 emacs-23 (utf-8 입력을 가정 함)을 사용하여 상자 밖에서 작동하게하고 기존 문제점을 xt-mouse.el로 수정합니다. 이맥스 (22)와 함께 사용하려면이 마우스 위치를 디코딩하는 데 사용하는 함수의 재정을 필요로 (새로운 정의와 함께 잘 작동 이맥스-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는 배포 로그인하는 기계, xterm을 작업하는 모든 기계에 패치하십시오. 빌라!

경고 : 마우스 이스케이프 시퀀스는 더 이상 얻을 수 있기 때문에 xterm 등의 마우스 모드를 사용하지만 UTF-8로 자신의 입력을 취급하지 않는 응용 프로그램은이 패치에 의해 혼란스러워 할 것이다. 그러나 이러한 응용 프로그램은 x> 95 인 마우스 위치가 utf-8 코드와 유사하지만 보이지 않기 때문에 현재 xterm과 끔찍하게 구분됩니다. xterm을위한 새로운 마우스 모드를 만들지 만, 특정 응용 프로그램 (gnu screen!)은 알 수없는 이스케이프 시퀀스를 필터링합니다. 이맥스는 내가 사용하는 유일한 터미널 마우스 앱이기 때문에 패치를 순수한 승리로 간주하지만 YMMV.

+2

나는이 터미널을 가지고 있지 않다. Emacs 사용자는 아니지만,이 질문은 암울하다. 새로운 사용자가 자세히 설명합니다. 나는 (그것을 재현하고 설정을 분석 꽤 시간이 걸릴 것)이 하나의 당신을 도울 수 있다고 생각하지만, 당신이 정확한을 저장하기 위해 (도구) "스크립트"를 사용하여 시도 터미널 에뮬레이터로 전송 바이트가 없습니다 신청? 는 – scy

+1

흠 (아, 그리고 아마이 질문에 오히려 고급 사용자에서 후보 이상 ... 것). 스크립트는 똑같은 것을 봅니다. 또한 마우스 모드를 활성화 한 다음 표준 입력을 옥텟 스트림으로 변환하는 빠른 C 프로그램을 작성했습니다. $ xterm -e echo-octets xterm (위)에서 직접 실행해도 7 비트로 설정할 수있는 모든 것, 마우스 클릭은 \ 377 이하로 제한됩니다 - 의심스럽게 8 비트 인코딩. 컴파일 되었습니까? 어쨌든 ... 이맥스 아니에요과 위 맞다면 희망 비난하지. – Ryan

답변

3

OK, 알아 냈습니다. 실제로 두 가지 문제가 있습니다.

먼저, 일부 소스 다이빙은 xterm이 창의 마우스 사용 가능 영역을 223x223 문자로 잘라내고 다른 모든 위치에 대해 0x0을 보냅니다.

둘째, emacs-23은 UTF-8을 인식하며 x> 160 및 y> 94 ​​인 마우스 이벤트로 인해 혼란 스럽습니다. 이 경우 xterm의 x 및 y 인코딩은 2 바이트 UTF-8 문자 (예 : 0xC2 0x80)로 표시되므로 결과적으로 마우스 시퀀스가 ​​한 문자 짧아 보입니다.

xterm 용 마우스 이벤트가 emacs-23을 unconfuse하고 2047x2047까지 터미널을 허용하는 UTF-8을 방출하도록 만드는 패치를 작성하고 있지만 아직 어떻게 될지 잘 모르겠습니다.

2

23.2에서 작동을 멈추게하는 해결책 (및 업스트림 수정 사항)이 Emacs 자체에서 발생했다고 생각합니다. 23.1은 urxvt, gnu screen, putty 또는 iTerm을 사용하여 95 열 뒤에 마우스 클릭을 처리 할 수 ​​있지만 23.2는 사용할 수 없습니다. 모든 것을 latin-1로 설정하면 아무런 효과가 없습니다. 23.1은 xt-mouse.el에서 동일한 코드를 사용합니다. src/lread.c와 src/character.h가 바뀌었고 한눈에 버그가 어딘가에 있다고 추측 할 수 있습니다. 223 번째 칸 이후에 무슨 일이 일어나는지에 관해서는 단서가 없습니다.

23.2의 xt- 마우스 회귀에 짜증을내는 사람들을 위해서 마우스 222 번까지의 마우스 클릭으로 작동하는 수정 된 버전의 xterm-mouse-event-read가 있습니다. 내 원래 수정이 부족한 처리). 이것은 아마도 23.1 이전에는 작동하지 않습니다.

(defun xterm-mouse-event-read() 
    (let ((c (read-char))) 
    (cond ((= c 0) #x100) 
     ; for positions past col 222 emacs just delivers 
     ; 0x0, best we can do is stay at eol 
     ((= 0 (logand c (- #x100))) c) 
     ((logand C#xff))))) 

... 편집 : 여기 이맥스 24 (BZR 헤드)의 버전입니다. 23.2에서 col 222까지는 다시 작동하지만, 222 오버플로 처리가 부족합니다. Ryan 제안 :

(defun xterm-mouse-event-read() 
    (let ((c (read-char))) 
    (if (> C#x3FFF80) 
     (+ 128 (- C#x3FFF80)) 
     c))) 
1

xterm이 패치로 utf-8 모드에서 작동하지만 utf-8 해킹은 표현할 수없는 한 유니 코드 문자가 삭제되기 때문에 다른 모든 로케일에서 가능한 최악의 방법으로 손상됩니다.

rxvt-unicode는 (9.09 이후의 릴리스에서) "ESC [코드; x; y M", 십진수를 사용하여 양식의 응답을 보내는 1015 모드를가집니다. 이것은 앱에서 프로빙을 할 필요가 없으며 UTF-8 이외의 지역에서도 작업 할 수 있다는 이점이 있습니다.

+0

감사합니다. 필자는 실제로 rxvt 솔루션이 원칙적으로 훨씬 뛰어 났지만 (원래 vt100이 수행해야했던 기능), 너무 많은 다른 응용 프로그램을 중단시킵니다. 때로는 일부 앱을 깨 버리거나 모든 앱을 다시 작성하도록 선택함으로써 덜 침략적 인 앱으로 이동했습니다. 즉, 어쨌든 gnu 화면에서 마우스 처리를 다시 작성해야한다는 것이 밝혀졌습니다. – Ryan

5

xterm-262은 위에 인라인 된 패치를 추가합니다. 그러나이 패치는 의도적으로 고장났습니다. Rxvt-unicode의 개발자는이를 인식하고 마우스 좌표를보고하는 또 다른 확장 기능을 추가했습니다.

지금 당장이 문제에 대한 광범위한 지원을 받고 있습니다. Rxvt-unicodeiTerm2은 이미 두 확장자를 모두 지원합니다. xterm (urxvt 확장을 지원) 패치를 만들었으며, 새로운 확장자를 모두 지원하는 gnome-terminal, konsoleputty 패치를 만들었습니다. 응용 프로그램에 관해서는 에 urxvt 확장에 대한 지원을 추가했습니다.

저와 함께 더 많은 터미널 개발자와 응용 프로그램에이 확장 기능을 구현하도록하십시오 (적어도 urxvt입니다. 다른 응용 프로그램이 올바르게 인식 할 수 없기 때문에).

기술 정보 및 추가 정보는 http://www.midnight-commander.org/ticket/2662을 참조하십시오.

관련 문제