Exuberant Ctags#
Program ctags#
--regex-<lang>#
Argument --regex-<lang>
dla bieżącego wywołania programu ctags zarządza wyrażeniami regularnymi w poszczególnych językach spośród wszystkich obsługiwanych języków (zarówno tych pochodzących z wbudowanych parserów, jak i tych z własnych wyrażeń regularnych), które będą brane pod uwagę przy generowaniu tagów dla analizowanych plików.
Niniejszy poradnik dla programu ctags nie jest przewodnikiem po wyrażeniach regularnych, dlatego wszystkie opisy i przykłady dla wyrażeń regularnych są bardzo ogólnikowe. W razie potrzeby należy poszukać dodatkowych informacji na własną rękę.
Opis działania#
Prawidłowe użycie argumentu najlepiej objaśnić na zapisie składniowym:
ctags --regex-<lang>[=value] [--argument | -argument] [path]
gdzie poszczególne człony oznaczają:
- ctags - ścieżka względna lub bezwzględna do pliku binarnego programu ctags (
ctags.exe
). Wszystko zależy od sposobu uruchamiania programu ctags, np. z systemowej konsoli, ze skrótu do programu czy z innego programu/skryptu. - <lang> - identyfikator konkretnego języka obsługiwanego w bieżącym wywołaniu programu ctags, którego wyrażenia regularne będą modyfikowane. Wielkość znaków nie ma znaczenia.
value - jedna z dwóch wartości tekstowych wpływająca na wyrażenia regularne w poszczególnych językach:
""
- specjalna pusta wartość oznaczająca anulowanie wszystkich zdefiniowanych do tej pory wyrażeń regularnych dla danego języka. Nie ma ona wpływu na generowanie tagów, których definicje umieszczono we wbudowanych parserach, ale je można kontrolować argumentem--<lang>-kinds
. Jest ona równoważna z brakiem przekazania argumentu--regex-<lang>
lub z jego przekazaniem, ale bez podania jakiejkolwiek wartości."pattern"
- wzorzec definiujący pojedynczą regułę, która będzie brana pod uwagę przy generowaniu tagów dla analizowanych plików. Można go wyrazić następującym zapisem składniowym:/regexp/replacement/[kind-spec/][flags]
Wzorzec ten w swojej minimalnej postaci składa się z dwóch wymaganych pól regexp i replacement (pola kind-spec i flags są opcjonalne), które rozdziela się jakimś znakiem separatora w postaci pojedynczego znaku. Separatorem może być dowolny znak (z nielicznymi wyjątkami, np.
"\"
,"|"
,"^"
,"@"
,"&"
czy"
), który pojawi się jako pierwszy we wzorcu. W praktyce najczęściej wykorzystuje się znak"/"
, ale równie dobrze może być to np."-"
,"+"
,"="
czy"%"
. Ważnym jest, aby każde wystąpienie tego znaku w roli innej niż separator poprzedzać znakiem uniku"\"
.Poszczególne pola we wzorcu oznaczają:
regexp - wyrażenie regularne, które będzie porównywane z każdą linią w analizowanych plikach. Jeśli wystąpi jakieś dopasowanie między wyrażeniem regularnym a danymi tekstowymi w testowanej linii to wygenerowany zostanie dla niej tag z nazwą (
tagname
) wskazywaną przez replacement. Domyślnie program ctags obsługuje rozszerzone wyrażenia regularne POSIX, ale za pomocą pola flags można przejść na podstawowe wyrażenia regularne POSIX. W programie ctags pochodzącym z projektu Exuberant Ctags silnik wyrażeń regularnych został zorientowany na pojedynczej linii, co sprawia, że obsługa wyrażeń regularnych rozciągających się na wiele linii jest niedostępna.- replacement - nazwa (
tagname
) dla taga, który zostanie wygenerowany dla analizowanej linii w sytuacji, kiedy zostanie do niej dopasowane wyrażenie regularne regexp. Wartość można podawać wprost, ale nie może być ona pustym łańcuchem znakowym. W praktyce najczęściej stosuje się odwołanie wsteczne (back reference) do jakiegoś przechwyconego dopasowania w wyrażeniu regularnym. Dostępnych jest dziewięć odwołań wstecznych, które wskazujemy za pomocą znaku uniku"\"
, po którym następuje cyfra z przedziału1-9
, np."\1"
czy"\9"
. Za polem replacement zawsze należy umieścić znak separatora, nawet jeśli nie podajemy za nim kolejnych opcjonalnych pól. kind-spec - opcjonalna definicja opisująca rodzaj (
kind
) wygenerowanego taga. Pełną postać definicji można wyrazić następującym zapisem składniowym:short-name,full-name,description
gdzie poszczególne człony oznaczają (wartości zawierające spacje należy otoczyć podwójnymi cudzysłowami, albo można otoczyć nimi całą definicję):
- short-name # - skrótowa nazwa dla rodzaju taga w postaci pojedynczej litery, która przy domyślnych ustawieniach będzie dodawana do wygenerowanego taga za polem
tagaddress
. Jeśli podana wartość będzie składała się z więcej niż jednej litery to zostanie potraktowana jak full-name, to co za nią jak description (niezależnie od liczby zastosowanych potem przecinków), a dla skrótowej nazwy użyta zostanie domyślna litera"r"
. Jeśli wartość będzie pusta to użyta zostanie domyślna litera"r"
. - full-name # - pełna nazwa dla rodzaju taga, która może być dodawana zamiast short-name, np. ze względu na użycie argumentu
-−fields
czy-x
. Pusta wartość jest uznawana za prawidłową i powoduje, że pełna nazwa taga również będzie pusta. Jeśli pełna nazwa nie pojawi się w definicji opisującej rodzaj taga to użyta zostanie domyślna wartość"regex"
. - description # - dodatkowy opis dla rodzaju taga, który zostanie dołączony do danych wyświetlanych przez argument
−−list−kinds
. Jeśli wartość będzie pusta lub nie pojawi się w definicji opisującej rodzaj taga to użyta zostanie pełna nazwa z full-name, jeśli istnieje, w przeciwnym razie jej domyślna wartość"regex"
.
Ogólnie rzecz biorąc istnieje duża swoboda przy tworzeniu definicji opisującej rodzaj wygenerowanego taga, gdzie poszczególne jej pola są opcjonalne, podobnie zresztą jak cała definicja, co jest równoznaczne z jawnym użyciem wartości
"r,regex"
. Za polem kind-spec zawsze należy umieścić znak separatora, nawet jeśli nie podajemy za nim kolejnego opcjonalnego pola flags, w przeciwnym razie zostanie ono potraktowane jak pole flags.- short-name # - skrótowa nazwa dla rodzaju taga w postaci pojedynczej litery, która przy domyślnych ustawieniach będzie dodawana do wygenerowanego taga za polem
flags - opcjonalna lista flag, gdzie każda flaga to pojedyncza litera (bez dodatkowych znaków spacji między nimi), która wpływa na sposób interpretowania wyrażeń regularnych. Jeśli lista flag zawiera powtarzające się flagi lub flagi kontrolujące ten sam mechanizm to decydująca będzie ostatnia wymieniona w niej flaga. Jeśli w liście flag podana zostanie jakaś nieistniejąca flaga to zwrócony zostanie komunikat
ctags: Warning: unknown regex flag: 'x'
.W programie ctags pochodzącym z projektu Exuberant Ctags zdefiniowano trzy flagi dla wyrażeń regularnych:
"b"
- wzorzec zostanie zinterpretowany zgodnie z wymogami podstawowych wyrażeń regularnych POSIX # (POSIX Basic Regular Expression)[WikiEN, boost, GNU]."e"
- wzorzec zostanie zinterpretowany zgodnie z wymogami rozszerzonych wyrażeń regularnych POSIX # (POSIX Extended Regular Expression)[WikiEN, boost, GNU]. Jest to domyślne zachowanie i jest ono równoznaczne z brakiem przekazania flagi"e"
."i"
- porównanie wyrażenia regularnego z danymi tekstowymi odbywa się bez zwracania uwagi na wielkość znaków.
Za polem flags nie ma potrzeby umieszczania dodatkowego znaku separatora, bo i tak zostanie on zignorowany razem ze wszystkimi znakami, które wystąpią bezpośrednio za nim (włącznie z kolejnymi znakami separatora).
- argument - jeden lub więcej dodatkowych argumentów dostrajających działanie programu ctags.
- path - jedna lub więcej dodatkowych ścieżek do plików/folderów, które będą analizowane przy generowaniu tagów (szczegóły).
Kilka uwag odnośnie stosowania argumentu --regex-<lang>
:
- Argument
--regex-<lang>
można podawać wielokrotnie (separatorem jest spacja), i każdy kolejny będzie miał wpływ tylko na te argumenty, które występują bezpośrednio po nim. - Jeśli drugim członem w argumencie
--regex-<lang>
będzie identyfikator nieobsługiwanego języka to zwrócony zostanie komunikatctags: Warning: unknown language "xxx" in --regex-xxx option
. - Przekazanie argumentu
--regex-<lang>
bez podania jakiejkolwiek wartości jest równoważne z niejawnym użyciem pustej wartości""
. - Tworzenie własnych reguł z wyrażeniami regularnymi poprzez argument
--regex-<lang>
jest możliwe dopiero po dodaniu funkcji+regex
w czasie kompilacji programu ctags, co można sprawdzić np. argumentem--version
. - Argument
--regex-<lang>
zarządza wyrażeniami regularnymi we wszystkich obsługiwanych językach (z wbudowanych parserów oraz własnych wyrażeń regularnych). - Każdy wzorzec umieszczony w argumencie
--regex-<lang>
jest osobną regułą dla danego języka, nawet jeśli wcześniej zdefiniowano dla niego wzorzec o identycznych polach. To powoduje, że argument−−list−kinds
może zwracać identycznie wyglądające rodzaje tagów, które wciąż pochodzą od osobnych reguł biorących udział przy generowaniu tagów dla analizowanych plików. Jeśli wzorce wygenerują identyczne tagi (z dokładnością do jednego znaku) to za pomocą argumentu--sort
można pozbyć się wszystkich zbędnych duplikatów (co jest domyślnym zachowaniem programu ctags). - Nie ma żadnego argumentu, który wyświetliłby listę ze wszystkimi regułami definiującymi własne wyrażenia regularne dla konkretnego lub wszystkich obsługiwanych języków.
Prosty przykład:
ctags --regex-c="" --list-kinds=c :: wyczyszczenie wszystkich wyrażeń regularnych dla języka C
ctags --regex-c= --list-kinds=c :: wyczyszczenie wszystkich wyrażeń regularnych dla języka C
ctags --regex-c --list-kinds=c :: wyczyszczenie wszystkich wyrażeń regularnych dla języka C
ctags --list-kinds=c
ctags --regex-c=/a/a/ --list-kinds=c :: nowy rodzaj tagu z domyślnymi wartościami 'r,regex'
ctags --regex-c=/a/a/ --regex-c=/a/a/ --list-kinds=c :: dwa nowe rodzaj tagu z domyślnymi wartościami 'r,regex'
ctags --regex-c=/a/a/v/ --list-kinds=c :: nowy rodzaj tagu z wartościami 'v,regex'
ctags --regex-c=/a/a/v,tag/ --list-kinds=c :: nowy rodzaj tagu z wartościami 'v,tag'
ctags --regex-c=/a/a/v,tag,tags/ --list-kinds=c :: nowy rodzaj tagu z wartościami 'v,tags'
ctags --regex-c=/a/a/i --list-kinds=c :: nowy rodzaj tagu z domyślnymi wartościami 'r,regex' oraz flagą 'i'
ctags --regex-c=/a/a/ie --list-kinds=c :: nowy rodzaj tagu z domyślnymi wartościami 'r,regex' oraz flagami 'ie'
ctags --regex-c=/a/a/v/ --c-kinds=-v --list-kinds=c :: wyłączenie tagu z rodzajem 'v' tylko we wbudowanym parserze języka C
ctags --regex-c=/a/a/v/ --c-kinds --list-kinds=c :: wyłączenie wszystkich rodzajów tagów z wbudowanego parsera języka C
ctags --langdef=new --regex-new=/a/a/v/ --list-kinds=new :: nowy język 'new' z własnym rodzajem tagu 'v,regex'
ctags --langdef=new --regex-new=/a/a/v/ --regex-new=/a/a/v/ --list-kinds=new :: nowy język 'new' z dwoma własnymi rodzajami tagu 'v,regex'
ctags --langdef=new --regex-new=/a/a/v/ --regex-new --list-kinds=new :: wyczyszczenie wszystkich wyrażeń regularnych dla nowego języka 'new'
ctags --langdef=new --regex-new=/a/a/v/ --new-kinds --list-kinds=new :: wyłączenie wszystkich rodzajów tagów dla nowego języka 'new'
ctags --langdef=new --regex-new=/a/a/v/ --new-kinds=-v --list-kinds=new :: wyłączenie tagu z rodzajem 'v' dla nowego języka 'new'
:: Błędne przypadki
ctags --regex-
ctags --regex-cos
ctags --regex-c=/
ctags --regex-c=//
ctags --regex-c=///
ctags --regex-c=/a/
ctags --regex-c=/a//
ctags --regex-c=/a/b
ctags --regex-c=//b
ctags --regex-c=/a/b/c
ctags --regex-c=/a/b/ic