CTAGS-INCOMPATIBILITIES(7)

πŸ’– CTAGS-INCOMPATIBILITIES β€” the group chat version ✨

okay so this whole page is the ctags-incompatibilities man page from the Universal Ctags manual (section 7), and it's basically the receipts on every single way Universal Ctags and Exuberant Ctags do NOT vibe together. Universal Ctags is the fork, Exuberant Ctags is the ancestor, and the family reunion was messy bestie. πŸ’€


πŸ“œ SYNOPSIS

ctags [options] [file(s)]
etags [options] [file(s)]

🌸 DESCRIPTION

This page spills the tea on the major incompatible changes that got introduced into Universal Ctags after it forked off from Exuberant Ctags. Like, it's the same family tree but the branches grew in different directions. πŸ¦‹

πŸ—‚οΈ Option files loading at starting up time (preload files)

Universal Ctags does not load ~/.ctags when it starts up. Not a thing anymore. The file paths for preload files got moved around too. Go peek at the "FILES" section of ctags(1) for the current deets. πŸ“

🌱 Environment variables for arranging command lines

Universal Ctags does not read the CTAGS and/or ETAGS environment variables. Those are retired, bestie. No cap. πŸ™…β€β™€οΈ

🎭 Behavior when --excmd=mixed is given

Exuberant Ctags uses line numbers as addresses for C preprocessor macro definition tags. Universal Ctags uses patterns for those tags instead. Different address style, same energy. ✨

🚧 Incompatibilities in command line interface

πŸ”’ Ordering in a command line

The command line format for Universal Ctags is "ctags [options] [source_file(s)]" and it follows the standard POSIX convention, periodt.

Exuberant Ctags, though? It accepts an option following a source file. Like this:

$ ctags -o - foo.c --list-kinds=Sh
f  functions

Universal Ctags warns and just ignores that --list-kinds=Sh option entirely, like this:

$ 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 warning is doing the most, but it's for your own good πŸ’…

πŸ”„ The order of application of patterns and extensions in --langmap

When it applies mappings for the name of a given source file, Exuberant Ctags tests file name patterns AFTER file extensions β€” that's called e-map-order. Universal Ctags flips it: it tests file name patterns BEFORE file extensions β€” that's u-map-order. πŸ”₯

This incompatible change was introduced to deal with this exact situation:

  • build.xml as 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 that the user probably wants the Ant parser, because the file name pattern it declares is more specific than the file extension the XML parser declares. But e-map-order would pick the XML parser. Tragic. So Universal Ctags uses the u-map-order even though it introduces an incompatibility. It's giving "we know it's different, we did it on purpose." πŸ‘‘

The --list-map-extensions=<language> and --list-map-patterns=<language> options are super helpful for verifying the file extensions and the file name patterns of a given <language>. 🧚

πŸ—‘οΈ Remove --file-tags and --file-scope options

ngl, even in Exuberant Ctags, --file-tags was never documented in its man page. Iconic of it.

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 the F/fileScope extra as the replacement for the --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're allowed to use are more restricted than in Exuberant Ctags. For more details, go read the description of --langdef=name in ctags-optlib(7). πŸ“–

πŸ‘‹ Obsoleting --<LANG>-kinds option

Some options have <LANG> as a parameterized part in their name, like --foo-<LANG>=... or --<LANG>-foo=.... Most of all such options in Exuberant Ctags have the former form, --foo-<LANG>=.... The one exception? --<LANG>-kinds.

Universal Ctags uses the former form for all <LANG> parameterized options. So use --kinds-<LANG> instead of --<LANG>-kinds in Universal Ctags. --<LANG>-kinds still works for now, but it will be removed in the future. πŸ™ˆ

Also the former form may be friendlier to shell completion engines, which is lowkey a slay. πŸ’…

🚫 Disallowing to define a kind with file as name

The kind name file is reserved. Using it as part of a kind spec in the --regex-<LANG> option is now disallowed. Sorry bestie, that name is taken. πŸ’–

🚫 Disallowing to define a kind with 'F' as letter

The kind letter 'F' is reserved. Using it as part of a kind spec in the --regex-<LANG> option is now disallowed. πŸ™…β€β™€οΈ

🚫 Disallowing to use other than alphabetical character as kind letter

Exuberant Ctags accepts a character other than an alphabetical character as a kind letter in the --regex-<LANG>=... option. Universal Ctags accepts only an alphabetical character. That's it. That's the rule. ✨

πŸ”€ 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. And it accepts only an alphabetical character or numerical character as the rest of the 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 exists so the output of Universal Ctags follows the tags file format. It's for the ✨aesthetic✨ of correctness.

🎯 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 also cannot define more than one kind reusing a kind name with different kind letters.

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' got used twice β€” once for defining a kind abstractClass and once for attribute. Not the moment. 😭

πŸ“„ 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 the initial letter of the name part. 🌈

The kinds heading1, heading2, and heading3 in the HTML parser are the examples. See, it's a feature. 🫢

βœ‚οΈ 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 in no truncation, because Exuberant Ctags does not truncate. Choose your fighter. ⭐

🏷️ 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 were introduced to follow the above rule:

  • Cobol's file kind is renamed to fileDesc because the kind name file is 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).


aaaand that's the whole page bestie, you ate it up πŸ’…βœ¨ this was the CTAGS-INCOMPATIBILITIES(7) page from Universal Ctags, version 6.2.1 β€” go forth and be incompatible (on purpose) πŸ¦‹πŸ’–πŸ‘‘

πŸ“¦ where this page comes from