Как установить кодировку вывода команды shell-command-on-region?

У меня есть небольшой сценарий elisp, который применяет Perl::Tidy к региону или целому файлу. Для справки вот скрипт (заимствованный из EmacsWiki):

(defun perltidy-command(start end)
"The perltidy command we pass markers to."
(shell-command-on-region start 
                       end 
                       "perltidy" 
                       t
                       t
                       (get-buffer-create "*Perltidy Output*")))

(defun perltidy-dwim (arg)
"Perltidy a region of the entire buffer"
(interactive "P")
(let ((point (point)) (start) (end))
(if (and mark-active transient-mark-mode)
    (setq start (region-beginning)
          end (region-end))
  (setq start (point-min)
        end (point-max)))
(perltidy-command start end)
(goto-char point)))

(global-set-key "\C-ct" 'perltidy-dwim)

Я использую текущий Emacs 23.1 для Windows (EmacsW32). Проблема, с которой я сталкиваюсь, заключается в том, что, если я применяю этот сценарий к файлу с кодировкой UTF-8 ("U(Unix)" в строке состояния), вывод возвращается с кодировкой Latin-1, то есть два или более символов для каждого Исходный символ ASCII.

Есть ли способ, как я могу это исправить?

РЕДАКТИРОВАТЬ: проблема, кажется, решается с помощью (set-terminal-coding-system 'utf-8-unix) в моем init.el, У кого-нибудь есть другие решения, пишите!

2 ответа

Ниже от shell-command-on-region документ

To specify a coding system for converting non-ASCII characters
in the input and output to the shell command, use C-x RET c
before this command.  By default, the input (from the current buffer)
is encoded using coding-system specified by `process-coding-system-alist',
falling back to `default-process-coding-system' if no match for COMMAND
is found in `process-coding-system-alist'.

Во время выполнения ищет систему кодирования из process-coding-system-alist сначала, если это ноль, то выглядит из default-process-coding-system,

Если вы хотите изменить кодировку, вы можете добавить опцию конвертации в process-coding-system-alistниже приводится содержание.

Value: (("\\.dz\\'" no-conversion . no-conversion)
 ...
("\\.elc\\'" . utf-8-emacs)
("\\.utf\\(-8\\)?\\'" . utf-8)
("\\.xml\\'" . xml-find-file-coding-system)
 ...
("" undecided))

Или, если вы не установили process-coding-system-alist, это ноль, вы можете назначить свой вариант кодирования default-process-coding-system,

например:

(setq default-process-coding-system '(utf-8 . utf-8))

(Если вход кодируется как utf-8затем вывод закодирован как utf-8)

Или же

(setq default-process-coding-system '(undecided-unix . iso-latin-1-unix))

Я также написал пост об этом, если вы хотите детали.

Цитирование документации для shell-command-on-region (C-h f shell-command-on-region RET):

Чтобы указать систему кодирования для преобразования не входящих в ASCII символов на входе и выходе в команду оболочки, используйте Cx RET c перед этой командой. По умолчанию вход (из текущего буфера) кодируется в той же системе кодирования, которая будет использоваться для сохранения файла, "buffer-file-coding-system". Если выходные данные собираются заменить область, то они декодируются из той же системы кодирования.

Неинтерактивными аргументами являются START, END, COMMAND, OUTPUT-BUFFER, REPLACE, ERROR-BUFFER и DISPLAY-ERROR-BUFFER. Невзаимодействующие абоненты могут указывать системы кодирования, связывая "coding-system-for-read" и "coding-system-for-write".

Другими словами, вы бы сделали что-то вроде

(let ((coding-system-for-read 'utf-8-unix))
  (shell-command-on-region ...) )

Это не проверено, не уверен, что значение coding-system-for-read (или возможно -write вместо? или как хорошо?) должно быть в вашем случае. Я думаю, вы также можете использовать аргумент OUTPUT-BUFFER и направить вывод в буфер, система кодирования которого настроена на то, что вам нужно.

Другой вариант может заключаться в том, чтобы покачивать локаль в вызове perltidy, но, опять же, без дополнительной информации о том, что вы используете сейчас, и без возможности экспериментировать в системе, аналогичной вашей, я могу только намекнуть.

Другие вопросы по тегам