Как установить кодировку вывода команды 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, но, опять же, без дополнительной информации о том, что вы используете сейчас, и без возможности экспериментировать в системе, аналогичной вашей, я могу только намекнуть.