2012-06-27 15 views
6

Desidero configurare emacs per utilizzare le applicazioni esterne quando apro file di immagini dalla modalità dired.emacs dired e openwith

D'altra parte, voglio anche utilizzare le immagini in linea nei buffer emacs.

aprire file in applicazioni esterne utilizzo openwith.el pacchetto http://www.emacswiki.org/emacs/OpenWith

Il problema con il modo minore openwith è che è globale e quando viene attivata da un-mode-hook dired

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

funziona ovunque e tutte le immagini in linea nei buffer emacs vengono aperte in applicazioni esterne.

Ho provato a cambiare

:global t 

a

:global nil 

nel openwith.el, ma in qualche modo disabilita openwith modalità completamente.

Quindi, la mia domanda è: come dire ad emacs di usare openwith solo la modalità minore con buffer dired e non altrove?

Grazie.

risposta

0

Un modo potrebbe essere quello di impostare emacsclient come programma preferito per i tipi di file che ti piace in openwith-associations in openwith.el e iniziare a utilizzare emacsclient.

È possibile avviare ogni volta una nuova sessione di emacs ma questo sembra più brutto del suggerimento precedente.

4

Il modo in cui openwith-mode funziona è un po 'particolare: presuppone davvero che lo si usi globalmente o per niente. Quello che vuoi qui, tuttavia, è usarlo localmente, cioè solo da un buffer diretto.

Questo non può essere raggiunto molto facilmente, ma qui è un modo.

Aprire il file sorgente di openwith-mode, openwith.el. Quindi scorrere fino in fondo fino ad arrivare alla definizione della modalità secondaria reale. Poi commento fuori tale definizione posizionando una virgola all'inizio di ogni riga:

;;;###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)))) 

Quindi sotto questo codice (ma prima (provide 'openwith)), inserire il seguente codice:

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

Questo codice fa poche cose.

Innanzitutto, definisce una variabile denominata openwith-mode. Questa variabile viene utilizzata all'interno di una delle funzioni di openwith-mode che decide se utilizzare un'applicazione esterna o meno. Normalmente, una variabile del genere viene fornita automaticamente da Emacs quando si definisce una modalità secondaria, tuttavia poiché abbiamo appena commentato la definizione della modalità secondaria precedente, reintroduciamo esplicitamente questa variabile qui.

Lo scopo della variabile è di funzionare come una sorta di switch attraverso il quale possiamo controllare se un file di immagine debba essere in linea o passato a un visualizzatore esterno.

Successivamente abbiamo l'espressione (mapc ...). Quello che facciamo qui è un'iterazione su un elenco di cinque funzioni:

  • dired-trovare-alternano file
  • dired-find-file di
  • -find-file di dired-altro-finestra
  • dired -mouse-trovare-file-other-window
  • dired-view-file di

che sono funzioni dired prevede per l'apertura di un file. A ciascuna di queste funzioni viene aggiunta una piccola quantità di codice in una tecnica denominata advising: ciò che (ad-add-advice...) fa è impostare la variabile openwith-mode su t ogni volta che viene chiamata una di queste cinque funzioni. Al di fuori della chiamata di funzione, la variabile rimane impostata su nil.

Questo ha l'effetto che ogni volta che si utilizza una delle funzioni di dired per aprire un file, la funzione openwith-mode responsabile della chiamata alle applicazioni esterne vede la variabile impostata su t e tenta prontamente di aprire un'applicazione esterna se questa lo sa. Il motivo per cui dobbiamo saltare questi cerchi è che la stessa funzione openwith viene anche chiamata ogni volta che apri un file immagine usando C-x C-f - questo è il modo in cui è implementato openwith-mode.

(NB: sfortunatamente non è possibile utilizzare l'attuale modalità principale come opzione perché questa sarà la modalità principale di un nuovo buffer che sarà stato creato già per l'apertura del file. È sempre fundamental-mode.)

Infine, le ultime tre righe sono solo copia & incolla dalla definizione in modalità secondaria che abbiamo commentato prima. Dicono che la funzione che ho già menzionato molto e che è responsabile per la chiamata di applicazioni esterne - chiamate open-with-filehandler - è un cosiddetto gestore di file. In realtà non fa nulla di speciale per l'effettivo accesso al file, quindi stiamo impostando safe-magic per quella funzione su t. Inoltre, dichiariamo che l'operazione insert-file-contents è gestita dalla nostra funzione in modo non banale. (Vedere here per ulteriori informazioni su queste proprietà.)

E all'ultimo momento, effettivamente installiamo il gestore di file.


Importante: Il documenation openwith modalità consiglia di inserire le seguenti due righe nel file .emacs:

(require 'openwith) 
(openwith-mode t) 

Ora che non c'è minor-mode openwith-mode più (dopo abbiamo commentato la sua definizione), per favore assicurati di rimuovere la seconda riga, ad escommentando fuori troppo:

;; (openwith-mode t) 

Dopo riavviare Emacs, se si apre un file immagine con dired, si dovrebbe aprire in un'applicazione esterna; se lo apri tramite C-x C-f verrà inserito in un buffer.

+0

upvoted, ma non hanno spiegato perché avevi bisogno di commentare la definizione di modalità (o modificare direttamente la biblioteca a tutti - 'eval-dopo-load' sarebbe un approccio più normale all'aggiunta di quel codice aggiuntivo). – phils

+0

@phils buon punto - Ho solo fatto un piccolo commento a riguardo, ma non era molto chiaro: il modo in cui openwith-mode è progettato, è pensato per essere o su * globalmente *: aggiunge un gestore di file globale e quando la modalità è attiva, quel gestore di file controlla le applicazioni esterne, se è spento, non fa nulla. – Thomas

+0

Ma non otterresti lo stesso risultato usando 'eval-after-load' per eseguire il wrap' (fmakunbound 'openwith-mode) 'e il resto del codice, e in realtà non toccare la libreria originale? – phils

Problemi correlati