id = "ctags"
name = "Universal Ctags"
homepage = "https://ctags.io/"
description = "Generate an index (or tag) file of language objects found in source files."
icon = "https://github.com/universal-ctags.png"
executables = ["ctags"]
[dotfiles]
paths = [
"[configHome]/ctags/",
"~/.ctags.d/",
"~/ctags.d/",
"~/.ctags",
]
secret = []
side_effect = false
[commands]
format = 1
features = ["standard_streams"]
label = "Generate tags"
description = "Index source files into a tags file with Universal Ctags. Per-language kinds, fields and extras, regex parsers and option files are left out."
quality = "ai-draft"
parser = { end_of_options = "--", interleave = "permute", long_equals = true, short_attached = true, short_bundles = true }
[[commands.source]]
id = "manual"
kind = "manual"
url = "https://docs.ctags.io/en/latest/man/ctags.1.html"
revision = "2026-10-27"
evidence = """
``--exclude=<pattern>``
``--recurse[=(yes|no)]``
``-R``
Equivalent to ``--recurse``.
``-L <file>``
``--append[=(yes|no)]``
``-a``
Equivalent to ``--append``.
``-f <tagfile>``
``--output-format=(u-ctags|e-ctags|etags|xref|json)``
``--sort=(yes|no|foldcase)``
``--languages=[+|-](<list>|all)``
"""
[[commands.field]]
id = "files"
label = "Files or directories"
description = "With Recurse on and nothing listed, the current directory is indexed."
type = "path"
position = 0
multiple = true
path = { kind = "any", role = "input" }
sources = ["manual"]
[[commands.field]]
id = "recurse"
label = "Recurse into directories"
type = "boolean"
option = ["--recurse", "-R"]
sources = ["manual"]
[[commands.field]]
id = "output"
label = "Tag file"
description = "Defaults to tags; - writes to standard output."
type = "path"
option = ["-f"]
path = { kind = "file", role = "output", must_exist = false, standard_stream = true }
effect = "overwrite"
sources = ["manual"]
[[commands.field]]
id = "append"
label = "Append to existing tag file"
type = "boolean"
option = ["--append", "-a"]
sources = ["manual"]
[[commands.field]]
id = "exclude"
label = "Exclude pattern"
type = "string"
option = ["--exclude"]
multiple = true
sources = ["manual"]
[[commands.field]]
id = "languages"
label = "Languages"
description = "Comma-separated list, or all."
type = "string"
option = ["--languages"]
sources = ["manual"]
[[commands.field]]
id = "sort"
label = "Sort tags"
type = "enum"
option = ["--sort"]
choices = [{ value = "yes", label = "Yes" }, { value = "no", label = "No" }, { value = "foldcase", label = "Case-folded" }]
sources = ["manual"]
[[commands.field]]
id = "output_format"
label = "Output format"
type = "enum"
option = ["--output-format"]
choices = [{ value = "u-ctags", label = "u-ctags" }, { value = "e-ctags", label = "e-ctags" }, { value = "etags", label = "etags" }, { value = "xref", label = "xref" }, { value = "json", label = "JSON" }]
sources = ["manual"]
[[commands.field]]
id = "file_list"
label = "File list"
description = "Read the names of files to index from a file; - reads standard input."
type = "path"
option = ["-L"]
path = { kind = "file", role = "input", standard_stream = true }
sources = ["manual"]
[[commands.task]]
id = "project"
label = "Index this project"
fields = ["files", "recurse", "exclude", "languages"]
required = []
set = { recurse = [true] }
[[commands.task]]
id = "json"
label = "Print JSON to stdout"
fields = ["files", "recurse", "exclude"]
required = []
set = { recurse = [true], output = ["-"], output_format = ["json"] }
lock = ["output", "output_format"]
[[commands.group]]
id = "basic"
label = "Basic"
fields = ["files", "recurse", "output", "exclude", "languages"]
[[commands.group]]
id = "advanced"
label = "Advanced"
fields = ["append", "sort", "output_format", "file_list"]