CTAGS-LANG-ELM(7)
β¨ ctags-lang-elm β¨
okay bestie, so this is a page from Universal Ctags β it's ctags-lang-elm(7), aka the little corner of the docs that's all about tagging Elm source code. it's not a full manual, it's literally described as "Random notes", and honestly? we respect the honesty. π
πΈ SYNOPSIS πΈ
ctags ... --languages=+Elm ...
ctags ... --language-force=Elm ...
ctags ... --map-Elm=+.elm ...
π¦ DESCRIPTION π¦
The Elm parser is a PEG parser built with PackCC, and PackCC is part of the ctags infrastructure itself. it should correctly process all top level statements, no cap. π«Ά
but bestie... there's a limitation. π functions embedded in let/in blocks? they will mostly be fine, but sometimes a function in a let/in block will be omitted. not a vibe, but it is what it is.
π EXAMPLES π
π Imports
Imported modules get tagged, and their role is "imported", not "def". Types, functions, etc. that get exposed via an imported module have their role as "exposed". β¨
Exposed items are marked as being in the scope of their own module, not the module that's doing the importing. iykyk.
"input.elm"
module SomeMod exposing (..)
import MyMod exposing
( map
, Maybe
, Result(..)
, MyList(Empty)
)
"output.tags" with --options=NONE -o - --sort=no --extras=+r --fields=+r input.elm
SomeMod input.elm /^module SomeMod exposing (..)$/;" m roles:def
MyMod input.elm /^import MyMod exposing$/;" m roles:imported
map input.elm /^ ( map$/;" f module:MyMod roles:exposed
Maybe input.elm /^ , Maybe$/;" t module:MyMod roles:exposed
Result input.elm /^ , Result(..)$/;" t module:MyMod roles:exposed
MyList input.elm /^ , MyList(Empty)$/;" t module:MyMod roles:exposed
Empty input.elm /^ , MyList(Empty)$/;" c type:MyMod.MyList roles:exposed
π Namespaces
Namespaces get tagged too, and their role is "def". slay. π
"input.elm"
module AMod exposing (..)
import MyImport as NSpace exposing (impFunc)
"output.tags" with --options=NONE -o - --sort=no --extras=+r --fields=+r input.elm
AMod input.elm /^module AMod exposing (..)$/;" m roles:def
NSpace input.elm /^import MyImport as NSpace exposing (impFunc)$/;" n module:AMod roles:def moduleName:MyImport
MyImport input.elm /^import MyImport as NSpace exposing (impFunc)$/;" m roles:imported
impFunc input.elm /^import MyImport as NSpace exposing (impFunc)$/;" f module:MyImport roles:exposed
π Type names
Constructors and top level functions will have type names. it's giving fully typed. π
"input.elm"
funcA : Int -> Int
funcA a = a + 1
type B
= B1Cons
{ x : Float
, y : Float
}
| B2Cons String Integer
| B3Cons
"output.tags" with --options=NONE -o - --sort=no --extras=+r --fields=+r input.elm
funcA input.elm /^funcA a = a + 1$/;" f typeref:typename:Int -> Int roles:def
B input.elm /^type B$/;" t roles:def
B1Cons input.elm /^ = B1Cons$/;" c type:B typeref:typename:{ x : Float , y : Float } -> B roles:def
B2Cons input.elm /^ | B2Cons String Integer$/;" c type:B typeref:typename:String -> Integer -> B roles:def
B3Cons input.elm /^ | B3Cons$/;" c type:B typeref:typename:B roles:def
π§ Function parameter lists
Function parameter lists can be extracted into the tags file signature field. okay so technically they're not really function signatures, but it's the closest concept available in ctags. use --fields=+S. π
funcA a1 a2 =
a1 + a2
"output.tags" with --sort=no --extras=+r --fields=+rS
funcA input.elm /^funcA a1 a2 =$/;" f signature:a1 a2 roles:def
π KNOWN LIMITATIONS π
bestie this is the part where we keep it real. π
The ctags signature field is used for function parameter lists, even though it's not an idea field. see above. π
Elm requires all statements at the same logical level to have the same indentation. if there's additional indentation, that line is part of the previous one. so, without over-complicating the PEG parser, we have the following limitations... π
- Sometimes functions in
let/inblocks will be omitted. - Functions in
let/inblocks will be marked as being in the scope of their outer function, regardless of how deeply nested thelet/inblock is. - Functions in
let/inblocks won't have type names.
π SEE ALSO π
ctags(1), ctags-client-tools(7)
mwah π that's the whole page! this was Universal Ctags version 6.2.1, and the manpage is CTAGS-LANG-ELM(7). go tag some Elm, bestie β you've got this. π«Άβ¨π
π¦ where this page comes from
- alpine 3.24: ctags-doc 6.2.1-r0 Β· GPL-2.0-or-later
- fedora 43: ctags 6.2.1-1.fc43 Β· GPL-2.0-or-later
- fedora 44: ctags 6.2.1-3.fc44 Β· 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