Wie kann man Code-Faltungseffekte in Emacs erzielen?

123

Was ist der beste Weg, um so etwas wie Code-Faltung oder die Art des Radfahrens zu erreichen, die der Org-Modus verwendet? Was wäre die beste Lösung in elisp, um diese Art von Verhalten zu erzeugen?

EDIT: Es tut mir leid, dass ich nicht klar war. Ich möchte etwas in elisp programmieren, das der Code-Faltung sehr ähnlich ist oder dem Org-Modus mit der Hierarchie, die erweitert werden kann, am ähnlichsten ist. Ich frage mich, wie ich diesen Effekt am besten erreichen kann. Ich denke, ich habe gehört, dass Emacs-Overlays eine gute Lösung sind, aber ich weiß es nicht.

Was das Falten angeht, verwende ich nur das eingebaute Set-Selective-Display

EDIT NUMBER 2:

Vielen Dank für die Antworten, aber ich glaube, ich stelle die falsche Frage. Lassen Sie mich versuchen, klarer zu machen, was ich versuche. Ich möchte Folgendes erstellen

Wenn Sie Ihren Punkt auf eine Funktion setzen und diese elisp-Funktion aufrufen, wird die Funktionsdefinition von jedem Ort aus platziert (ich denke nur daran, find-tag dafür zu verwenden) und im aktuellen Puffer entfaltet. Die Idee ist, wenn Sie zu einem anderen Puffer springen müssen, um die Funktionsdefinition zu lesen. Ich denke, es ist ein Kontextwechsel zu einer anderen Datei. Ich möchte also, dass es sich wie das Falten von Code verhält, nur dass Code außerhalb des Puffers eingezogen wird. Dies stellt einige Probleme dar, da der Code nicht akut in den Puffer eingefügt werden kann. Wenn jemand ihn speichert, wird der eingezogene Code gespeichert. Ich frage mich also, ob es eine Möglichkeit gibt, einen Bereich innerhalb eines Puffers zu erstellen, der ebenfalls nicht Teil des Puffers ist. Ich denke das macht Sinn.

Jacob
quelle
Sie suchen nach etwas, das beim Aufrufen mit point in einem Funktionsaufruf zur Funktionsdefinition springt? Wenn Sie Hilfe zu einer Elisp-Funktion erhalten, können Sie zum Elisp-Code springen? Ich glaube nicht, dass Sie dies ohne ein Konzept von "The project" tun können. Wie würden Sie beispielsweise wissen, zu welcher "Swap" -Funktion Sie springen möchten?
Brian Postow
1
Siehe auch: stackoverflow.com/questions/382781/…, wo die selektive Anzeige für einige faltähnliche Effekte etwas optimiert wird.
Michael Paulukonis
Ich empfehle Ihnen, Ihre zu entfernen EDIT NB 2und eine neue Frage zu stellen.
Stefan

Antworten:

151

Das Falten ist bei Emacs im Allgemeinen nicht erforderlich, da es Tools enthält, die die Aktionen, die beim Falten von Code manuell ausgeführt werden, explizit implementieren.

Die meisten Menschen haben guten Erfolg mit einfachen inkrementellen Suchen. Siehe "foo" irgendwo erwähnt? Geben Sie ein C-sfoo, suchen Sie die Definition, drücken Sie die Eingabetaste, lesen Sie sie und drücken Sie dann, um C-x C-xzu Ihrem ursprünglichen Standort zurückzukehren. Einfach und sehr nützlich.

Die meisten Modi unterstützen imenu . M-ximenuHiermit können Sie nach Namen zu einer Funktionsdefinition (usw.) springen. Sie können es auch an einen Mausklick binden, um ein Funktionsmenü aufzurufen (oder es der Menüleiste hinzufügen; weitere Informationen finden Sie auf der Info-Seite). Es liefert Daten für welchen Funktionsmodus, mit denen Sie sehen können, in welcher Funktion Sie sich derzeit in der Modellreihe befinden. (Warum sind deine Funktionen so lang?)

Es gibt auch eine Geschwindigkeitsleiste , die die IMENU-Informationen (und andere Dinge) grafisch anzeigt.

Wenn Sie sich einen Überblick über Ihre Datei M-xoccurverschaffen möchten, versuchen Sie es mit ". Bei einem regulären Ausdruck wird mit jeder Übereinstimmung im aktuellen Puffer ein neuer Puffer erstellt. Sie können nach" (defun "suchen, um einen Überblick über die Funktionen der aktuellen Datei zu erhalten Wenn Sie auf das Ergebnis klicken, gelangen Sie an diese Position in der Datei.

Überlegen Sie sich also, was Sie wirklich erreichen möchten, und Emacs setzt dies wahrscheinlich um. Kämpfe nicht mit unvollkommenen Werkzeugen, mit denen du Dinge ständig falten und entfalten kannst.

Jrockway
quelle
13
Vim bietet all diese Funktionen auch in der einen oder anderen Form an, aber ich finde die Code-Faltfunktion immer noch von unschätzbarem Wert.
Intuitiert
115
Ich habe für den ersten Satz herabgestimmt ("Falten ist bei Emacs im Allgemeinen nicht erforderlich, da ..."). Ich verwende ständig einfaches Falten (basierend auf der Einrückungsstufe), um die Struktur von unbekanntem Code zu scannen.
Simon Michael
4
Frau o ist die Abkürzung für Mx auftreten
Joshua Olson
3
Ich habe hochgestimmt, weil viele nützliche Verknüpfungen in der Antwort vorhanden sind, aber auch @SimonMichael-Kommentare hochgestimmt, weil das Falten / Entfalten manchmal immer noch nützlich sein kann!
Adrien Coquio
56
Die Antwort war gut durchdacht und sehr informativ. Das OP fragte jedoch, wie Code gefaltet werden soll. Das OP fragte nicht nach der bevorzugten Methode aller, um das Falten von Code zu vermeiden. Down stimmte ab.
wkschwartz
104

Hide-Show-Modus ( hs-minor-mode) mit Standard-Tastenkombination C-c @ C-M-hzum Auslösen des Faltens ( hs-hide-all)

dmckee --- Ex-Moderator Kätzchen
quelle
12
Das funktioniert gut. Und mit dem Bösen-Modus, wird dies durch die normalen vim Befehle ausgelöst wird: zR, zM, zo, zc.
Justin M. Keyes
39

Ein anderer Weg, um die Katze zu häuten:

Dafür benötigen Sie kein Paket oder eine zusätzliche Konfiguration. Gehen Sie einfach zu einer beliebigen Quelldatei und geben Sie ein

M-1 Cx $ und Magie passiert!

Wie immer ist es weiße Magie: Cx $ bringt Ihren Code zurück.

Wir können das Hilfesystem von Emacs verwenden, um herauszufinden, was los ist: Ch k Cx $ sagt uns, dass die obige Tastenkombination set-selektive Anzeige aufruft , eine Funktion, die ein numerisches Argument akzeptiert (das Präfix M-1 übergibt 1 als Wert dieses Arguments) und setzt, nicht überraschend, die Variable Selective-Display auf den Wert dieses Arguments.

von kleinen Emacs Zauberer Blog

Nur der Vollständigkeit halber : M-3 Cx $ würde tiefer verschachtelten Code anzeigen und so weiter.

FWIW Ich habe heute einen winzigen Helfer gemacht, der auf etw basiert. hier gefunden , so dass F5 die Code-Faltung basierend auf der aktuellen Cursorposition umschaltet:

(global-set-key (kbd "<f5>") 'set-selective-display-dlw)

(defun set-selective-display-dlw (&optional level)
"Fold text indented same of more than the cursor.
If level is set, set the indent level to LEVEL.
If 'selective-display' is already set to LEVEL, clicking
F5 again will unset 'selective-display' by setting it to 0."
  (interactive "P")
  (if (eq selective-display (1+ (current-column)))
      (set-selective-display 0)
    (set-selective-display (or level (1+ (current-column))))))
einSelbst
quelle
22

Ich verwende den Gliederungsminderheitsmodus, um meinen Python-Code zu falten. Anstatt {{{und}}} wie im Faltmodus platzieren zu müssen, wird dort verwendet, wo der Block definiert ist.

http://www.gnu.org/software/emacs/manual/html_node/emacs/Outline-Mode.html http://www.emacswiki.org/emacs/OutlineMinorMode

Ich bin mir ziemlich sicher, dass es mit Emacs kommt. Ich füge dies dann meinen .emacs hinzu

;;======= Code folding =======
(add-hook 'python-mode-hook 'my-python-outline-hook)
; this gets called by outline to deteremine the level. Just use the length of the whitespace
(defun py-outline-level ()
  (let (buffer-invisibility-spec)
    (save-excursion
      (skip-chars-forward "    ")
      (current-column))))
; this get called after python mode is enabled
(defun my-python-outline-hook ()
  ; outline uses this regexp to find headers. I match lines with no indent and indented "class"
  ; and "def" lines.
  (setq outline-regexp "[^ \t]\\|[ \t]*\\(def\\|class\\) ")
  ; enable our level computation
  (setq outline-level 'py-outline-level)
  ; do not use their \C-c@ prefix, too hard to type. Note this overides some bindings.
  (setq outline-minor-mode-prefix "\C-t")
  ; turn on outline mode
  (outline-minor-mode t)
  ; initially hide all but the headers
  ;(hide-body)
  ; make paren matches visible
  (show-paren-mode 1)
)
Nikwin
quelle
8
Es sieht so aus, als ob outline-modePython in Emacs 24 sofort einsatzbereit ist - keine benutzerdefinierten outline-levelFunktionen erforderlich . Dies ist alles, was ich zu meinem hinzufügen musste user.el:(add-hook 'python-mode-hook 'outline-minor-mode)
Sense
1
Oh, und Sie möchten auf jeden Fall überschreiben outline-minor-mode-prefix- die Standard-Tastenkombinationen sind schrecklich - ich benutze(setq outline-minor-mode-prefix (kbd "C-;"))
Sense
13

Sie können Code auch falten, indem Sie CEDET mit folgendem Code in der Init-Datei verwenden:

(global-semantic-folding-mode t)

Nach der Auswertung dieses Codes wird das kleine Dreieck im Randbereich angezeigt, sodass Sie den Code damit falten und entfalten können. Diese Methode ist präziser, da sie syntaktische Informationen verwendet, die aus dem Quellcode extrahiert wurden

Alex Ott
quelle
1
Wenn Sie auf einen Fehler stoßen,
werfen Sie
9

Der hs-Moll-Modus funktioniert wunderbar.

Es funktioniert noch schöner, wenn es mit Fold-Dwim kombiniert wird (mach was ich meine). Dann gibt es Fold-Dwim-Org, das org-Modus-ähnliche Tastenkombinationen für das Falten von Code bietet! Beide können über Marmelade installiert werden (und ich denke elpa).

Jones
quelle
5

vimish-fold ist auch eine schöne und einfache Lösung.

https://github.com/mrkkrp/vimish-fold .

Von der Homepage:

Dies ist ein Paket zum Falten von Text wie in Vim. Es hat die folgenden Funktionen:

  • Faltung aktiver Regionen;
  • gutes visuelles Feedback: Es ist offensichtlich, welcher Teil des Textes gefaltet ist.
  • Standardmäßig Persistenz: Wenn Sie eine Datei schließen, verschwinden Ihre Falten nicht.
  • Die Persistenz lässt sich gut skalieren. Sie können Hunderte von Dateien mit vielen Falten ohne nachteilige Auswirkungen bearbeiten.
  • es bricht keine Einkerbung oder so etwas;
  • Falten können sehr leicht vom gefalteten Zustand in den entfalteten Zustand und zurück umgeschaltet werden;
  • schnelle Navigation zwischen vorhandenen Falten;
  • Sie können Falten mit der Maus entfalten (gut für Anfänger und nicht nur für sie);
  • Für Fans von Avy-Paketen: Mit Avy können Sie Text mit einer minimalen Anzahl von Tastenanschlägen falten!

Mit dem exzellenten use-packageinstalliere und aktiviere ich es mit diesem Snippet in meiner Konfiguration:

(use-package vimish-fold
  :ensure t
  :config (vimish-fold-global-mode t))
Horus
quelle
3

Ich bin überrascht, dass niemand von einer Verengung und Erweiterung sprach. Es ist super toll, es kommt auch mit Emacs gebündelt. Wählen Sie einfach den Code aus, auf den Sie sich konzentrieren möchten, und drücken Sie C-x n n, um zum Vollbildmodus zurückzukehren C-x n w. Ich bevorzuge es immer, integrierte Emacs-Funktionen zu verwenden, als meinen Benutzerbereich mit einem anderen Paket zu überladen. Wenn Emacs dies mit integrierten Funktionen tun können, ziehe ich das einem Paket von Drittanbietern vor, aber das bin nur ich, bedeutet oder impliziert nichts anderes, als dass ich einfache Dinge gegenüber komplexen langen Konfigurationen mag.

Kirk Walla
quelle
2

emacs wird mit dem hs-minor-Modus geliefert, der das Falten von Code zwischen ausgeglichenen Ausdrücken vereinfacht. http://www.emacswiki.org/emacs/HideShow

Eunikorn
quelle
2

Ich glaube, dass Ihr Vergleich Ihres "Projekts" mit dem Falten nicht ganz gut ist, da es beim Falten darum geht, das Erscheinungsbild zu ändern, während der Pufferinhalt (der Text) intakt bleibt. Ihr Projekt würde beinhalten, zusätzlichen Text anzuzeigen, während der Pufferinhalt intakt bleibt, AFAIU. So. Es kann nicht als Komposition aus Einfügen und Falten von Text implementiert werden (dann würde der Pufferinhalt geändert).

Aber vielleicht ist es tatsächlich mit dem gleichen Mechanismus möglich, mit dem gefaltet wird - "Overlays" ... Berücksichtigen Sie die Overlay-Eigenschaften "Vor-String" und "Nach-String" . Vielleicht könnten Sie Ihre Funktionsdefinitionen in diese Zeichenfolgen einfügen, die zu einer Überlagerung mit der Länge Null am Punkt gehören. Sehen Sie sich die Funktion " Gliederungsflaggenregion" an, um zu sehen, wie Überlagerungen im Gliederungsmodus verwendet werden.

imz - Ivan Zakharyaschev
quelle
2

Wenn Sie verwenden hs-minor-mode, ist es möglicherweise eine gute Idee, auch eine bequemere Verknüpfung festzulegen, z.

(eval-after-load 'hideshow
 '(progn
   (global-set-key (kbd "C-+") 'hs-toggle-hiding)))
Quazgar
quelle
0

Mit Inspiration von einSelbsts Antwort :

(Beratung-Hinzufügen 'Set-selektive-Anzeige
            : Filterargumente (Lambda (Args)
                           (wenn (oder (Auto Argumente) selektive Anzeige)
                               args
                             (Liste (1+ (aktuelle Spalte))))
            '((Name. Set-Selective-Display-From-Cursor-Spalte)))

Voila, C-x $wurde plötzlich nützlich , auch ohne C-unoch M-4Geschäft.

DomQ
quelle
0

Wenn Sie JavaScript verwenden und verwenden js2-mode.el, können Sie:

C-c C-f: schalten Sie alle ein / aus

C-c C-e: Element ausblenden

C-c C-s: Element anzeigen

Roboli
quelle