tutorial source para mac for emacs lisp elisp

source - Emacs lisp "shell-command-on-region"



emacs para mac (3)

En GNU Emacs, quiero ejecutar un programa, figlet, en el texto seleccionado actualmente. Luego quiero comentar la región que se produce.

He descubierto cómo hacerlo usando los comandos estándar de Emacs:

  • establecer marca con C- <space> al comienzo de la palabra
  • mover el cursor al final de la palabra
  • Cu Mx shell-command-on-region RET figlet RET
  • Mx comentario-región RET

Sin embargo, no he podido averiguar cómo escribir un programa Emacs lisp para hacer todo esto. Aquí está mi intento:

(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)

Entonces C-<space>; Mx figlet-region C-<space>; Mx figlet-region produce basura:

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

Responder

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

(Esto se basa en la respuesta de Trey Jackson.)

Ejemplo (modo de interacción Lisp)

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

Ejemplo (modo CPerl)

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


Bueno, no estoy seguro de dónde viene la basura, pero el error en sí mismo proviene de shell-command-region . Cuando se usa en elisp , espera al menos 3 argumentos, START END y COMMAND .

Además, en general, es una mala práctica meterse con la marca en las funciones. Esto es lo que el documento de push-mark tiene que decir sobre el tema:

Los programadores novatos de Emacs Lisp a menudo intentan usar la marca para los propósitos equivocados. Consulte la documentación de `set-mark ''para obtener más información.


No es una buena idea usar un comando interactivo como shell-command-on-region en un programa lisp. Debes usar call-process-region lugar:

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

Debería ser más resistente contra varias opciones de usuario.


No estoy seguro de lo que estás tratando de lograr con el empuje de las marcas, creo que obtendrías la misma funcionalidad haciendo esto:

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

El argumento de interactivo le dice a Emacs que pase la región (señalar y marcar) como los dos primeros argumentos del comando.