Also highlight named parameters between parentheses #28
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Until now, named parameters were highlighted in the following situations:
?name
accounts for these constructions:fun ?name -> expr
f ?name
,f ?name:expr
?name:typ -> typ
?(name …)
accounts for these:?(name : typ)
,?(name = expr)
,?(name : typ = expr)
.~name
accounts for these:fun ~name -> expr
f ~name
,f ~name:expr
This commit adds highlighting in the following situation:
~(name …)
accounts for these:?(name : typ)
.A related wish
What is still missing is highlighting non-optional parameters in function types:
name:typ -> typ
. Highlighting these is desirable to me, particularly for .mli files, so I have been thinking about it. This is mostly impossible because the syntax has no recognizable~
, so we essentially need to match anything of the shapename :
, which of course has countless conflicts (beware, below follow many lists with many bullets — I really want this):{ name : typ }
,{ r with name : typ }
(I would tend to consider it an opportune side effect)val name : typ
fun
:fun name : typ -> expr
,fun pat name : typ -> expr
let
,external
: similarval
(for objects): similarmethod
: similar(name : typ)
(name :> typ)
,(expr : name :> typ)
name :: expr
name := expr
We can filter out many of these
:
and rule out>
,:
and=
(those cannot be the beginning of a type expression);name
, and rule out anything alphanumeric (including keywords likewith
,let
…);name
and:
; this is not complete but relies on a sensible coding style;Alternatively, we may enumerate which tokens of the grammar can precede the type expression
name:typ -> typ
::
:>
of
(valid for polymorphic variants but not for ADTs, apparently)&
— as in[< `A of & name:int -> int & name:bool -> bool ]
(idem)=
.
— as in'a . typexpr
->
(
,
— as in( typexpr , typexpr ) t
and[ typexpr , typexpr ] classpath
[
— as in[ typexpr ] classpath
constraint typexpr
(
However, we need not consider the following contexts:
typexpr * typexpr
(because of precedence between*
and->
, this would be a syntax error)[ typexpr | typexpr ]
(this would cause a type error))
Of these tokens, we may restrict the match to the most common ones, ie.
=
,:
and->
— I am unsure about(
. But even with the first three, false positives remain:To me, that’s good enough for realistic code.
In any case, we will never get rid of the ambiguity between the type expression
( name : int -> bool )
(wherename
is of typeint
) and the value expression( name : int -> bool )
(wherename
is of typeint->bool
(!!!)).