Podpowiadanie składni

Coldpeer

Emacs jest edytorem przeznaczonym głównie dla programistów i to właśnie przez nich używany jest najczęściej. Wiele współczesnych edytorów kodów źródłowych posiada mechanizm podpowiadania/uzupełniania składni danego języka. Nie inaczej jest i w Emacsie.

     1 C-M-/
     2 Pabbrev
     3 Dabbrev
     4 Xrefactory
     5 Semantic, Speedbar i ECB

C-M-/

Jedną z najbardziej znanych metod jest kombinacja klawiszy `C-M-/`.

Działanie jest proste. Gdy mamy powiedzmy dwa obiekty xaaa i xabb, to po wpisaniu x, a następnie wybraniu C-M-/, pokaże się nowy bufor z listą wyników pasujących do wzorca, czyli xaaa i xabb. Można przejść na ten bufor (C-x o) i wybrać odpowiednią pozycję. Gdy napiszemy xab, automatycznie dopełni się do xabb (oczywiście po naciśnięciu C-M-/), nie wyświetlając bufora, gdyż jest to jedyna pasująca pozycja.

Metoda ma swoja wady jak i plusy. Z jednej strony utrudnia życie wyświetlaniem okna z buforem podpowiedzi, a z drugiej strony jest o tyle ciekawa, że jak przykładowo mamy klasę A i w niej zdefiniowaną składową x, to po wpisaniu nazwy instancji i operatora odniesienia do składowych (np. w C++ dla obiektów jest to kropka) uzyskamy dopełnienie do x. Tak samo przydaje się do niepamiętanych nazw z innych modułów.

Pabbrev

Pabbrev to dodatek podobny działaniem do opisanej powyżej metody, aczkolwiek bardziej funkcjonalny. Kod źródłowy można pobrać stąd (w razie czego: [[Z pogranicza/Emacs/Instalacja rozszerzeń do Emacsa]]).

Działanie. Przyjmijmy, że mamy dane dwa obiekty - xxxAbc i xxxAbb. Wpisując na przykład xx i naciskając TAB, otworzy się bufor z pozycjami pasującymi do wzorca, czyli obydwa nasze obiekty (nazwy) a dodatkowo obok kursora wyświetla w nawiasach kwadratowych pierwszą z rzędu nazwę - naciśnięcie jeszcze raz tabulatora spowoduje dopełnie do xxxAbc.

Propozycja wydaje się o wiele bardziej interesująca niż C-M-/, aczkolwiek nie jest porywająca. Dodatkowym minusem jest odczuwalnie rzadkie aktualizowanie nazw.

Dabbrev

Dabbrev jest uproszczoną wersją omawianego powyżej Pabbrev, nie wyświetla propozycji obok kursora, ale jest bardziej praktyczny. Dodatek powinien być zainstalowany domyślnie w GNU Emacsie (przynajmniej ja w 22.1 mam, ale pewnie i w 21 jest), a jeśli nie, to można pobrać z EmacsWiki.

Za jedno uzupełnienie odpowiada funkcja dabbrev-expand. Aby wyświetlić listę propozycji do uzupełnienia, wystarczy skorzystać z funkcji dabbrev-completion. Choć dostępny jest skrót M-/, możemy podbindować dabbrev-expand pod np. C-TAB:

(global-set-key (kbd "C-<TAB>") 'dabbrev-expand)

W przykładzie załóżmy, że są dane obiekty xxxAbc, xxxAbb, następnie xxx, do którego będziemy zaraz dopełniać, a po nim jeszcze obiekt xxxFF. Kursor znajduje się przy xxx (przed xxxFF). Naciskając C-TAB, dopełni się do xxxAbb (od dołu do góry poczynając od miejsca, w którym jest kursor); następne naciśnięcie tabulatora spowoduje zmianę na xxxAbc,a kolejne do xxxFF. Następne sprowadzi do pierwotnej postaci xxx, a jeszcze następne zacznie od początku, czyli xxxAbb.

A co, jeśli chcielibyśmy używać TAB-a do uzpełniania kodu? Ok, możemy podbindować pod TAB, a nie C-TAB, ale wtedy nie będzie nam działało wcinanie. Przedstawiam teraz zmodyfikowaną wersję znalezionej na grupach funkcji indent-or-expand. Oto kod, który wystarczy wrzucić do pliku ~/.emacs:

(defun indent-or-expand ()
  "Either indent according to mode, or expand the word preceding point."
  (interactive)
  (if (and
     (= ?w (char-syntax (or (char-before) ?\0)))
     (not (= ?w (char-syntax (or (char-after) ?\0)))))
    (dabbrev-expand nil)
    (indent-according-to-mode)))

(global-set-key (kbd "TAB") 'indent-or-expand)

Jeśli nie ma nic przed kursorem, to po naciśnięciu TAB nastąpi wcinanie, jeśli jest - dabbrev-expand.

Prawda, nie jest to może wykwintna metoda, ale moim zdaniem lepsza i bardziej sprawdzająca się w praktyce od powyższych. Sam jej używam w połączeniu z powyższą funkcją.

Z rodziny *abbrev warto jeszcze zainteresować się Abbrev, jednak bardziej polecam Dabbrev bądź Pabbrev.

Xrefactory

Chyba każdy się zgodzi, że najlepszym mechanizmem podpowiadania składni dla języków [[C|C/C++]] oraz [[Java]] jest Xrefactory. Wystarczy spojrzeć na zrzuty ekranu tu, czy tu. Niestety Xrefactory jest narzędziem płatnym - licencja nakazuje odinstalowanie biblioteki po ośmiu dniach, bądź jej zakupienia.

Nie będę opisywał tutaj sposobu działania, bo myślę, że jest on widoczny po screenach oraz wszystko inne znajduje się na stronie http://xref-tech.com/xrefactory.

Semantic, Speedbar i ECB

Powyższe metody, za wyjątkiem C-M-/ i Xrefactory, nie zwracają uwagi na kontekst. Mamy np. klasę `A` i w niej zdefiniowaną składową `x`; po wpisaniu nazwy instancji i operatora odniesienia do składowych (np. w C++ dla obiektów jest to kropka) nie uzyskamy dopełnienie do `x`. Można ten problem rozwiązać np. korzystając z Semantic. W tym celu należy wywołać funkcję `semantic-analyze-possible-completions` lub `semantic-complete-analyze-inline`, jeżeli zależy nam tylko na podpowiedzeniu nazw, a nie na możliwości wstawienia kodu.

Równie ciekawą opcją jest włączenie Speedbar razem z Semantic. Uruchamia się go funkcją semantic-speedbar-analysis, a przechodzi do niego M-TAB. Jeśli uważamy, że się zbyt wolno odświeża, możemy zrobić to ręcznie klawiszem klawiszem g.

Niestety niemożliwe jest korzystanie z innego Speedbara jednocześnie (np. przeglądarki klas) - tylko jeden może być odświeżany za jednym razem. Rozwiązaniem może być dość podobna, aczkolwiek bardziej funkcjonalna biblioteka ECB.

2 komentarzy

Ja jeszcze używam Emacs'a (od kliku miesięcy) ;-) Dla tych co nie używają: gorąco polecam.
Ja póki co używam MOD+/ do podpowiadania składni. Bardzo ciekawym narzędziem jest etags - pozwala np. przejść do definicji wskazanej funkcji, czy wyszukiwać i zamieniać wg. wzorca w całym projekcie. Można też dzięki temu mieć autouzupełnianie w minibuforze.

Zachęcam do rozbudowy tego tekstu o nowe pozycje. Sam z chęcią przeczytam i na pewno przyda się to wielu osobom. Słyszałem też, że python-mode da się zintegrować z IPythonem - próbował ktoś? Bo ja na razie nic nie znalazłem. To tak btw. Swoją drogą, ciekawi mnie, kto z Was z 4p używa Emacsa (oprócz Dodka i mnie)?