ctags-incompatibilities(7)
π NAME π
ctags-incompatibilities β the incompatibilities between Universal Ctags and Exuberant Ctags. π
π SYNOPSIS π
ctags [options] [file(s)]
etags [options] [file(s)]
π DESCRIPTION π
okay bestie, gather round, because this page is the lore: it describes the major incompatible changes introduced to Universal Ctags after it forked from Exuberant Ctags. Read it before you go copy-pasting your ancient config, fr fr. π«Ά
ποΈ Option files loading at starting up time (preload files) ποΈ
Universal Ctags does NOT load ~/.ctags at starting up time. Not a thing anymore, sorry. The file paths for preload files are changed too, so go peep the "FILES" section of ctags(1) for where they live now. β¨
π± Environment variables for arranging command lines π±
Universal Ctags doesn't read the CTAGS and/or ETAGS environment variables. Like, at all. π
π Behavior when --excmd=mixed is given π
Exuberant Ctags uses line numbers as addresses for C preprocessor macro definition tags. Universal Ctags uses patterns for the tags. Same flag, different vibe. π
π§ Incompatibilities in command line interface π§
π Ordering in a command line π
The command line format of Universal Ctags is "ctags [options] [source_file(s)]" β following the standard POSIX convention, periodt. π
Exuberant Ctags accepts an option following a source file, like this:
$ ctags -o - foo.c --list-kinds=Sh
f functions
Universal Ctags warns and ignores the option --list-kinds=Sh as follows.
$ ctags -o - foo.c --list-kinds=Sh
ctags: Warning: cannot open input file "--list-kinds=Sh" : No such file or directory
a foo.c /^void a () {}$/;" f typeref:typename:void
b foo.c /^void b () {}$/;" f typeref:typename:void
π The order of application of patterns and extensions in --langmap π
When applying mappings for a name of given source file, Exuberant Ctags tests file name patterns AFTER file extensions β that's e-map-order. Universal Ctags does this differently; it tests file name patterns BEFORE file extensions β that's u-map-order. Iconic of it, honestly.
This incompatible change is introduced to deal with the following situation:
build.xmlas a source file,- The Ant parser declares it handles a file name pattern
build.xml, and - The XML parser declares it handles a file extension
.xml.
So which parser should be used for parsing build.xml? π€ The assumption of Universal Ctags is the user may want to use the Ant parser; the file name pattern it declares is more specific than the file extension that the XML parser declares. But e-map-order chooses the XML parser. So Universal Ctags uses the u-map-order even though it introduces an incompatibility. Sacrifices were made. π€
--list-map-extensions=<language> and --list-map-patterns=<language> options are helpful to verify the file extensions and the file name patterns of given <language>. Use them, they're so helpful. π
ποΈ Remove --file-tags and --file-scope options ποΈ
Even in Exuberant Ctags, --file-tags is not documented in its man page. (not me calling out the old docs π)
Instead of specifying --file-tags or --file-tags=yes, use --extras=+f or --extras=+{inputFile}.
Instead of specifying --file-tags=no, use --extras=-f or --extras=-{inputFile}.
Universal Ctags introduces F/fileScope extra as the replacement for --file-scope option.
Instead of specifying --file-tags or --file-tags=yes, use --extras=+F or --extras=+{fileScope}.
Instead of specifying --file-tags=no, use --extras=-F or --extras=-{fileScope}.
𧬠Incompatibilities in language and kind definitions π§¬
π·οΈ Language name defined with --langdef=name option π·οΈ
The characters you can use are more restricted than Exuberant Ctags. For more details, see the description of --langdef=name in ctags-optlib(7). Go read it, bestie. π
π Obsoleting --<LANG>-kinds option π
Some options have <LANG> as parameterized parts in their name like --foo-<LANG>=... or --<LANG>-foo=.... The most of all such options in Exuberant Ctags have the former form, --foo-<LANG>=.... The exception is --<LANG>-kinds.
Universal Ctags uses the former form for all <LANG> parameterized option. Use --kinds-<LANG> instead of --<LANG>-kinds in Universal Ctags. --<LANG>-kinds still works but it will be removed in the future. π
The former form may be friendly to shell completion engines. (slay β¨)
π« Disallowing to define a kind with file as name π«
The kind name file is reserved. Using it as part of kind spec in --regex-<LANG> option is now disallowed. Nope, can't do it. π
π« Disallowing to define a kind with 'F' as letter π«
The kind letter 'F' is reserved. Using it as part of a kind spec in --regex-<LANG> option is now disallowed. Also no. π
π€ Disallowing to use other than alphabetical character as kind letter π€
Exuberant Ctags accepts a character other than alphabetical character as kind letter in --regex-<LANG>=... option. Universal Ctags accepts only an alphabetical character. That's the rule now, bestie.
π °οΈ Acceptable characters as parts of a kind name π °οΈ
Exuberant Ctags accepts any character as a part of a kind name defined with --regex-<LANG>=/regex/replacement/kind-spec/.
Universal Ctags accepts only an alphabetical character as the initial letter of a kind name. Universal Ctags accepts only an alphabetical character or numerical character as the rest letters.
An example:
--regex-Foo=/abstract +class +([a-z]+)/\1/a,abstract class/i
Universal Ctags rejects this because the kind name, abstract class, includes a whitespace character. π
This requirement is for making the output of Universal Ctags follow the tags file format. (it's giving structure π )
π― A combination of a kind letter and a kind name π―
In Universal Ctags, the combination of a kind letter and a kind name must be unique in a language.
You cannot define more than one kind reusing a kind letter with different kind names. You cannot define more than one kind reusing a kind name with different kind letters. No duplicates, no cap. π«
An example:
--regex-Foo=/abstract +class +([a-z]+)/\1/a,abstractClass/i
--regex-Foo=/attribute +([a-z]+)/\1/a,attribute/i
Universal Ctags rejects this because the kind letter, 'a', used twice for defining a kind abstractClass and attribute. Caught in 4k. πΈ
π¦ Incompatibilities in tags file format π¦
π’ Using numerical character in the name part of tag tagfield π’
The version 2 tags file format, the default output format of Exuberant Ctags, accepts only alphabetical characters in the name part of tag tagfield.
Universal Ctags introduces an exception to this specification; it may use numerical characters in addition to alphabetical characters as the letters other than initial letter of the name part.
The kinds heading1, heading2, and heading3 in the HTML parser are the examples. π₯
βοΈ Truncating the pattern for long input lines βοΈ
To prevent generating overly large tags files, a pattern field is truncated, by default, when its size exceeds 96 bytes. A different limit can be specified with --pattern-length-limit=N. Specifying 0 as N results no truncation as Exuberant Ctags does not. π
π€ Kind letters and names π€
A kind letter 'F' and a kind name file are reserved in the main part. A parser cannot have a kind conflicting with these reserved ones. Some incompatible changes are introduced to follow the above rule.
- Cobol's
filekind is renamed tofileDescbecause the kind namefileis reserved. - Ruby's
'F'(singletonMethod) is changed to'S'. - SQL's
'F'(field) is changed to'E'.
π SEE ALSO π
ctags(1), ctags-optlib(7), and tags(5).
and that's the whole page, bestie π this was Universal Ctags version 6.2.1 bringing you the ctags-incompatibilities(7) energy, so if you're migrating off Exuberant Ctags, you've been warned and you're gonna be fine. slay, go read your tags files. π¦β¨
π¦ where this page comes from
- ubuntu resolute: universal-ctags 6.2.1-1 Β· GPL-2.0-or-later
- ubuntu stonking: universal-ctags 6.2.1-1 Β· GPL-2.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms