Emacs'de kod katlama efektleri nasıl elde edilir?


123

Kod katlama veya org modunun kullandığı döngü türü gibi bir şeyi başarmanın en iyi yolu nedir? Bu tür davranışları yaratmak için elisp'deki en iyi çözüm ne olabilir?

DÜZENLEME: Üzgünüm net olamadım. Elisp'te kod katlamaya çok benzer şeyler yapan veya aslında en çok org modu gibi genişletilebilen hiyerarşi ile bir şey programlamak istiyorum. Bu etkiyi elde etmenin en iyi yolunu merak ediyorum. Sanırım emacs kaplamalarının iyi bir çözüm olduğunu duydum, ama bilmiyorum.

Katlama konusunda sadece yerleşik set seçici ekranı kullanıyorum

2 NUMARASINI DÜZENLE:

Cevaplar için teşekkürler ama sanırım yanlış soruyu soruyorum, bu yüzden ne yapmaya çalıştığım konusunda daha net olmaya çalışayım. Aşağıdakileri oluşturmak istiyorum

Noktanızı bir işleve koyduğunuzda ve bu elisp işlevini çağırdığınızda, işlev tanımını olduğu yere koyacaktır (bunun için sadece bul-etiketini kullanmayı düşünüyorum) ve onu mevcut tamponda açacaktır. Buradaki fikir, işlev tanımını okumak için farklı bir arabelleğe atlamanız gerekmesidir, bunun başka bir dosyaya bağlam geçişi olduğunu hissediyorum. Bu yüzden, sadece arabellekten dışarıdan gelen kodu çektiği kod katlama gibi davranmasını istiyorum. Bu, kodu arabelleğe tam olarak yapıştıramadığı için bazı problemler ortaya çıkarır veya birisi onu kaydederse, çekilen kodu kaydeder. Bu nedenle, bir tamponun içinde tamponun parçası olmayan bir alan oluşturmanın bir yolu olup olmadığını merak ediyorum. Bence bu mantıklı.


Bir işlev CALL ile çağırdığınızda, işlev tanımına atlayacak bir şey mi arıyorsunuz? bir elisp işlevi hakkında yardım almak gibi bir nevi elisp koduna geçmenize izin verecek mi? Bunu "Proje" kavramı olmadan yapabileceğinizi sanmıyorum. Örneğin, hangi "takas" işlevine atlamak istediğinizi nasıl bilebilirsiniz?
Brian Postow

1
Ayrıca bkz: stackoverflow.com/questions/382781/…, burada bazı katlama benzeri efektler için seçici ekran biraz ince ayarlanmıştır.
Michael Paulukonis

Seninkini kaldırmanı EDIT NB 2ve yeni bir soru oluşturmanı tavsiye ederim .
Stefan

Yanıtlar:


151

İnsanların kodu katlarken manuel olarak yaptığı eylemleri açıkça uygulayan araçlara sahip olduğundan, emacs ile katlama genellikle gereksizdir.

Çoğu insan basit artımlı aramalarda iyi bir başarı elde eder. Bir yerde geçen "foo" yu gördün mü? Yazın C-sfoo, tanımı bulun, enter tuşuna basın, okuyun ve C-x C-xbulunduğunuz yere dönmek için tuşuna basın . Basit ve çok kullanışlı.

Çoğu mod imenu'yu destekler . M-ximenuisme göre bir işlev tanımına (vb.) atlamanıza izin verir. Ayrıca, bir işlev menüsü almak için bir fare tıklamasına da bağlayabilirsiniz (veya menü çubuğuna ekleyebilirsiniz; daha fazla ayrıntı için Bilgi sayfasına bakın). Hangi işlev modu için veri sağlar, bu da şu anda modelin içinde hangi işlevin içinde olduğunuzu görmenizi sağlar. (Yine de işlevleriniz neden bu kadar uzun?)

Orada da hız çubuğu grafiksel imenu bilgisini (ve başka şeyler) görüntüler, hangi.

Dosyanıza genel bir bakış istiyorsanız, deneyin M-xoccur. Bir normal ifade verildiğinde, mevcut arabellekteki her eşleşmeyle yeni bir arabellek oluşturacaktır. Geçerli dosyanın işlevlerine genel bir bakış için "(defun" için arama yapabilirsiniz. Sonucu tıklamak sizi dosyadaki o konuma götürecektir.

Her neyse, gerçekten neye ulaşmak istediğinizi düşünün ve Emacs muhtemelen bunu uyguluyor. Bir şeyleri sürekli katlamanıza ve açmanıza neden olan kusurlu araçlarla savaşmayın.


13
Vim ayrıca tüm bu özellikleri bir şekilde veya başka bir şekilde sunuyor ancak yine de kod katlama özelliğini paha biçilemez buluyorum.
intuited

115
İlk cümle için aşağı oy verdim ("Katlama genellikle emacs için gereksizdir, as ..."). Tanıdık olmayan kodun yapısını taramak için sürekli olarak basit katlamayı (girinti düzeyine göre) kullanıyorum.
Simon Michael

4
Ms o meydana Mx için kısayoldur
Joshua Olson

3
Yukarı oy verdim çünkü cevaptaki birçok yararlı kısayol ama aynı zamanda @SimonMichael yorumu da artıyor çünkü katla / aç bazen hala faydalı olabilir!
Adrien Coquio

56
Cevap iyi düşünülmüş ve çok bilgilendiriciydi. Ancak OP, kod katlamanın nasıl yapılacağını sordu. OP, herkesin kod katlamayı önlemenin en sevdiği yolun ne olduğunu sormadı. Olumsuz oy verildi.
wkschwartz

104

katlamayı tetiklemek için hs-minor-modevarsayılan tuş atamalı ( ) gizle-göster modu C-c @ C-M-h( hs-hide-all)


12
Bu iyi çalışıyor. Ve kötülük-modu ile, bunun normal vim komutları tarafından tetiklenir: zR, zM, zo, zc.
Justin M.Keyes

39

Kedinin derisini yüzmenin başka bir yolu:

Olduğu gibi, bunun için herhangi bir pakete veya ekstra yapılandırmaya ihtiyacınız yoktur. Herhangi bir kaynak dosyaya gidin, yazın

M-1 Cx $ ve sihir gerçekleşir!

Her zamanki gibi beyaz sihir: Cx $ kodunuzu geri getirecek.

Neler olup bittiğini keşfetmek için Emacs'ın yardım sistemini kullanabiliriz: Ch k Cx $ bize yukarıdaki tuş kombinasyonunun, bir sayısal bağımsız değişken alan bir işlev olan set-selective-display'i çağırdığını söyler (M-1 öneki değer olarak 1'i geçer Bu argümandan) ve şaşırtıcı olmayan bir şekilde, seçici-gösterme değişkenini bu argümanın değerine ayarlar.

dan küçük Emacs'ta sihirbazlık günlüğü

Tamlık için: M-3 Cx $ daha derin iç içe geçmiş kodu gösterir ve bu böyle devam eder.

FWIW Bugün buna dayanarak küçük bir yardımcı yaptım. F5'in kod katlamayı geçerli imleç konumuna göre değiştirebilmesi için burada bulundu :

(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

Python kodumu katlamak için küçük anahat modunu kullanıyorum. Katlama modunda olduğu gibi {{{ve}}} yerleştirmeye ihtiyaç duymak yerine, bloğun tanımlandığı yeri kullanır.

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

Emacs ile geldiğinden oldukça eminim. Daha sonra bunu .emac'lerime ekliyorum

;;======= 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
outline-modeemacs 24'te kullanıma hazır python'u destekliyor gibi görünüyor - özel outline-levelişlevlere gerek yok . Tüm eklemem gereken bu user.el:(add-hook 'python-mode-hook 'outline-minor-mode)
scytale

1
oh ve kesinlikle geçersiz kılmak istiyorsunuz outline-minor-mode-prefix- varsayılan tuş atamaları berbat - kullanıyorum(setq outline-minor-mode-prefix (kbd "C-;"))
scytale

13

Ayrıca, init dosyasında aşağıdaki kodla CEDET kullanarak kod katlama elde edebilirsiniz:

(global-semantic-folding-mode t)

Bu kodun değerlendirilmesinden sonra, küçük üçgen saçak alanında görünecek, böylece kodu kullanarak katlayıp açabileceksiniz. Bu yöntem, kaynak koddan çıkarılan sözdizimsel bilgileri kullandığından daha kesindir.



9

hs-minor-mode güzel çalışıyor.

Fold-dwim ile eşleştirildiğinde daha da güzel çalışıyor (demek istediğimi yapın). Ardından, kod katlama için kuruluş modu gibi anahtar bağlamaları sağlayan fold-dwim-org var! Her ikisi de marmelat ile kurulabilir (ve sanırım elpa).



5

vimish-fold aynı zamanda güzel ve kolay bir çözümdür.

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

Ana sayfadan:

Bu, Vim'deki gibi metin katlama yapmak için bir pakettir. Aşağıdaki özelliklere sahiptir:

  • aktif bölgelerin katlanması;
  • iyi görsel geri bildirim: metnin hangi kısmının katlandığı açıktır;
  • varsayılan olarak kalıcılık: Dosyayı kapattığınızda kıvrımlarınız kaybolmaz;
  • kalıcılık iyi bir şekilde ölçeklenir; olumsuz etkiler olmadan çok sayıda kat yeri olan yüzlerce dosya üzerinde çalışabilirsiniz;
  • girintiyi veya başka bir şeyi kırmaz;
  • kıvrımlar, katlanmış durumdan açılmış duruma ve çok kolay bir şekilde geri döndürülebilir;
  • mevcut kıvrımlar arasında hızlı gezinme;
  • kıvrımları açmak için fareyi kullanabilirsiniz (yeni başlayanlar için iyidir ve sadece onlar için değil);
  • avy paketi hayranları için: metni minimum sayıda tuş vuruşuyla katlamak için avy'yi kullanabilirsiniz!

Mükemmel kullanarak use-packagekurdum ve yapılandırmamdaki bu pasajı kullanarak etkinleştirdim:

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

3

Kimsenin daralma-genişlemeden bahsetmemesine şaşırdım. Süper harika, emacs ile birlikte geliyor. Odaklanmak istediğiniz kodu seçin ve C-x n ntam görünüm moduna geri dönmek için düğmesine basın C-x n w. Kullanıcı alanımı başka bir paketle doldurmaktansa her zaman yerleşik emacs işlevselliğini kullanmayı tercih ederim. Eğer emacs bunu yerleşik işlevsellikle yapabiliyorsa, bunu bazı üçüncü taraf paketlerine tercih ederim, ancak bu sadece benim, karmaşık uzun yapılandırmalardan daha basit şeyleri sevdiğimden başka bir şey ifade etmez veya ima etmez.



2

İnanıyorum ki, "projenizi" katlama ile karşılaştırmanız pek iyi değil, çünkü katlama, tampon içeriğini (metin) sağlam tutarken görünümü değiştirmekle ilgilidir. Projeniz, arabellek içeriğini sağlam tutarken fazladan metin göstermeyi içerir, AFAIU. Yani. metin ekleme ve katlamanın bir bileşimi olarak uygulanamaz (daha sonra arabellek içeriği değişir).

Ama belki de, katlamanın - "overlays" ile yapıldığı gibi aynı mekanizma ile mümkündür ... "before-string" ve "after-string" overlay özelliklerini düşünün ; belki, fonksiyon tanımlarınızı, noktada sıfır uzunluklu bir kaplamaya ait olan bu dizelere koyabilirsiniz. Anahat modunda kaplamaların nasıl kullanıldığını görmek için anahat-bayrak-bölge işlevine bakın.


2

Eğer kullanırsanız hs-minor-mode, aynı zamanda daha uygun kısayolu mesela ayarlamak için iyi bir fikir olabilir:

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

0

EinSelbst'in cevabından ilham alarak :

(tavsiye-ekle 'set-seçici-ekran
            : filtre-değiştirgeleri (lambda (değiştirgeler)
                           (eğer (veya (araba değiştirgeleri) seçici ekran)
                               args
                             (liste (1+ (geçerli-sütun)))))
            '((name. set-selective-display-from-cursor-column)))

Voila, ne iş ne de iş C-x $olmadan aniden işe yaradı .C-uM-4


0

Biraz JavaScript yapıyor ve kullanıyorsanız js2-mode.el, şunları yapabilirsiniz:

C-c C-f: değiştir gizle / göster

C-c C-e: öğeyi gizle

C-c C-s: öğeyi göster

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.