LINUX.ORG.RU

Emacs и разные кодировки


0

0

Проблемка возникла с emacsом небольшая.Вопрос как переключать кодировки в текущем буфере?Вот открыл файл и понял что он в cp1251 а не koi8-r и при нажатии на что-нибудь он автоматом в cp1251 все это покажет.
В самом .emacs прописанно:
(set-terminal-coding-system 'koi8-r)
(set-keyboard-coding-system 'koi8-r)
; This could help for transferring data from bad old apps
;(set-selection-coding-system 'koi8-r)
(cond (window-system (set-frame-font "-misc-fixed-medium-r-normal-*-16-*-*-*-*-*-*-*")))
(setq default-buffer-file-coding-system 'koi8-r)
(prefer-coding-system 'koi8-r)
(define-coding-system-alias 'koi8-u 'koi8-r)
(put-charset-property 'cyrillic-iso8859-5 'preferred-coding-system 'koi8-r)
(codepage-setup 1251)
(define-coding-system-alias 'windows-1251 'cp1251)
(set-input-mode nil nil 'We-will-use-eighth-bit-of-input-byte)
(setq-default coding-system-for-read 'koi8-r)
(set-selection-coding-system 'koi8-r)
(defun My-select-coding ()
(interactive)
(let ((noconf (not (buffer-modified-p))))
(set-buffer-file-coding-system
(read-coding-system "Select coding system: "))
(revert-buffer nil noconf t)))
;;
(global-set-key "\C-xr" 'My-select-coding)
То есть новый буфер я открываю спокойно в нужно кодировке C-x RET c cp1251 - это работает.А вот текущий буфер никак не переключается. Все в тех же дрючках заместо русского. Что еще дописать сюда надо?

anonymous

В емаксе из цвс (23.0.0) есть команда revert-buffer-with-coding-system. В обычном емаксе её кажись нема. Вызывается как C-x <RET> r CHARSET

Zmacs
()
Ответ на: комментарий от Zmacs

Вот у меня 22.0.50 и забиндено C-x r только используется как видно revert-buffer. Функция revert-buffer-with-coding-system тоже присутствует.Как бы мне поменять строчку revert-buffer в функции:
(defun My-select-coding ()
(interactive)
(let ((noconf (not (buffer-modified-p))))
(set-buffer-file-coding-system
(read-coding-system "Select coding system: "))
(revert-buffer nil noconf t)))
;;
(global-set-key "\C-xr" 'My-select-coding)
чтобы там было rever-buffer-with-system-coding автоматом? Что прописать в качестве переменных заместо nil noconf t ?

anonymous
()
Ответ на: комментарий от Zmacs

Ну частично почитал мануальчик сделал такую вещь:
(defun My-select-coding ()
(interactive)
(let ((noconf (not (buffer-modified-p))))
;; (set-buffer-file-coding-system
;; (read-coding-system "Select coding system: "))
(revert-buffer-with-coding-system (read-coding-system "Select coding system: "))))
;
(global-set-key "\C-xr" 'My-select-coding)
)
Все работает.Только вопрос в конце смущает:
Revert buffer from file <тут имя файла> (yes or no)
Как бы выкинуть вопрос этот?

anonymous
()
Ответ на: комментарий от Reset

Ну дык на функцию мою внимательно глядим и видим, что там определяется как раз C-x r :)))Мне только как избавится от вопроса не понятно

anonymous
()
Ответ на: комментарий от anonymous

я когда-то выкладывал небольшой код без использования revert-buffer* на http://www.emacswiki.org/cgi-bin/wiki/GnuEmacsRussification. Он там почти в самом низу.

Там используются функции (encode|decode)-coding-region, поэтому работает даже не на файловых буферах. Можешь попробовать, кодировки переключаются циклически по F5 я у себя использую уже достаточно долго, глюки есть, но некритичные. Хотя все же надо будет как-то подправить...

uj2 ★★★
()
Ответ на: комментарий от uj2

В чем плюс такого решения без revert-buffer? Ну понятно перекодировал в нужную и сохранил. По хорошему надо открывать в той кодировке которой я хочу. Но если при открытии кракозябры должен быть простой способ переключить кодировку на нужную.Вот для этого revert-buffer-with-system-coding и нужен. Но вот как её выполнить без дурацкого вопроса yes-no так и не нашел. А эту интересную штучку с recode-region я наверное оставлю в .emacs

anonymous
()
Ответ на: комментарий от anonymous

Плюс в том, что таким образом можно перекодировать не только файловый буфер, и не только ПОЛНОСТЬЮ, но и другие буферы, а также отдельные регионы буфера (ну, в перспективе). Например, у меня иногда бывает попадается текст в непонятной кодировке; я просто создаю новый буфер, копипастю его туда, и там уже по F5 ищу нужную кодировку.

> Но если при открытии кракозябры должен быть простой способ переключить кодировку на нужную

В моих функциях нужно просто доделать, чтобы оно снимало флажок модификации при декодировании (поскольку на самом деле ничего не меняется в самом файле), если я правильно понял.

> Но вот как её выполнить без дурацкого вопроса yes-no так и не нашел.

Тю, переопредели временно эти функции, делов-то :)

(flet ((y-or-n-p (prompt) t) (yes-or-no-p (prompt) t)) (revert-buffer-with-coding-system 'windows-1251))

uj2 ★★★
()
Ответ на: комментарий от uj2

Тогда вопрос а как будет выглядить со стандартыми recode-region твоя функция? А вот то что получилось в результате подсказки:
(defun My-select-coding ()
(interactive)
(let ((noconf (not (buffer-modified-p))))
(flet ((y-or-n-p (prompt) t) (yes-or-no-p (prompt) t)) (revert-buffer-with-coding-system (read-coding-system "Select coding system: ")))))
(global-set-key "\C-xr" 'My-select-coding)
Сенкс. Теперь все отлично по C-x r переключает сразу после запроса на нужную кодировку, а по C-x <RET> r после запроса подтверждение спрашивает. Теперь функцию твою со стандартным recode-region заценить и все вобше отлично будет.

anonymous
()
Ответ на: комментарий от anonymous

> Тогда вопрос а как будет выглядить со стандартыми recode-region твоя функция?

Хрен его знает, возьми да напиши :) Я уж не помню, почему я recode-region не использовал. По-моему, потому, что в емаксах < 22 такой функции не было и пришлось юзать то, что было...

uj2 ★★★
()
Ответ на: комментарий от uj2

Все сделал на твоей основе:
(setq evm-coding-systems-list (make-ring 10))
(ring-insert evm-coding-systems-list 'koi8-r)
(ring-insert evm-coding-systems-list 'alternativnyj)
(ring-insert evm-coding-systems-list 'iso-8859-5)
(ring-insert evm-coding-systems-list 'windows-1251)
(ring-insert evm-coding-systems-list 'utf-8)
(ring-insert evm-coding-systems-list 'cp866-dos)

(global-set-key [f5]
(lambda ()
(interactive)
(let* ((keys (recent-keys))
(len (length keys))
(key1 (if (> len 0) (elt keys (- len 1)) nil))
(key2 (if (> len 1) (elt keys (- len 2)) nil))
cs)
(if (eq key1 key2)
(setcar evm-coding-systems-list
(ring-plus1 (car evm-coding-systems-list)
(ring-length evm-coding-systems-list)))
(setcar evm-coding-systems-list 0))
(set-buffer-multibyte t)
(recode-region (point-min) (point-max) (aref (cddr evm-coding-systems-list)
(car evm-coding-systems-list)) buffer-file-coding-system))
(set-buffer-file-coding-system (aref (cddr evm-coding-systems-list) (car evm-coding-systems-list)))))
Остался вопрос.Сейчас у меня целиком весь буфер перекодируется. Как сделать так чтобы только выделенное перекодировалось? Что заместо point-min и point-max прописать надо?И как еще при этом определить есть выделение, а если нет то весь буфер целиком?Интересно еще я правильно понял что при переключение кодировок по F5 он в том режиме что остановился(допустим на cp1251) и правит данный буфер и сохранять тоже в данной кодировке будет?Я правильно понял при:
(set-selection-coding-system 'koi8-r)
то копировать в другие буферы он будет в коевой кодировке?

anonymous
()
Ответ на: комментарий от uj2

Да еще интересная фича ваявилась. Переделал немножко перекодирование с целью read-only буфера тоже вертеть как охота. Так вот dired показывает немножко фигню какую-то. Локаль у меня koi а emacs пускается как LANG=ru_RU.UTF8 (надо для dictem иначе там русских нема).По умолчанию видно: 48640 тут_дрючки_с_псевдо_графикой 19 2006 Распайка при перекодировании на одной из кодировок; 48640 Янв 19 2006 куча_3_значных_цифр_через_слеш Это где вертеть чтобы нормально показывало?Пока полностью на utf переходить не охота. p.s. нифига не пропускает пост с такими данными:)

anonymous
()
Ответ на: комментарий от anonymous

ох, скока у тебя вопросов, ты мануал на досуге почитай что-ли... :)

> Как сделать так чтобы только выделенное перекодировалось? Что 
> заместо point-min и point-max прописать надо? И как еще при этом 
> определить есть выделение, а если нет то весь буфер целиком?

Я бы сделал так: 

(let ((start (if (and transient-mark-mode mark-active)
                (region-beginning) (point-min))) 
      (end (if (and transient-mark-mode mark-active) 
              (region-end) (point-max))))
  (recode-region start end ...

как-то так. Токо ето, я этот код не проверял...

> Интересно еще я правильно понял что при переключение кодировок 
> по F5 он в том режиме что остановился(допустим на cp1251) и правит
> данный буфер и сохранять тоже в данной кодировке будет?

Насчет обычного `recode-buffer' не знаю, я не втыкал особо 
в специфику. Мои функции (`recode-buffer-dangerous' и 
`recode-buffer-safe') меняют `buffer-file-coding-system', 
посему сохранение будет происходить в правильной кодировке.

uj2 ★★★
()
Ответ на: комментарий от anonymous

dired врядли будет работать, у меня не работает. В смысле, оно-то перекодирует, но потом файл найти не может (видимо, берет текст из буфера, хз, честно говоря, как).

uj2 ★★★
()
Ответ на: комментарий от uj2

10x завтра код проверю. А мануал да почитаю, уже надыбал все по русски и программирование на elisp до кучи. Все таки за всю эту балалайку я взялся неделю назад и до этого в глаза не видел ни emacs ни elisp

anonymous
()
Ответ на: комментарий от uj2

Не работает. Насколько я понял при первой проверке mark-active снимается. Как ее обратно поставить? Оппробовал mark-active устанавливать по разному искал и так и не нашел. Есть ли где функция при выполнении команды восстанавливать выделение? Попробовал save-excursion как то у меня оно не работает.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.