Продолжение истории про buffer-file-coding-system ...
Dmitry Astapov <[email protected]>
| Newsgroups | gmane.emacs.xemacs.user.russian |
|---|---|
| Organization | My Humble Opinions Ltd. -- views expressed are mine and only mine |
| Message-ID | <[email protected]> |
Если кто помнит, некоторое время тому назад я (в письме <[email protected]>) жаловался на то, что у меня не работает конструкция: (modify-coding-system-alist 'file "\\.abc\\'" '(windows-1251 . windows-1251)) Точнее, она работает, но не до конца - указаная coding-system используется для чтения файла с диска, но buffer-file-coding-system всегда оказывается "равным" set-language-environment. Т.е., в моем случае, я всегда получаю buffer-file-coding-system == koi8-u-unix. Соответственно, если ты после исправлений на автомате давишь C-x C-s, то файл записывается в кодировке koi8-u. Особенно замечательно работает это для xml-файлов в кодировке utf-8.... Чтобы этого не происходило, после открытия файла приходится делать M-x set-buffer-file-coding-system RET ut-8 (например) RET. "И так 18 раз"(с)анекдот. Надоедает до невозможности. Сегодя я раскопал топор войны и навалился на эту проблему. Что выяснилось: Ответственным за разбор file-coding-system-alist является insert-file-contents, которая живет в code-files.el. Трассировка показала, что определение coding-system, используемой для чтения данных с диска действительно работает без сучка и задоринки. А вот дальше ... Цитата: ;; now finally set the buffer's `buffer-file-coding-system'. [...] (if (local-variable-p 'buffer-file-coding-system (current-buffer)) ;; if buffer-file-coding-system is already local, just ;; set its eol type to what was found, if it wasn't ;; set already. (set-buffer-file-coding-system (subsidiary-coding-system buffer-file-coding-system (coding-system-eol-type coding-system))) ;; otherwise actually set buffer-file-coding-system. (set-buffer-file-coding-system coding-system)) Очевидно, что мне придет Счастье, если выполнится ветка со словом otherwise. Произойдет это только тогда, когда buffer-file-coding-system не будет local-variable для открываемого буффера... (звучит тревожная музыка, ассистены вносят на операционный стол set-language-enviroment). Тривиальные упражнения с edebug и grep показывают, что set-language-enviroment в ходе своей работы делает setq-default buffer-file-coding-system. А сама buffer-file-coding-system, как можно прочесть в ее документации, "Automatically buffer-local when set in any fashion". В том числе, очевидно, и при помощи setq-default ... Внимание, вопрос - что лучше, жить без set-language-enviroment, или научиться делать переменную virgin & unset? Сразу замечание - после: (setq-default buffer-file-coding-system nil) пресловутая проверка на local-variable-p все равно возвращает t. Какие есть идеи? И кто (с xemacs новее, чем 2.4.13) может подтвердить воспроизводимость бага? PS Инструкция По ВОспроизведению Бага (считаем, что по умолчанию сделано set-language-enviroment "Cyrillic-KOI8-R") C-x C-b *scratch* RET вводим (modify-coding-system-alist 'file "\\.zzz\\'" 'windows-1251) , делаем ему eval-last-sexp (C-x C-e) C-x C-f /tmp/bogus.zzz M-x set-buffer-file-coding-system RET windows-1251 что-то пишем по-русски C-x C-s C-x k RET Еще раз открываем /tmp/bogus.zzz Если в modeline написано "KOI8", а не "Cyr", и в переменной buffer-file-coding-system находится значение #<coding koi8_r_unix>, то баг в наличии имеется. -- Dmitry Astapov //ADEpt GPG KeyID/fprint: F5D7639D/CA36 E6C4 815D 434D 0498 2B08 7867 4860 F5D7 639D