-
Notifications
You must be signed in to change notification settings - Fork 589
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Haskell] The syntax highlighting changes are too dramatic to bear. #3227
Comments
The One color schemes use a red color for the {
"scope": "variable.other",
"foreground": "var(--foreground)",
}, |
Can you copy/paste the code in question so it needn't be transcribed by each person attempting to reproduce? |
data LetExpr = LetApp LetExpr LetExpr | LetDef [([Int], LetExpr)] LetExpr |
LetFun Int | LetVar Int | LetNum Int
deriving (Show, Eq)
parseLet :: String -> Maybe LetExpr
parseLet s = case parse letExpr s of
[(e, "")] -> Just e
_ -> Nothing
letExpr = letApp <|> letExprWithoutApp
-- 用于在letApp Parser中消除左递归
letExprWithoutApp = letFun
<|> letVar
<|> letNum
<|> letDef
<|> wrapped letExpr
letFun = LetFun <$> fun
letVar = LetVar <$> var
letNum = LetNum <$> nat
letDef = LetDef <$ symbol "let" <*> eqnList <* symbol "in" <*> letExpr
letApp = do
es <- letExprWithoutApp `sepBy` oneOrMoreSpaces
case es of
f:xxs@(_:_) -> return $ foldl LetApp f xxs
_ -> empty
eqnList :: Parser [([Int], LetExpr)]
eqnList = eqn `sepBy` (tok ';')
varList :: Parser [Int]
varList = var `sepBy` oneOrMoreSpaces
eqn :: Parser ([Int], LetExpr)
eqn = (,) <$> left <* tok '=' <*> right
where left = (:) <$> fun <* oneOrMoreSpaces <*> varList
right = letExpr
fun = char 'f' >> nat
var = char 'x' >> nat
tok = token . char
wrapped :: Parser a -> Parser a
wrapped p = id <$ tok '(' <*> p <* tok ')'
sepBy :: Parser a -> Parser b -> Parser [a]
sepBy p q = (:) <$> p <*> many (q >> p)
-- 一个或多个 space 的 parser
oneOrMoreSpaces :: Parser ()
oneOrMoreSpaces = some (sat isSpace) >> return () |
Thanks, it looks better! |
Any token of any meaning should receive a valuable scope to enable color schemes to address it. Otherwise they are forced to be highlighted as plain text under all circumstances. One may argue about the used scope name though. But ideally it should be one of the more common basic scopes used by most (and default) color schemes to ensure consistent highlighting accross syntaxes.
VSCode scopes them The idea behind A class also calls a constructor to create new objects of certain type. Nothing else a Haskell constructor function does. We could also scope it |
I don't pay much attention to scope names, but I think they should be consistent and differentiated. For the code shown below, all locations of data LetExpr = LetApp LetExpr LetExpr | LetDef [([Int], LetExpr)] LetExpr |
LetFun Int | LetVar Int | LetNum Int
deriving (Show, Eq) |
Choosing colors is the task of a color-scheme while syntax definitions only define valuable and semantically correct names for certain tokens. It's easy to achieve tha same highlighting with ST. While many older syntax definitions tried to achieve certain highlighting by abusing scope names we have decided to move on defining semantically correct scope names as a stable base for everything long ago because the former approach only works well for certain color schemes and languages. Sure, this path may result in some maintenance work for color scheme authors. But it should allow color schemes of reduced complexity in the long term by reducing the need to write language specific rules.
ST traditionally scopes all constructs They can be highlighted the same way if the color scheme decides to do so. It doesn't look that tramatical with the default setup of ST4126 using Mariana. |
Yes, |
The |
Why? With the scheme of all constructor references using |
Only In general, it comes down to the decision of what scope a constructor should receive, in which case I'm always happy to reference my favorite (unresolved) RFC discussion at #1842. TL;DR: it's complicated (?) Edit: added |
But as the syntax chooses to use
Even if we'd use I may be wrong, but I read |
For goto definition, |
Isn't |
In my opinion, The following is what it should be. data LetExpr = LetApp LetExpr LetExpr | LetDef [([Int], LetExpr)] LetExpr |
-- ^^^^^^^ entity.name.type storage.type
-- ^^^^^^ entity.name.function.constructor constant.other
-- ^^^^^^^ ^^^^^^^ storage.type |
Following the assignment, Each branch is a definition, define a constuctor, here are |
So finally all the constructors |
Yes. |
Represents the type of the corresponding parameter, which can be either a certain type (beginning with an uppercase letter) or a type variable (beginning with a lowercase letter). |
I agree with @absop's highlighting of the example. |
Another issue is how |
I think letDef = LetDef <$ ...
letApp = ... LetApp f xxs ... , they are called. |
I agree with @pennychase's opinion. |
In a comment to PR 2697 I gave an example of highlighting qualified imports that uses different scopes in the qualified name. @deathaxe explained that the scope naming scheme for all syntaxes differentiate between qualifiers and the entity that is imported. But in a qualified import you're not importing anything, rather you're giving a short name for the namespace. So in the example I gave |
I think I got the point about types vs. constructors. But please note ST's old Haskell syntax didn't distinguish them as well. All types and constructors were scoped data LetExpr = LetApp LetExpr LetExpr | LetDef [([Int], LetExpr)] LetExpr |
-- ^^^^^^^ constant.other
-- ^^^^^^ constant.other
-- ^^^^^^^ ^^^^^^^ constant.other I am not currently sure if constructors and types can be distinghished and thus highlighted correctly in all the different expressions. |
Both types and constructors start with a upper case letter, but constructors are applicative, types are not applicative, the will not be called, they are basically only referenced in type definitions. In something like a function call, if the function (means the first token in |
@absop I assume your issue has been resolved? Maybe close this? |
/cc @AmjadHD FYI, as this was your color scheme being talked about in the opening comment. |
OK, thanks |
This PR addresses some points from #3227. 1. It reorganizes prelude type/constant scopes, so `Just`, `Nothing`, `Left` and `Right` are highlighted consistently. 2. It scopes data constructors in data declarations `entity.name.constant`. 3. As a preparation for 2.) the strategy to handle `[context] =>` expresssions in class/data/newtype/type declarations had to be changed a bit to (more) reliably. It is mainly required to detect the beginning of data constructor expressions (`= Constr`), but also helps with some edge cases in the other declarations. Note: This PR does not scope data types and data constructors differently in normal statements/expressions as no reliable strategy hasn't been found to do so. * [Haskell] Reorganize and add prelude type and data constructors According to Haskell's wording ... - type constructors are scoped `support.type`, `storage.type` Type constructors without parameters are called "type". - data constructors are scoped `support.constant`, `constant.other` Data constructors without parameters are called "constant". Data constructors denote first class values. As such they can be assigned to variables etc. See: https://wiki.haskell.org/Constructor * [Haskell] Reorganize class identifier contexts Merge class and type contexts as it is not possible to reliably distinguish both in all situations anyway. The common scope `storage.type` ensures same highlighting under all circumstances. * [Haskell] Improve declaration context This commit... 1. adds some infrastructure to make sure to correctly match `[context] =>` patterns in class/instance/data/type/newtype declarations. It's required to reliably match the beginning of data constructors. 2. removes `entity.name.class` scoping from instance declarations as this was semantically wrong. * [Haskell] Improve deriving expression This commit limits fully qualified data type matching to 1 after `deriving` keywords, in case they are not surrounded by parens. More reliably pop as soon as possible. * [Haskell] Fix data constructor definitions This commit adds data constructor expressions in order to 1. scope constructors `entity.name.constructor` in declarations. 2. add declared constructor names to Symbol List. 3. enable "Goto Definition" It should improve readability of constructor expressions as the declared constructor may be tinted differently then the following types which define its signature.
@absop Are you satisfied with the look of the color scheme after deathaxe's commit ? |
Partly answered by #3321 |
Problem description
I am using the One Light color scheme, and I just updated my default packages with the master branch (under the help of this script), noticed that syntax highlighting in Haskell has changed dramatically as shown in the two screenshots below.
In my opinion, the previous syntax highlighting file was rough and lacked some features, such as the inability to jump to type definitions, which the new syntax highlighting file fixes. However, the new syntax highlighting caused the whole interface to look a bit exaggerated. Of course, this had something to do with the color scheme, but I still felt it was a problem.
Before the update
After the update
The text was updated successfully, but these errors were encountered: