Wed, 23 Jan 2008

Копиране от буфера на X.org в буфер на GNU Emacs

Потребителите на GNU Emacs навярно са забелязали, че понякога се проявява досаден проблем при копиране на текст от буфера на X.org. Полученият текст в буфера на Emacs видимо се отличава от нормалния текст по шрифт и размер. Проблемът е най-лесно забележим при копиране на знаци от кирилицата, но се наблюдава и при някои специални знаци. Например:

Пример за копиране на текст от уеб-четец

При поставянето на избрания текст в буфер на Emacs, резултатът е неприятен:

Поставен текст в Emacs (преди промяната)

Знаците от кирилицата в копирания текст са много по-едри от нормалното (спрямо латиницата или текста, писан в буфера по-рано). Едно бързо изследване на някоя от тези едри букви с M-x describe-char показва, че те не само имат различен шрифт, но и странно кодиране:

  character: м (54238, #o151736, #xd3de, U+043C)
    charset: japanese-jisx0208 (JISX0208.1983/1990 Japanese Kanji: ISO-IR-87.)
 code point: #x27 #x5E
     syntax: w 	which means: word
   category: Y:Cyrillic characters of 2-byte character sets j:Japanese
	     |:While filling, we can break a line at this character.
buffer code: #x92 #xA7 #xDE
  file code: #xD0 #xBC (encoded by coding system mule-utf-8)
    display: by this font (glyph code)
     -JIS-Fixed-Medium-R-Normal--16-150-75-75-C-160-JISX0208.1983-0 (#x275E)

Представянето на редовната буква „м“ от кирилицата с японското кодиране JIS X 0208 е неуместно, още повече когато това става в буфер, в който очакваме цялото съдържание да е представено в UTF-8.

Оказва се, че проблемът с представянето на текста съществува още на ниво X. По исторически причини в X има много начини за представяне на текст в буфера и затова при копиране на съдържанието му Emacs се опитва да отгатне какво е кодирането там. Това се прави по серия от евристични методи.

За щастие, можем да подскажем на Emacs да опитва най-напред да декодира текста като UTF-8 (дори и текстът в буфера да не е обявен изрично за такъв), а едва при евентуален провал да продължава с евристиката си. За целта трябва да установим стойност на променливата x-select-request-type:

(setq x-select-request-type '(UTF8_STRING COMPOUND_TEXT STRING TEXT))

Тази променлива не подлежи на управление с интерфейса на Customize, затова горният ред трябва да се постави в ~/.emacs. Разбира се, няма нужда да рестартираме Emacs, за да усетим промяната. Достатъчно е само да поставим курсора някъде в израза (setq …) и да натиснем C-M-x. След това вече може да копираме текст от буфера на X без да получаваме странно форматирани символи:

Поставен текст в Emacs (след промяната)