Comment réaliser des effets de pliage de code dans Emacs?
Quel est le meilleur moyen de réaliser quelque chose comme le pliage de code, ou le type de cyclisme utilisé par org-mode. Quelle serait la meilleure solution dans elisp pour créer ce type de comportement?
Modifier: Je suis désolé, je n'étais pas clair. Je veux programmer quelque chose dans elisp qui fait des choses très similaires au pliage de code, ou en fait plus comme org-mode avec la hiérarchie qui peut être étendue. Je me demande la meilleure façon d'atteindre cet effet. Je pense que j'ai entendu les superpositions emacs sont une bonne solution, mais je ne sais pas.
En ce qui concerne le pliage, j'utilise simplement le set-selective-display intégré
MODIFIER LE NUMÉRO 2:
Merci pour les réponses, mais je pense que je pose la mauvaise question, alors laissez-moi essayer d'être plus clair sur ce que j'essaie de faire. Je voudrais créer ce qui suit
Lorsque vous mettez votre point sur une fonction et appelez cette fonction elisp, elle mettra la définition de la fonction où qu'elle se trouve (je pense simplement à utiliser find-tag pour cela) et la déploiera dans le tampon courant. L'idée est que si vous devez passer à un tampon différent pour lire la définition de la fonction, j'ai l'impression que c'est un changement de contexte vers un autre fichier. Donc, je voudrais qu'il se comporte comme un pliage de code seulement il tire dans le code externe du tampon. Cela présente quelques problèmes car il ne peut pas coller le code dans le tampon ou si quelqu'un l'enregistre, il sauvera le code tiré. Je me demande donc s'il existe un moyen de créer une zone à l'intérieur d'un tampon qui ne fait pas non plus partie du tampon. Je pense que cela a du sens.
12 réponses
Le pliage est généralement inutile avec emacs, car il dispose d'outils qui implémentent explicitement les actions que les gens font manuellement lors du pliage de code.
La plupart des gens ont un bon succès avec des recherches incrémentielles simples. Voir "foo" mentionné quelque part? Type , C-sfoo
, trouver la définition, appuyez sur entrée, le lire, puis appuyez sur , C-x C-x pour revenir là où vous étiez. Simple et très utile.
La plupart des modes prennent en charge imenu. M-ximenu
vous permettra de aller à une définition de fonction (etc.) par son nom. Vous pouvez également le lier à un clic de souris pour obtenir un menu de fonctions (ou l'ajouter à la barre de menus; voir la page Info pour plus de détails). Il fournit des données pour which-function-mode, ce qui vous permettra de voir quelle fonction vous êtes actuellement dans la ligne de modelage. (Pourquoi vos fonctions sont-elles si longues?)
Il y a aussi speedbar , qui affiche les informations imenu (et d'autres choses) graphiquement.
Si vous voulez obtenir un vue d'ensemble de votre fichier, essayez M-xoccur
". Étant donné une expression rationnelle, il créera un nouveau tampon avec chaque correspondance dans le tampon actuel. Vous pouvez rechercher "(defun " pour obtenir un aperçu des fonctions implémentées par le fichier actuel. En cliquant sur le résultat vous déplacer à cette position dans le fichier.
Donc de toute façon, pensez à ce que vous voulez vraiment réaliser, et Emacs implémente probablement cela. Ne vous battez pas avec des outils imparfaits qui vous font plier et déplier les choses constamment.
Cacher-montrer le mode de (hs-minor-mode
) avec le raccourci clavier par défaut C-c @ C-M-h
pour déclencher le pliage (hs-hide-all
)
Une autre façon de peler le chat:
Comme il arrive, vous n'avez besoin d'Aucun paquet ou configuration supplémentaire pour que. Il suffit d'aller à n'importe quel fichier source, tapez
M-1 C-x $ et la magie opère!
Comme d'habitude, c'est de la magie blanche: C-x $ ramènera votre code.
Nous pouvons utiliser le système D'aide D'Emacs pour découvrir ce qui se passe: C-h K C-x $ nous dit que la combinaison de touches ci-dessus appelle set-sélectif-affichage, une fonction qui prend un argument numérique (le préfixe M-1 passe 1 comme valeur de cet argument) et, sans surprise, définit la variable sélective-affichage de la valeur de cet argument.
Juste pour l'exhaustivité: M-3 C - x $ montrerait un code imbriqué plus profond et ainsi de suite.
FWIW j'ai fait une petite aide aujourd'hui basée sur smth. trouvé ici de sorte que F5 bascule le pliage de code en fonction de la position actuelle du curseur:
(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))))))
J'utilise le mode mineur de contour pour plier mon code python. Au lieu d'avoir besoin de placer {{{ et }}} comme en mode pliage, il utilise où le bloc est défini.
http://www.gnu.org/software/emacs/manual/html_node/emacs/Outline-Mode.html http://www.emacswiki.org/emacs/OutlineMinorMode
Je suis sûr qu'il est livré avec emacs. Je puis ajouter à mon .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)
)
Vous pouvez également obtenir le pliage de code en utilisant CEDET avec le code suivant dans le fichier init:
(global-semantic-folding-mode t)
Après évaluation de ce code, le petit triangle apparaîtra dans la zone fringle, de sorte que vous pourrez plier et déplier le code en l'utilisant. Cette méthode est plus précise, car elle utilise des informations syntaxiques, extraites du code source
HS-minor-mode fonctionne à merveille.
Cela fonctionne encore plus magnifiquement lorsqu'il est associé à fold-dwim (faites ce que je veux dire). Ensuite, il y a fold-dwim-org, qui fournit un mode org comme des raccourcis clavier pour le pliage de code! Les deux peuvent être installés via marmelade (et je pense elpa).
Apparemment, il n'y a pas de solution parfaite, mais je pense que la meilleure est la suivante:
vimish-fold
est également une solution agréable et facile.
Https://github.com/mrkkrp/vimish-fold.
De la page d'accueil:
C'est un paquet pour effectuer le pliage de texte comme dans Vim. Il a les caractéristiques suivantes:
- pliage des régions actives;
- bon retour visuel: il est évident quelle partie du texte est pliée;
- persistance par défaut: lorsque vous fermez le fichier, vos plis ne disparaissent pas;
- les échelles de persistance bien, vous pouvez travailler sur des centaines de fichiers, avec beaucoup de plis, sans effets indésirables;
- Il ne casse pas l'indentation ou quelque chose;
- plis peut être basculé de plié État à déplié et retour très facilement;
- navigation rapide entre les plis existants;
- , vous pouvez utiliser la souris pour déplier les plis (bon pour les débutants, et pas seulement pour eux);
- pour les fans de paquet avy: vous pouvez utiliser avy pour plier le texte avec un nombre minimal de touches!
En utilisant l'excellent use-package
Je l'installe et l'active en utilisant cet extrait dans ma configuration:
(use-package vimish-fold
:ensure t
:config (vimish-fold-global-mode t))
Emacs est livré avec HS-minor-mode qui fascilite le pliage de code entre les expressions équilibrées http://www.emacswiki.org/emacs/HideShow
Je crois que votre comparaison de votre" projet " au pliage n'est pas très bonne, car le pliage consiste à changer l'apparence tout en gardant le contenu du tampon intact (le texte). Votre projet impliquerait d'afficher du texte supplémentaire tout en gardant le contenu du tampon intact, AFAIU. Si. il n'est pas implémentable en tant que composition d'insertion et de pliage de texte (alors, le contenu du tampon serait modifié).
Mais peut-être, c'est en effet possible avec le même mécanisme que le pliage est fait avec -- "superposition"... Considérez les propriétés de superposition "before-string" et "after-string" ; peut-être que vous pourriez mettre vos définitions de fonction dans ces chaînes appartenant à une superposition de longueur nulle au point. Regardez la fonctionoutline-flag-region pour voir comment les superpositions sont utilisées en mode outline.
Si vous utilisez hs-minor-mode
, Il pourrait être judicieux de définir également un raccourci plus pratique, par exemple:
(eval-after-load 'hideshow
'(progn
(global-set-key (kbd "C-+") 'hs-toggle-hiding)))
Avec l'inspiration de la réponse de einSelbst :
(advice-add 'set-selective-display :filter-args (lambda (args) (if (or (car args) selective-display) args (list (1+ (current-column))))) '((name . set-selective-display-from-cursor-column)))
Voilà, C-x $
est soudainement devenu utile même sans aucune activité C-u
Ni M-4
.