もっと interactive を使おう

;; 指定領域をperltidy
(defun perltidy-region ()
  "Run the perltidy parser on the current region."
  (interactive)
  (let ((start (mark))
        (end (point))
        (shell-command-default-error-buffer "perltidy-errors")
        (command "perltidy"))
    (shell-command-on-region
     start
     end
     command
     t t
     shell-command-default-error-buffer)))

;; 上記のbuffer全体版
(defun perltidy-buffer ()
  "Run the perltidy parser on the current buffer."
  (interactive)
  (save-excursion
    (mark-whole-buffer)
    (perltidy-region)))

世の中の Emacs 使いの約八割は interactive の使い方をよくわかっていないという説をとなえてみる。
同じことをするなら自分ならこう書くかな。

(defun perltidy-region (beg end)
  "Run the perltidy formater on the region."
  (interactive "r")
  (let ((perltidy "perltidy")
        (error-buffer "*perltidy-errors*"))
    (shell-command-on-region beg end perltidy t t error-buffer)))

(defun perltidy-buffer (buffer)
  "Run the perltidy formatter on the buffer."
  (interactive (list (current-buffer)))
  (with-current-buffer buffer
    (perltidy-region (point-min) (point-max))))

(interactive "r") でインタラクティブに呼ばれた場合はカレントリージョンの開始位置、終了位置が引数になる。で、interactive の引数に文字列の代わりに リストを渡せばそれが引数の代わりになる。
まぁ、本当は emacs.el に以下の様に書いてあるんだけど。

(defun perltidy-region (beg end)
  (interactive "r")
  (shell-command-on-region beg end "perltidy -q" nil t))