ctags-elm
ctags-elm copied to clipboard
Do we really want to distinguish between constants and functions?
This isn't really a valid distinction in functional programming. Constants are functions that don't take arguments. If we do want to distinguish them, I think we need to do so on the function declaration (one or more lower case identifiers followed by equals, or something) not by type as is currently the case.
I have defined a function type:
type alias Renderer =
List (Attribute Msg) -> String -> Html Msg
And instances of this type:
renderName : Field.Renderer
renderName atts value =
...
get falsely classified as constants because there is no arrow on the type even though the declaration clearly takes a parameter.
Since type annotations are optional, it'd probably be better to match on the first line of a function definition if that's possible. What do you think?
Matching on the function definition has issues to, for example, with point free functions.
add = (\x y -> x + y)
You're right. And, since elm-format puts the r.h.s. of that =
on the next line, we can't even match against the lambda until ctags supports multi-line regex matching.
I believe that this is still a valid issue, i.e. there is no good way to reliably distinguish between functions and constants using an Exuberant ctags regular expressions file. I think that there can be a decent case made to eliminate the distinction between them in the .ctags
file.
What do you feel about replacing the two lines dealing with functions and constants with something like this single line?
--regex-Elm=/^ *([[:lower:]][[:alnum:]_]+)[[:blank:]]*:[^:].+$/\1/f,function_constant,functions_constants/
If I understand correctly, that says: match a line starting with a variable name (identifier starting with lower) followed by zero or more blanks and then one or more characters that are not colons to the end of the line. That might work, the pitfall I can see is that it should also match
type aias Model =
Creating a tag for a function called type
. Does exuberant ctags support exclusive matching? If so you can match type and type aliases exclusively and leave a less specific rule like this for functions.
Actually, I think exclusive matching is a good idea. My function pattern currently looks as follows, which is too specific: it matches only lines comprising a series of lower case words. And I spotted a case in my own elm code where I have a function definition that destructures a pair in the arguments list. I will try using exclusive matching for type and type alias definitions and then I can use a less specific pattern to match functions and maybe capture my destructuring function.
--regex-elm=/^([[:lower:]_][[:alnum:]_]*)[[:blank:]]([[:lower:]_][[:alnum:]_]*[[:blank:]]+)*=/\1/f,function,Functions/
regex-Elm=/^ *([[:lower:]][[:alnum:]_]+)[[:blank:]]*:[^:].+$/\1/f,function_constant,functions_constants/
This matches a line starting with a lowercase name followed by a colon but not two colons and something else until the end of the line. That means that this line will match functions and constant type signatures.
To my knowledge, Exuberant Ctags does not support exclusive matching, but the colon rule means that it really does not match types, etc. even though the rule is not exclusive.
I need to write some tests for all of this, but not sure if I can get to it soon.
Okay. I missed the first colon! Regular expressions are so much fun to read. I have switched to matching the function definitions as type annotations are optional and in practice I believe they are commonly included at top level and omitted for helper functions. Now this is the right choice for the direction I have chosen because I do want to match (nested) helper functions. And for your project this approach looks like a good choice. My experience of where type annotations are added is based on Haskell, though. Elm programmers might behave differently.
I'ts a shame universal ctags isn't more prevalent: they have framework for unit tests cases.
By the way, I have now implemented the more general pattern for functions that I described in my comment above (using exclusive matching to prevent false positives on type defs), so I'm very grateful to you for this discussion which is helping me think through the issues. Thanks again!