Come ottenere effetti di piegatura del codice in Emacs?


123

Qual è il modo migliore per ottenere qualcosa come la piegatura del codice o il tipo di ciclismo utilizzato dalla modalità organizzazione. Quale sarebbe la migliore soluzione in elisp per creare questo tipo di comportamento?

EDIT: mi dispiace di non essere stato chiaro. Voglio programmare qualcosa in elisp che faccia cose molto simili alla piegatura del codice, o in realtà più simili alla modalità org con la gerarchia che può essere espansa. Mi chiedo il modo migliore per ottenere questo effetto. Penso di aver sentito che gli overlay di emacs sono una buona soluzione, ma non lo so.

Per quanto riguarda la piegatura, utilizzo solo il display selettivo del set incorporato

MODIFICA NUMERO 2:

Grazie per le risposte, ma penso di fare la domanda sbagliata, quindi lasciami cercare di essere più chiaro su ciò che sto cercando di fare. Vorrei creare quanto segue

Quando metti il ​​tuo punto su una funzione e chiami questa funzione elisp, inserirà la definizione della funzione ovunque si trovi (sto pensando di usare solo find-tag per questo) e la spiegherà nel buffer corrente. L'idea è che se devi passare a un buffer diverso per leggere la definizione della funzione, mi sento come se fosse un cambio di contesto su un altro file. Quindi vorrei che si comportasse come il piegamento del codice solo che estrae il codice esterno dal buffer. Questo presenta alcuni problemi in quanto non può incollare in modo acuto il codice nel buffer o se qualcuno lo salva salverà il codice inserito. Quindi mi chiedo se esiste un modo per creare un'area all'interno di un buffer che non fa parte del buffer. Penso che abbia senso.


Stai cercando qualcosa che quando lo chiami con punto in una funzione CALL salta alla definizione della funzione? un po 'come ottenere aiuto su una funzione elisp ti permetterà di saltare al codice elisp? Non credo che tu possa farlo senza un concetto di "Il progetto" Ad esempio, come potresti sapere a quale funzione di "scambio" vuoi passare?
Brian Postow

1
Vedi anche: stackoverflow.com/questions/382781/… dove la visualizzazione selettiva è leggermente ottimizzata per alcuni effetti simili a pieghe.
Michael Paulukonis

Ti consiglio di rimuovere il tuo EDIT NB 2e di fare una nuova domanda.
Stefan l'

Risposte:


151

La piegatura non è generalmente necessaria con emacs, poiché ha strumenti che implementano esplicitamente le azioni che le persone fanno manualmente quando piegano il codice.

La maggior parte delle persone ha un buon successo con semplici ricerche incrementali. Vedi "foo" menzionato da qualche parte? Digita C-sfoo, trova la definizione, premi Invio, leggila, quindi premi C-x C-xper tornare al punto in cui ti trovavi. Semplice e molto utile.

La maggior parte delle modalità supporta imenu . M-ximenuti permetterà di saltare a una definizione di funzione (ecc.) per nome. Puoi anche associarlo a un clic del mouse per ottenere un menu di funzioni (o aggiungerlo alla barra dei menu; vedere la pagina Informazioni per maggiori dettagli). Fornisce dati per quale modalità di funzione, che ti permetterà di vedere in quale funzione ti trovi attualmente all'interno della modeline. (Perché le tue funzioni sono così lunghe, però?)

C'è anche speedbar , che visualizza le informazioni imenu (e altre cose) graficamente.

Se vuoi avere una panoramica del tuo file, prova M-xoccur". Data una regex, creerà un nuovo buffer con ogni corrispondenza nel buffer corrente. Puoi cercare" (defun "per avere una panoramica delle funzioni del file corrente Facendo clic sul risultato ti sposterai in quella posizione nel file.

Quindi, comunque, pensa a ciò che vuoi veramente ottenere, ed Emacs probabilmente lo implementa. Non combattere con strumenti imperfetti che ti fanno piegare e aprire le cose costantemente.


13
Vim fornisce anche tutte queste funzionalità in una forma o nell'altra, ma trovo comunque inestimabile la sua funzionalità di piegatura del codice.
intuito il

115
Ho votato contro la prima frase ("Il ripiegamento generalmente non è necessario con emacs, come ..."). Uso costantemente la piegatura semplice (basata sul livello di rientro) per scansionare la struttura di un codice sconosciuto.
Simon Michael

4
Ms o è la scorciatoia per Mx verificarsi
Joshua Olson

3
Ho votato in alto perché molte scorciatoie utili nella risposta, ma anche @SimonMichael hanno votato in alto perché piegare / aprire potrebbe ancora essere utile a volte!
Adrien Coquio

56
La risposta è stata ben congegnata e molto istruttiva. Tuttavia, l'OP ha chiesto come eseguire il ripiegamento del codice. L'OP non ha chiesto quale fosse il modo preferito da tutti per evitare il ripiegamento del codice. Ho votato verso il basso.
wkschwartz

104

modalità hide-show ( hs-minor-mode) con combinazione C-c @ C-M-hdi tasti predefinita per attivare la piegatura ( hs-hide-all)


12
Funziona bene. E con il male-mode, questo è innescato da normali comandi di vim: zR, zM, zo, zc.
Justin M. Keyes

39

Un altro modo per scuoiare il gatto:

Come accade, non hai bisogno di alcun pacchetto o configurazione aggiuntiva per questo. Vai a qualsiasi file sorgente, digita

M-1 Cx $ e la magia accade!

Come al solito, è magia bianca: Cx $ riporterà il tuo codice.

Possiamo usare il sistema di aiuto di Emacs per scoprire cosa sta succedendo: Ch k Cx $ ci dice che la combinazione di tasti sopra sta chiamando set-selettiva-display , una funzione che accetta un argomento numerico (il prefisso M-1 passa 1 come valore di tale argomento) e, non sorprende, imposta la variabile di visualizzazione selettiva sul valore di tale argomento.

dal blog di maghi di emacs minore

Solo per completezza: M-3 Cx $ mostrerebbe un codice annidato più profondo e così via.

FWIW Oggi ho creato un piccolo aiutante basato su smth. trovato qui in modo che F5 attivi il ripiegamento del codice in base alla posizione corrente del cursore:

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

22

Uso la modalità minore contorno per piegare il mio codice Python. Invece di dover posizionare {{{e}}} come nella modalità pieghevole, utilizza dove è definito il blocco.

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

Sono abbastanza sicuro che venga fornito con emacs. Quindi aggiungo questo al mio .emacs

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

8
sembra che outline-modesupporti Python out-of-the-box in emacs 24 - non c'è bisogno di outline-levelfunzioni personalizzate . Questo è tutto quello che dovevo aggiungere al mio user.el:(add-hook 'python-mode-hook 'outline-minor-mode)
scytale

1
oh e tu sicuramente vuoi sovrascrivere outline-minor-mode-prefix- le combinazioni di tasti predefinite sono orribili - io uso(setq outline-minor-mode-prefix (kbd "C-;"))
scytale

13

Puoi anche ottenere la piegatura del codice usando CEDET con il seguente codice nel file init:

(global-semantic-folding-mode t)

Dopo la valutazione di questo codice, il piccolo triangolo apparirà nell'area marginale, quindi potrai piegare e aprire il codice usandolo. Questo metodo è più preciso, poiché utilizza informazioni sintattiche, estratte dal codice sorgente


1
se di fronte a qualche bug, avere uno sguardo su questa domanda: stackoverflow.com/questions/15307113/...
AdrieanKhisbe

9

hs-minor-mode funziona magnificamente.

Funziona ancora più magnificamente se abbinato a fold-dwim (fai quello che intendo). Poi c'è fold-dwim-org, che fornisce modalità org come le associazioni di tasti per la piegatura del codice! Entrambi possono essere installati tramite marmellata (e credo elpa).



5

vimish-fold è anche una bella e facile soluzione.

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

Dalla homepage:

Questo è un pacchetto per eseguire la piegatura del testo come in Vim. Ha le seguenti caratteristiche:

  • ripiegamento delle regioni attive;
  • buon feedback visivo: è ovvio quale parte del testo è piegata;
  • persistenza di default: quando chiudi il file le tue pieghe non scompaiono;
  • la persistenza scala bene, puoi lavorare su centinaia di file con molte pieghe senza effetti negativi;
  • non rompe il rientro o qualcosa del genere;
  • le pieghe possono essere alternate dallo stato piegato allo stato aperto e viceversa molto facilmente;
  • navigazione rapida tra pieghe esistenti;
  • puoi usare il mouse per aprire le pieghe (buono per i principianti e non solo per loro);
  • per i fan del pacchetto avy: puoi usare avy per piegare il testo con il minimo numero di battute!

Usando l'eccellente use-packagelo installo e lo attivo usando questo snippet nella mia configurazione:

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

3

Sono sorpreso che nessuno abbia menzionato il restringimento-allargamento. È super fantastico, viene fornito anche in bundle con emacs. Seleziona semplicemente il codice su cui vuoi concentrarti e premi C-x n n, per tornare alla modalità di visualizzazione completa basta farlo C-x n w. Preferisco sempre utilizzare la funzionalità di emacs incorporata piuttosto che ingombrare il mio spazio utente con un altro pacchetto. Se emacs può farlo con funzionalità integrate, lo preferirò a un pacchetto di terze parti, ma sono solo io, non significa o implica nient'altro oltre al fatto che mi piacciono le cose semplici su configurazioni lunghe complesse.



2

Credo che il tuo confronto tra il tuo "progetto" e il pieghevole non sia abbastanza buono, perché il piegamento riguarda la modifica dell'aspetto mantenendo intatto il contenuto del buffer (il testo). Il tuo progetto comporterebbe la visualizzazione di testo extra mantenendo intatto il contenuto del buffer, AFAIU. Così. non è implementabile come composizione di inserimento di testo e piegatura (quindi, il contenuto del buffer verrebbe modificato).

Ma forse, è davvero possibile con lo stesso meccanismo con cui si esegue il ripiegamento - "overlay" ... Considera le proprietà di overlay "before-string" e "after-string" ; forse, potresti inserire le tue definizioni di funzione in queste stringhe che appartengono a una sovrapposizione di lunghezza zero nel punto. Guarda la funzione outline-flag-region per vedere come vengono utilizzate le sovrapposizioni nella modalità outline.


2

Se lo usi hs-minor-mode, potrebbe essere una buona idea impostare anche una scorciatoia più comoda, ad esempio:

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

0

Con l'ispirazione dalla risposta di einSelbst :

(consiglio-aggiungi 'set-selettiva-display
            : filter-args (lambda (args)
                           (if (or (car args) selettiva-display)
                               args
                             (list (1+ (current-column)))))
            '((nome. imposta-visualizzazione-selettiva-dalla-colonna-cursore)))

Voilà, C-x $improvvisamente è diventato utile anche senza niente C-uM-4affari.


0

Se stai usando JavaScript e js2-mode.elstai usando , puoi:

C-c C-f: attiva / disattiva nascondi / mostra tutto

C-c C-e: nascondi elemento

C-c C-s: mostra elemento

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.