Jak uzyskać efekty zwijania kodu w Emacsie?

123

Jaki jest najlepszy sposób na osiągnięcie czegoś takiego jak składanie kodu lub typ cyklu używanego w trybie org. Jakie byłoby najlepsze rozwiązanie w elisp do tworzenia tego typu zachowań?

EDYCJA: Przepraszam, nie było jasne. Chcę zaprogramować w elisp coś, co robi rzeczy bardzo podobne do zwijania kodu, a właściwie najbardziej przypomina tryb org z hierarchią, którą można rozszerzyć. Zastanawiam się, jak najlepiej osiągnąć ten efekt. Wydaje mi się, że nakładki emacsa są dobrym rozwiązaniem, ale nie wiem.

Jeśli chodzi o składanie, po prostu używam wbudowanego zestawu selektywnego wyświetlania

EDYTUJ NUMER 2:

Dziękuję za odpowiedzi, ale myślę, że zadaję niewłaściwe pytanie, więc pozwól mi sprecyzować, co próbuję zrobić. Chciałbym stworzyć następujące

Kiedy umieścisz punkt na funkcji i wywołasz tę funkcję elisp, umieści definicję funkcji z dowolnego miejsca (myślę o użyciu do tego celu po prostu find-tag) i rozwinie ją w bieżącym buforze. Chodzi o to, że jeśli musisz przeskoczyć do innego bufora, aby odczytać definicję funkcji, czuję, że jest to przełącznik kontekstu do innego pliku. Chciałbym więc, żeby zachowywał się jak zwijanie kodu, tylko że pobiera kod zewnętrzny z bufora. Stwarza to pewne problemy, ponieważ nie może faktycznie wkleić kodu do bufora lub jeśli ktoś go zapisze, zapisze ściągnięty kod. Zastanawiam się więc, czy istnieje sposób na utworzenie obszaru wewnątrz bufora, który również nie jest częścią bufora. Myślę, że to ma sens.

Jakub
źródło
Szukasz czegoś, co wywołując to z punktem w funkcji CALL, przeskakuje do definicji funkcji? coś w rodzaju pomocy dotyczącej funkcji elisp pozwoli ci przejść do kodu elisp? Nie sądzę, abyś mógł to zrobić bez koncepcji „projektu”. Na przykład, skąd wiesz, do której funkcji „zamiany” chcesz przejść?
Brian Postow
1
Zobacz też: stackoverflow.com/questions/382781/… gdzie selektywne wyświetlanie jest nieco zmodyfikowane, aby uzyskać efekty podobne do zwijania.
Michael Paulukonis
Radzę usunąć swoje EDIT NB 2i zadać nowe pytanie.
Stefan

Odpowiedzi:

151

Zwalnianie jest generalnie niepotrzebne w emacsie, ponieważ zawiera narzędzia, które jawnie implementują czynności wykonywane ręcznie podczas zwijania kodu.

Większość ludzi odnosi sukcesy dzięki prostym wyszukiwaniom przyrostowym. Widzisz gdzieś wspomniane „foo”? Wpisz C-sfoo, znajdź definicję, naciśnij klawisz Enter, przeczytaj ją, a następnie naciśnijC-x C-x aby wrócić do poprzedniego miejsca. Proste i bardzo przydatne.

Większość trybów obsługuje imenu . M-ximenupozwoli ci przejść do definicji funkcji (itp.) według nazwy. Możesz również powiązać go z kliknięciem myszy, aby uzyskać menu funkcji (lub dodać je do paska menu; więcej szczegółów znajdziesz na stronie Informacje). Dostarcza danych dla trybu-funkcji, który pozwoli ci zobaczyć, w której funkcji aktualnie się znajdujesz w modelu. (Dlaczego jednak twoje funkcje są tak długie?)

Jest też speedbar , który wyświetla graficznie informacje imenu (i inne rzeczy).

Jeśli chcesz uzyskać przegląd swojego pliku, spróbuj M-xoccur ". Biorąc pod uwagę wyrażenie regularne, utworzy nowy bufor z każdym dopasowaniem w bieżącym buforze. Możesz wyszukać" (defun ", aby uzyskać przegląd funkcji bieżącego pliku narzędzia. Kliknięcie wyniku przeniesie Cię do tej pozycji w pliku.

W każdym razie pomyśl o tym, co naprawdę chcesz osiągnąć, a Emacs prawdopodobnie to implementuje. Nie walcz z niedoskonałymi narzędziami, które powodują, że ciągle składasz i rozkładasz rzeczy.

jrockway
źródło
13
Vim również zapewnia wszystkie te funkcje w takiej czy innej formie, ale nadal uważam, że jego funkcja zwijania kodu jest nieoceniona.
intuicja
115
Głosowałem w dół na pierwsze zdanie ("Składanie jest generalnie niepotrzebne w przypadku emacsa, ponieważ ..."). Ciągle używam prostego składania (na podstawie poziomu wcięć), aby skanować strukturę nieznanego kodu.
Simon Michael
4
Ms o to skrót do Mx występuje
Joshua Olson
3
Głosowałem w górę, ponieważ w odpowiedzi znalazło się wiele przydatnych skrótów, ale także głosowanie w górę @SimonMichael, ponieważ funkcja fold / unfold może być czasami przydatna!
Adrien Coquio,
56
Odpowiedź była dobrze przemyślana i bardzo pouczająca. Jednak OP zapytał, jak zrobić składanie kodu. OP nie zapytał, jaki jest ulubiony sposób unikania zwijania kodu przez wszystkich. Głosował w dół.
wkschwartz
104

tryb ukrywania ( hs-minor-mode) z domyślnym przypisaniem klawiszy, C-c @ C-M-haby wywołać zwijanie ( hs-hide-all)

dmckee --- kociak ex-moderator
źródło
12
To działa dobrze. I ze złego trybu, to jest wyzwalane przez normalnych poleceń vim: zR, zM, zo, zc.
Justin M. Keyes
39

Inny sposób na oskórowanie kota:

Tak się składa, że ​​nie potrzebujesz do tego żadnego pakietu ani dodatkowej konfiguracji. Po prostu przejdź do dowolnego pliku źródłowego, wpisz

M-1 Cx $ i dzieje się magia!

Jak zwykle, to biała magia: Cx $ przywróci kod.

Możemy użyć systemu pomocy Emacsa, aby odkryć, co się dzieje: Ch k Cx $ mówi nam, że powyższa kombinacja klawiszy wywołuje set-selektywne-display , funkcję, która przyjmuje jeden argument numeryczny (przedrostek M-1 przekazuje 1 jako wartość tego argumentu) i, co nie jest zaskakujące, ustawia zmienną selektywne wyświetlanie na wartość tego argumentu.

z pomniejszego bloga o czarodziejach emacsa

Tylko dla kompletności: M-3 Cx $ pokaże głębszy zagnieżdżony kod i tak dalej.

FWIW Zrobiłem dzisiaj małego pomocnika, bazującego na czymś. znaleziony tutaj , aby F5 przełącza zwijanie kodu w oparciu o bieżącą pozycję kursora:

(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
źródło
22

Używam trybu pomocniczego zarysu, aby złożyć mój kod w Pythonie. Zamiast potrzeby umieszczania {{{i}}}, jak w trybie zwijania, używa tego, gdzie zdefiniowano blok.

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

Jestem prawie pewien, że pochodzi z emacsa. Następnie dodaję to do mojego .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)
)
Nikwin
źródło
8
wygląda na to, że outline-modeobsługuje Pythona od razu po wyjęciu z pudełka w emacs 24 - nie ma potrzeby korzystania z niestandardowych outline-levelfunkcji. To wszystko, co musiałem dodać do mojego user.el:(add-hook 'python-mode-hook 'outline-minor-mode)
scytale
1
oh i na pewno chcesz to przesłonić outline-minor-mode-prefix- domyślne skróty klawiszowe są okropne - używam(setq outline-minor-mode-prefix (kbd "C-;"))
scytale
13

Możesz również uzyskać zwijanie kodu za pomocą CEDET z następującym kodem w pliku init:

(global-semantic-folding-mode t)

Po ocenie tego kodu mały trójkąt pojawi się w obszarze fringle, dzięki czemu będziesz mógł składać i rozkładać kod za jego pomocą. Ta metoda jest bardziej precyzyjna, ponieważ wykorzystuje informacje składniowe wyodrębnione z kodu źródłowego

Alex Ott
źródło
1
jeśli
napotkasz
9

hs-minor-mode działa pięknie.

Działa jeszcze piękniej w połączeniu z fold-dwim (rób co mam na myśli). Następnie jest fold-dwim-org, który zapewnia tryb org, podobny do przypisywania klawiszy do zwijania kodu! Oba można zainstalować za pomocą marmolady (i chyba elpa).

Jones
źródło
5

vimish-fold to także przyjemne i łatwe rozwiązanie.

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

Ze strony głównej:

To jest pakiet do wykonywania zawijania tekstu jak w Vimie. Posiada następujące cechy:

  • fałdowanie aktywnych regionów;
  • dobra opinia wizualna: oczywiste jest, która część tekstu jest zawinięta;
  • trwałość domyślna: kiedy zamykasz plik, twoje fałdy nie znikają;
  • trwałość skaluje się dobrze, możesz pracować na setkach plików z wieloma fałdami bez negatywnych skutków;
  • nie łamie wcięć ani czegoś takiego;
  • fałdy można bardzo łatwo przełączać ze stanu złożonego do rozłożonego iz powrotem;
  • szybka nawigacja między istniejącymi fałdami;
  • możesz używać myszki do rozkładania fałd (dobre dla początkujących i nie tylko dla nich);
  • dla fanów pakietu avy: możesz użyć avy do zwinięcia tekstu przy minimalnej liczbie naciśnięć klawiszy!

Korzystając z doskonałego use-package, instaluję i aktywuję go za pomocą tego fragmentu kodu w mojej konfiguracji:

(use-package vimish-fold
  :ensure t
  :config (vimish-fold-global-mode t))
Horus
źródło
3

Dziwię się, że nikt nie wspomniał o zwężaniu-poszerzaniu. Jest super niesamowity, jest również dostarczany w pakiecie z emacsem. Po prostu wybierz kod, na którym chcesz się skupić i naciśnij C-x n n, aby wrócić do trybu pełnego widoku, po prostu zrób C-x n w. Zawsze wolę używać wbudowanej funkcjonalności emacsa niż zaśmiecać moją przestrzeń użytkownika innym pakietem. Jeśli emacs może to zrobić z wbudowaną funkcjonalnością, to wolę to od jakiegoś pakietu innej firmy, ale to tylko ja, nie oznacza ani nie sugeruje niczego innego poza tym, że lubię proste rzeczy od złożonych, długich konfiguracji.

Kirk Walla
źródło
2

Uważam, że twoje porównanie twojego "projektu" do składania nie jest całkiem dobre, ponieważ składanie polega na zmianie wyglądu przy zachowaniu nienaruszonej zawartości bufora (tekstu). Twój projekt wymagałby pokazania dodatkowego tekstu przy zachowaniu nienaruszonej zawartości bufora, AFAIU. Więc. nie jest to możliwe do zaimplementowania jako kompozycja wstawiania tekstu i zawijania (wtedy zawartość bufora uległaby zmianie).

Ale być może jest to rzeczywiście możliwe, ten sam mechanizm jak składanie odbywa się - „nakładek” ... Rozważmy i „przed-string” „after-string” właściwości nakładki ; być może mógłbyś umieścić definicje funkcji w tych napisach należących w punkcie do nakładki o zerowej długości. Przyjrzyj się funkcji outline-flag-region, aby zobaczyć, jak nakładki są używane w trybie konturu.

imz - Ivan Zakharyaschev
źródło
2

Jeśli używasz hs-minor-mode, dobrym pomysłem może być również ustawienie wygodniejszego skrótu, np:

(eval-after-load 'hideshow
 '(progn
   (global-set-key (kbd "C-+") 'hs-toggle-hiding)))
quazgar
źródło
0

Z inspiracji odpowiedź einSelbst za :

(rada-dodaj 'ustaw-selektywne-wyświetlanie
            : argument-filtru (lambda (args)
                           (jeśli (lub (argumenty samochodowe) selektywne wyświetlanie)
                               argumenty
                             (lista (1+ (bieżąca kolumna)))))
            '((nazwa. set-selektywne-wyświetlanie-z-kolumny-kursora)))

Voila, C-x $nagle stał się użyteczny nawet bez C-uani M-4działalności.

DomQ
źródło
0

Jeśli wykonujesz trochę JavaScript i używasz js2-mode.el, możesz:

C-c C-f: przełącz ukryj / pokaż wszystko

C-c C-e: ukryj element

C-c C-s: pokaż element

roboli
źródło