CTAGS-LANG-ELM(7)

πŸ“¦
version 6.2.1 Β· 6 versions
, in alpine 3.24, fedora 43, fedora 44

✨ 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/in blocks will be omitted.
  • Functions in let/in blocks will be marked as being in the scope of their outer function, regardless of how deeply nested the let/in block is.
  • Functions in let/in blocks 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