Подтвердить что ты не робот

Emacs lisp "shell-command-on-region"

В GNU Emacs я хочу запустить программу, figlet, в текущем выделенном тексте. Затем я хочу прокомментировать созданный регион.

Я выяснил, как это сделать, используя стандартные команды Emacs:

  • установить метку с C- <space> в начале слова
  • переместите курсор в конец слова
  • C-u M-x shell-command-on-region RET figlet RET
  • M-x комментарий-область RET

Однако мне не удалось решить, как написать программу Emacs lisp, чтобы сделать все это. Вот моя попытка:

(defun figlet-region () 
  (interactive)
  (push-mark)
  (shell-command-on-region "figlet")
  (comment-region (mark) (point))
  (pop-mark)
)

(global-set-key "\C-c\C-f" 'figlet-region)

Затем C-<space>; M-x figlet-region производит мусор:

figlet-region: Wrong number of arguments: #[(start end command &optional output-buffer replace error-buffer display-error-buffer) "ÆÇÈ  
\"!É
'jÊ!j;j
0Wb
?Ë`Ì\"Í ÎQÎDRÎÉ!\"&
ffÏ )ãÐqÑ!#Ò#p=¬É$]d|e^|Íed ΠÎD¡ÎÉ!\"&â%qÉ$Á&%Ó *Í ÉØ#DÚ#É!\"&*#Ô!#ÕÖ×!8WrÐ!qd`Z'o   ØcÙÉ\"d'Zb)(Úp!)Û!*" [error-buffer small-temporary-file-directory temporary-file-directory exit-status error-file replace make-temp-file expand-file-name "scor" nil ...] 9 1945557 (let (string) (unless (mark) (error "The mark is not set now, so there is no region")) (setq string (read-from-minibuffer "Shell command on region: " nil nil nil (quote shell-command-history))) (list (region-beginning) (region-end) string current-prefix-arg current-prefix-arg shell-command-default-error-buffer t))], 1

Ответ

(defun figlet-region (&optional b e) 
  (interactive "r")
  (shell-command-on-region b e "figlet" (current-buffer) t)
  (comment-region (mark) (point)))

(Это основано на ответе Трей Джексона.)

Пример (Lisp Режим взаимодействия)

;;  _   _                 _        
;; | |_| |__   __ _ _ __ | | _____ 
;; | __| '_ \ / _` | '_ \| |/ / __|
;; | |_| | | | (_| | | | |   <\__ \
;;  \__|_| |_|\__,_|_| |_|_|\_\___/

Пример (режим CPerl)

#  _   _                 _        
# | |_| |__   __ _ _ __ | | _____ 
# | __| '_ \ / _` | '_ \| |/ / __|
# | |_| | | | (_| | | | |   <\__ \
#  \__|_| |_|\__,_|_| |_|_|\_\___/
4b9b3361

Ответ 1

Я не уверен, что вы пытаетесь выполнить с нажатием и появлением меток, я полагаю, что вы получите такую ​​же функциональность, выполнив это:

(defun figlet-region (&optional b e) 
  (interactive "r")
  (shell-command-on-region b e "figlet")
  (comment-region b e))

Аргумент интерактивности сообщает Emacs передать регион (точка и знак) в качестве первых двух аргументов команды.

Ответ 2

Не очень хорошая идея использовать интерактивную команду типа shell-command-on-region в программе lisp. Вы должны использовать call-process-region:

(defun figlet-region (&optional b e) 
  (interactive "r")
  (call-process-region b e "figlet" t t)
  (comment-region (mark) (point)))

Он должен быть более устойчивым к различным пользовательским параметрам.

Ответ 3

Ну, я не уверен, откуда идет мусор, но сама ошибка исходит от shell-command-region. При использовании в elisp он ожидает не менее 3 аргументов, START END и COMMAND.

Кроме того, в общем, плохой практикой является беспорядок с меткой в ​​функциях. Вот что должен сказать документ push-метки по этому вопросу:

Новичок Emacs Lisp программисты часто попробуйте использовать знак для неправильного цели. См. Документацию `set-mark 'для получения дополнительной информации.