Skip to content
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

Improve syntax highlighting #25296

Closed
wants to merge 2 commits into from
Closed

Conversation

chbk
Copy link
Contributor

@chbk chbk commented Feb 20, 2025

A PR to improve syntax highlighting and add missing scopes.
Changes are listed below with examples.

Release Notes:

  • Improved syntax highlighting for Bash, C, C++, CSS, Go, JavaScript, JSDoc, TSX, TypeScript, JSON, Markdown, Python, Regex, Rust

Bash

Zed 0.174.5 With this PR
  • >&, >&-, :, //, /, %, %%, #, ##, =, ==: operator
  • -lt, -le, -gt, -ge, -eq, -ne, -z, -n: keyword.operator, as defined in other languages
  • regex: string.regex, as defined in other languages
  • number: number
  • string: string
  • variable: property -> variable
  • ;: punctuation.delimiter
  • (, ), {, }, [, ]: punctuation.bracket
  • $, ${ }, $( ): punctuation.special, as defined in other languages
variable=I\ like\ Zed
function my_function() {
  echo "Hello world, ${variable//regex/string}" > file
}
if [ $(uid) -lt 600 ]; then
  my_function;
  cat file | grep hello >&3
fi

C, C++

Zed 0.174.5 With this PR
  • true, false, NULL, nullptr: constant -> constant.builtin, as defined in other languages
  • IDENTIFIER: constant -> constant.variable, different from constant literals
#include <stdbool.h>
int a[] = {true, false};
const int * IDENTIFIER = nullptr;

CSS

Zed 0.174.5 With this PR
  • |: operator
  • and, or, not, only: operator -> keyword.operator, as defined in other languages
  • keyword_query: constant, like in Atom and VS Code
  • namespace_name: property -> namespace, not a property name
  • property_name: constant -> property, like feature_name already defined
  • plain_value: constant
  • keyframes_name: constant, to stay coherent as it is tokenized as plain_value when referenced
  • unit: type -> constant.unit, Atom and VS Code also have a unit scope for this
  • id_name, class_name: property -> selector, not property names, these tokens deserve their own scope. Atom, VS Code, Neovim resort to recycling other scopes
@media keyword_query and not keyword_query {}
@supports (feature_name: plain_value) {}
@namespace namespace_name url("string");
namespace_name|tag_name {}
@keyframes keyframes_name {
  to {
    top: 200unit;
    color: #c01045;
  }
}
tag_name::before,
#id_name:nth-child(even),
.class_name[attribute_name=plain_value] {
  property_name: 2em 1.2em;
  --variable: rgb(250, 0, 0);
  color: var(--variable);
  animation: keyframes_name 5s plain_value;
}

Go

Zed 0.174.5 With this PR
  • constant: constant -> constant.variable, different from constant literals
  • package_identifier: namespace
  • method_elem: function.method
  • ; ,. ,, ,:: punctuation.delimiter
package my_package
import (
  pkg "fmt"
)
type A interface {
  method_elem(foo int, bar float64) int
}
func main() {
  identifier := true
  const constant int = 3
  for i := 0; i <= 3; i++ {
    pkg.Println(identifier)
  }
}

JavaScript, JSDoc, TSX, TypeScript

Zed 0.174.5 With this PR
  • IDENTIFIER: constant -> constant.variable, different from constant literals
  • true, false: boolean -> constant.builtin, this is the only language that has the boolean scope, so conforming to the majority
  • jsx_text: text.jsx
  • =: punctuation.jsx.delimiter
  • @: punctuation.special, as in Python
  • jsdoc: added comment.doc scope for themes that highlight it
/**
 * @keyword comment
 */
@log
class X {
  render() {
    return (
      <div jsx_attribute="value">
        <Input onKeyPress={super.bind(this)}/>
        jsx_text
      </div>
    );
  }
}
const IDENTIFIER = true

JSON

Zed 0.174.5 With this PR
  • true, false, null: constant -> constant.builtin, as defined in other languages
  • ,, :: punctuation.delimiter
{
  "property": null,
  "boolean": true
}

Markdown

Zed 0.174.5 With this PR

Changes to include the markup scope, conforming to Neovim, VS Code, Atom, and Zed itself.

  • # Heading: title -> markup.heading, as in the gitcommit grammar
  • ```: punctuation.markup.embedded
  • -, 1., >, |: punctuation.markup
  • *italic*: emphasis -> markup.emphasis
  • **bold**: emphasis.strong -> markup.emphasis.strong
  • ~~strikethrough~~: markup.strikethrough
  • `raw`: text.literal -> markup.raw
  • [link](url.com): markup.link
  • url.com: link_uri -> markup.link.url, as in the gitcommit grammar
  • paragraph, indented_code_block, pipe_table: text
# Heading

Some stylized text:
- `raw`
- *italic*
- ~strike~
- **strong**

> quoted

```python
print("some code")
```

1. Here is an ![image](image.jpg)
2. A [link](https://github.com/zed-industries)
3. And even a [referenced link][1]

[1]: https://zed.dev

| tables | are |
| --- | --- |
| properly | scoped |

Python

Zed 0.174.5 With this PR
  • @: operator, for matrix multiplication
  • IDENTIFIER: constant -> constant.variable, different from constant literals
  • identifier: variable
  • ., ,, :: punctuation.delimiter
class Mat(list):
  def __matmul__(self, b):
    ...
a, b = Mat(), Mat()
identifier = a @ b
IDENTIFIER = b @ a

Regex

Zed 0.174.5 With this PR
  • ^, $, \b, \B, \k: string.escape -> operator
  • group_name: property -> label
  • (?P=, <: punctuation.bracket
  • added regex scope to target regex tokens specifically
regex = /^(?<group>[!\.\?])\b[a-z]+word\k<group>$/g

Rust

Zed 0.174.5 With this PR
  • true, false: constant -> constant.builtin, as defined in other languages
  • IDENTIFIER: constant -> constant.variable, different from constant literals
  • identifier: variable
let identifier = true;
const IDENTIFIER: i32 = 3;

@cla-bot cla-bot bot added the cla-signed The user has signed the Contributor License Agreement label Feb 20, 2025
@zed-industries-bot
Copy link

Warnings
⚠️

This PR is missing release notes.

Please add a "Release Notes" section that describes the change:

Release Notes:

- Added/Fixed/Improved ...

If your change is not user-facing, you can use "N/A" for the entry:

Release Notes:

- N/A

Generated by 🚫 dangerJS against 249a395

@maxdeviant
Copy link
Member

@chbk Thank you for the PR!

I think we're going to need to split this up into smaller PRs in order to review. Splitting the changes up by language boundaries would be ideal.

@chbk
Copy link
Contributor Author

chbk commented Feb 21, 2025

@maxdeviant No problem, closing this one in favor of #25323 #25324 #25325 #25326 #25327 #25328 #25329 #25330 #25331 #25332 #25333

@chbk chbk closed this Feb 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla-signed The user has signed the Contributor License Agreement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants