2012-06-27 15 views
6

Quiero configurar emacs para usar las aplicaciones externas cuando abro archivos de imagen desde el modo dired.emacs direc y openwith

Por otro lado, también quiero usar imágenes en línea en los búferes de emacs.

Para abrir archivos en aplicaciones externas que utilizo openwith.el paquete http://www.emacswiki.org/emacs/OpenWith

El problema con el modo menor OpenWith es que es global y cuando está activado por un modo de descolgado dired

(add-hook 'dired-mode-hook 
      (lambda() 
      (setq truncate-lines t) 
      (openwith-mode t) 
      )) 

actúa en todas partes y todas las imágenes en línea en los búferes de emacs se abren en aplicaciones externas.

He intentado cambiar

:global t 

a

:global nil 

en el openwith.el, pero de alguna manera se desactiva el modo OpenWith por completo.

Entonces, mi pregunta es: ¿Cómo decirle a emacs que use abrir el modo menor solo con el búfer dired y en ningún otro lado?

Gracias.

Respuesta

0

Una forma podría ser establecer emacsclient como programa preferido para los tipos de archivos que desee en openwith-associations en openwith.el y comenzar a usar emacsclient.

Puede iniciar nueva sesión de emacs cada vez, pero eso suena más feo que la sugerencia anterior.

4

La manera en que openwith-mode funciona es un poco peculiar: se supone que se usa globalmente o no se usa en absoluto. Lo que quiere aquí, sin embargo, es usarlo localmente, es decir, solo desde un búfer directo.

Eso no se puede lograr muy fácilmente, pero aquí hay una manera.

Abra su archivo fuente de openwith-mode, openwith.el. Luego desplácese hacia abajo hasta llegar a la definición del modo menor real. Entonces comentario cabo esa definición mediante la colocación de una coma al principio de cada línea:

;;;###autoload 
; (define-minor-mode openwith-mode 
; "Automatically open files with external programs." 
; :lighter "" 
; :global t 
; (if openwith-mode 
;  (progn 
;   ;; register `openwith-file-handler' for all files 
;   (put 'openwith-file-handler 'safe-magic t) 
;   (put 'openwith-file-handler 'operations '(insert-file-contents)) 
;   (add-to-list 'file-name-handler-alist '("" . openwith-file-handler))) 
;  (setq file-name-handler-alist 
;   (delete '("" . openwith-file-handler) file-name-handler-alist)))) 

entonces debajo de este código (pero antes de (provide 'openwith)), inserte el siguiente código:

(defvar openwith-mode nil) 

(mapc (lambda (function) 
     (ad-add-advice function 
         '(dired-openwith nil t (advice . (lambda() (let ((openwith-mode t)) ad-do-it)))) 
         'around 0)) 
     '(dired-find-alternate-file 
     dired-find-file 
     dired-find-file-other-window 
     dired-mouse-find-file-other-window 
     dired-view-file)) 

(put 'openwith-file-handler 'safe-magic t) 
(put 'openwith-file-handler 'operations '(insert-file-contents)) 
(add-to-list 'file-name-handler-alist '("" . openwith-file-handler)) 

este código unas pocas cosas.

Primero, define una variable llamada openwith-mode. Esta variable se usa dentro de una de las funciones de openwith-mode que decide si usar una aplicación externa o no. Normalmente, Emacs proporciona automáticamente una variable como ésa cuando defines un modo menor; sin embargo, como acabamos de comentar la definición del modo secundario real anterior, volvemos a introducir esta variable explícitamente aquí.

El propósito de la variable es trabajar como un tipo de interruptor a través del cual podemos controlar si un archivo de imagen debe ser insertado o pasado a un visor externo.

A continuación tenemos la expresión (mapc ...). Lo que hacemos aquí es iterar sobre una lista de cinco funciones:

  • dired-find-alternativo-archivo
  • dired-find-file
  • -find-file dired-other-window
  • dired -mouse-find-file-other-window
  • dired-vista-archivo

que son funciones dired, prevé la apertura de un archivo. A cada una de estas funciones agregamos una pequeña cantidad de código en una técnica llamada advising: lo que hace (ad-add-advice...) es establecer la variable openwith-mode en t cada vez que se invoca una de estas cinco funciones. Fuera de la llamada de función, la variable permanece establecida en nil.

Esto tiene el efecto de que cada vez que utiliza una de las funciones de dired para abrir un archivo, la función de openwith-mode que es responsable de llamar a aplicaciones externas ve la variable establecida en t y rápidamente intenta abrir una aplicación externa si sabe uno La razón por la que tenemos que pasar por tales aros es que también se llama a la misma función de abrir-modo cada vez que abre un archivo de imagen usando C-x C-f - así es como se implementa openwith-mode.

(Nota: lamentablemente no podemos simplemente usar el modo principal actual como un interruptor porque este será el modo principal de un nuevo búfer que se habrá creado para que se abra el archivo. Siempre es fundamental-mode).

Finalmente, las últimas tres líneas son simplemente copiar & pegar desde la definición de modo menor que comentamos anteriormente. Dicen que la función que he estado mencionando mucho y que es responsable de llamar a las aplicaciones externas, llamada open-with-filehandler, es un denominado manejador de archivos. Realmente no hace nada especial para el acceso real al archivo, por lo tanto estamos configurando safe-magic para esa función a t. Además, declaramos que la operación insert-file-contents es manejada por nuestra función de una manera no trivial. (Consulte here para obtener más información sobre estas propiedades.)

Y, por último, instalamos el controlador de archivos.


Importante: El Documenation modo OpenWith recomienda que coloque las dos líneas siguientes en su archivo .emacs:

(require 'openwith) 
(openwith-mode t) 

Ahora que no hay minor-mode openwith-mode más (después de comentamos su definición), asegúrese de eliminar la segunda línea, por ej.comentando que demasiado:

;; (openwith-mode t) 

Después de reiniciar Emacs, si abre un archivo de imagen con Dired, se debe abrir en una aplicación externa; si lo abre a través de C-x C-f, se insertará en un búfer.

+0

upvoted, pero no he explicado por qué se necesitaba para comentar la definición del modo (o modificar directamente la biblioteca a todos - 'eval-after-load' sería un enfoque más normal para agregar ese código adicional). – phils

+0

@phils buen punto: solo hice un pequeño comentario al respecto, pero no estaba muy claro: la forma en que openwith-mode está diseñado, está destinado a ser o en * globalmente *: agrega un manejador de archivos global y cuando el modo está activado, ese manejador de archivos busca aplicaciones externas, si está desactivado, no hace nada. – Thomas

+0

Pero, ¿no obtendrías el mismo resultado al usar 'eval-after-load' para envolver' (fmakunbound 'openwith-mode) 'y el resto de tu código, y no tocar realmente la biblioteca original? – phils