I use vim, and I'd like to be able to navigate to function and type definitions spread across multiple Elm projects. My understanding is that the easiest way to go about this is to use ctags.
There is an existing open issue from January 2016 with various suggestions, including a link to ctags-elm which provides:
--langdef=Elm
--langmap=Elm:.elm
--regex-Elm=/^ *([[:lower:]][[:alnum:]_]+)[[:blank:]]*:[^:].*->.*/\1/f,function,functions/
--regex-Elm=/^ *([[:lower:]][[:alnum:]_]+)[[:blank:]]*:[^:][^-]+$/\1/c,constant,constants/
--regex-Elm=/^port +([[:lower:]][[:alnum:]_]+)[[:blank:]]*:[^:]/\1/p,port,ports/
--regex-Elm=/^type +([[:upper:]][[:alnum:]_]+)/\1/t,type,types/
--regex-Elm=/^type[[:blank:]]+alias[[:blank:]]+([[:upper:]][[:alnum:]_]+)/\1/a,type-alias,type-aliases/
If you install this in ~/.ctags
, you can scan all your sources:
$ ctags -R --languages=-all,+Elm
However this approach still has problems:
- It ignores qualified names, so an attempt to navigate to the definition of
List.map
will offer all the definitions ofDict.map
,Set.map
,Random.map
etc. - It scans all the
*.elm
files in all my directories, including tests and old dependencies.
Basically I'd like a solution that:
- Can follow qualified names☨ to their definition: navigating to
List.map
should prefer definitions ofmap
in files namedList.elm
. - Scans all the
*.elm
files in each project'ssource-directories
- Ignores everything in each project's
tests
directory - Ignores all the built
*.js
files - Optionally scans the latest versions☨ of library sources in each project's
elm-stuff/packages
directory
Is this possible with ctags
, or with a ctags wrapper that parses each project's elm-packages.json
file?
[☨] Regarding qualified names: I'm aware that some people abbreviate qualifiers, like:
import Math.Vector3 as V3
and I wouldn't expect a ctags regex to look for V3.add
in Math/Vector3
.
The longer-term solution would be a tool that understands Elm modules and imports, like hasktags
does for Haskell. For now I could live with ctags not understanding abbreviated qualifiers.
[☨] Regarding latest versions: Sources of dependencies are downloaded into elm-stuff/packages/GITHUB-USERNAME/GITHUB-PROJECTNAME/VERSION-TAG
, and over time it is possible to accumulate multiple versions, eg:
elm-stuff/packages/kfish/elm-gamepad/3.0.0
elm-stuff/packages/kfish/elm-gamepad/3.1.0
elm-stuff/packages/kfish/elm-gamepad/3.2.0
elm-stuff/packages/kfish/elm-gamepad/3.4.0
I can't answer on the Elm-specific points but…
Add this to
~/.ctags
:Add this to
~/.ctags
if they are not compiled in a specific directory:or exclude the directory/directories in which they are compiled.
How do you define "latest"?The only way I could think of to reach that goal would be to pre-compile the list of places to look in and feed it to
ctags
via the-L
flag:Actually, writing a shell script to generate a proper
list-of-files.txt
could probably fix all your pain points. Maybe someone already thought about that…See
$ man ctags
.