2016-04-17 10 views
1

Ich benutze Emacs mit bösen Modus, ich möchte <leader>tt auf die Funktion projectile-dired zuordnen, aber wenn ein Dired-Puffer angezeigt wird, dann sollte es auf die evil-delete-buffer gemappt werden, also im Wesentlichen eine Karte zu einer Toggle-Funktion erstellen.In Emacs wie erstellt man eine Zuordnung zu einer Funktion von einer anderen Funktion zurückgegeben?

Nach den Grundlagen der Emacs Lisp Lernen kam ich mit dieser Lösung:

(defun toggle-projectile-dired() 
    "Toggles projectile-dired buffer." 
    (interactive) 
    (or 
    (when (derived-mode-p 'dired-mode) 
    (evil-delete-buffer (current-buffer))) 
    (projectile-dired))) 

;; This is how the mapping is done 
(evil-leader/set-key "tt" 'toggle-projectile-dired) 

Aber was ich mit dieser Lösung tat, war eine Karte zu einer Funktion, die am Ende auf eine andere Funktion aufruft, zu erstellen.

Während meine Lösung funktioniert (und mir geht es gut), was ich nicht tun konnte, war die Funktion zurück zu rufen (anstatt es zu nennen, wie ich), wie solche Ansatz geschrieben werden sollte?

Oder mit anderen Worten, wie man einen Funktionsnamen zurückgibt und diese Zuordnung die zurückgebende Funktion aufrufen ?.

PD: Diese Frage ist nur um etwas Elisp zu lernen. Vielen Dank!

EDIT:

Hier einige Pseudo-Code (JavaScript) von dem, was ich erreichen möchte:

function toggleProjectileDired() { 
    if (derivedModeP == 'dired-mode') { 
    // We're in dired buffer 
    return 'evilDeleteBuffer'; 
    } else { 
    return 'projectileDired'; 
    } 
} 

evilLeaderSetKey("tt", toggleProjectileDired()); 

Meine Lösung in Pseudo-Code ist:

function toggleProjectileDired() { 
    if (derivedModeP == 'dired-mode') { 
    // We're in dired buffer 
    evilDeleteBuffer(); 
    } else { 
    projectileDired(); 
    } 
} 

evilLeaderSetKey("tt", toggleProjectileDired); 

Wie Sie kann man sehen, gibt man den Funktionsnamen zurück, der aufgerufen werden soll, während der andere die Funktion aufruft. Wie gebe ich einen Funktionsnamen zurück, der in elisp aufgerufen werden soll?

+0

Bitte fügen Sie einen Pseudo-Code hinzu, der ein Beispiel zeigt, was Sie zu tun hoffen, weil Ihre Frage nicht eindeutig ist. – phils

+0

Die Frage ist unklar. Außerdem gibt 'when' immer' nil' zurück (es sei denn, es verursacht einen nicht lokalen Exit und kehrt nicht zurück), so dass es in 'or' umgebrochen wird, ist nutzlos. Wenn Sie 'projectile-dired' nicht ausführen wollen, wenn' evil-delete-buffer' nicht-'nil' zurückgibt, verwenden Sie' und' anstelle von 'when' (oder machen Sie etwas anderes, das denselben Effekt hat). – Drew

+0

@phils done:) ..... @Drew danke Ich bin ein Neuling in Emacs, ich würde eine 'if' Anweisung verwenden, wenn das nicht funktionieren würde, aber es hat funktioniert, obwohl ich das geändert bekommen werde, danke. –

Antwort

1

(Caveat. Ich weiß nicht evil verwenden, und bin nicht vertraut mit ihren benutzerdefinierten Keybinding Funktionen)

Der kanonische Ansatz einen Schlüssel zu tun, eine Sache in dired-mode und eine andere Sache, an anderer Stelle eine zu definieren, ist verbindlich in Dired Keymap und eine andere Bindung in der globalen Keymap (oder was auch immer angemessen ist). Ich würde empfehlen, dass Sie versuchen, diesen Ansatz in den meisten Fällen zu befolgen, weil es viel einfacher ist, zu sehen, was passiert.

Es gibt jedoch eine Möglichkeit zu tun, wonach Sie fragen. Diese Seiten zeigen einige Variationen auf dem Ansatz:

Im Grunde verwenden Sie die :filter Einrichtung von Menüpunkten (nb Menüs sind tatsächlich Phantasie keymaps in Emacs) um den Befehl zur Laufzeit zu bestimmen. Beachten Sie, dass, wenn die Filterfunktion nil zurückgibt, Emacs es so behandelt, als ob keine Bindung in dieser Tastaturbelegung existiert, und weiterhin in den verbleibenden Tastaturbelegungen nach einer Bindung sucht; Diese Funktion erleichtert Bindungen, die nur bedingt aktiv sind.

Eine nicht evil Version Ihres Beispiel könnte wie folgt aussehen:

(define-key global-map (kbd "<f6>") 
    `(menu-item "" projectile-dired 
       :filter ,(lambda (default) 
         (if (derived-mode-p 'dired-mode) 
          'evil-delete-buffer 
          default)))) 

Auch dies wäre mehr üblich sein:

(global-set-key (kbd "<f6>") 'projectile-dired) 
(eval-after-load "dired" 
    '(define-key dired-mode-map (kbd "<f6>") 'evil-delete-buffer)) 

FWIW, ich glaube tatsächlich, den allgemeinen Ansatz Sie begann mit ist wahrscheinlich die beste in diesem Fall. Wenn die Eingabe von KEY in diesem Fenster immer auf dired umgeschaltet werden soll, dann erscheint die Bindung an einen Befehl toggle-dired als die selbsterklärendste Implementierung.