Merge pull request #892 from zed-industries/syntax-theme-fixes

Max Brunsfeld created

Syntax theme fixes

Change summary

assets/themes/dark.json                            | 81 +++++++++++++--
assets/themes/light.json                           | 81 +++++++++++++--
crates/language/src/highlight_map.rs               |  4 
crates/language/src/language.rs                    |  4 
crates/zed/src/languages/c/highlights.scm          | 11 +
crates/zed/src/languages/javascript/highlights.scm |  1 
crates/zed/src/languages/json/highlights.scm       |  9 +
crates/zed/src/languages/markdown/highlights.scm   |  2 
crates/zed/src/languages/rust/highlights.scm       | 14 ++
crates/zed/src/languages/toml/highlights.scm       | 20 ++-
crates/zed/src/languages/typescript/highlights.scm |  1 
crates/zed/src/main.rs                             | 12 +
styles/src/styleTree/editor.ts                     | 30 ++---
styles/src/themes/dark.ts                          | 12 +-
styles/src/themes/light.ts                         | 12 +-
styles/src/themes/theme.ts                         | 10 +
styles/src/utils/snakeCase.ts                      |  2 
17 files changed, 231 insertions(+), 75 deletions(-)

Detailed changes

assets/themes/dark.json 🔗

@@ -692,33 +692,88 @@
       }
     },
     "syntax": {
-      "keyword": "#4f8ff7",
-      "function": "#f9da82",
-      "string": "#f99d5f",
-      "type": "#3eeeda",
-      "number": "#aeef4b",
-      "comment": "#aaaaaa",
-      "property": "#4f8ff7",
-      "variant": "#53c1f5",
-      "constant": "#d5d5d5",
+      "primary": {
+        "color": "#d5d5d5",
+        "weight": "normal"
+      },
+      "comment": {
+        "color": "#aaaaaa",
+        "weight": "normal"
+      },
+      "punctuation": {
+        "color": "#c6c6c6",
+        "weight": "normal"
+      },
+      "constant": {
+        "color": "#d5d5d5",
+        "weight": "normal"
+      },
+      "keyword": {
+        "color": "#4f8ff7",
+        "weight": "normal"
+      },
+      "function": {
+        "color": "#f9da82",
+        "weight": "normal"
+      },
+      "type": {
+        "color": "#3eeeda",
+        "weight": "normal"
+      },
+      "variant": {
+        "color": "#53c1f5",
+        "weight": "normal"
+      },
+      "property": {
+        "color": "#4f8ff7",
+        "weight": "normal"
+      },
+      "enum": {
+        "color": "#ee670a",
+        "weight": "normal"
+      },
+      "operator": {
+        "color": "#ee670a",
+        "weight": "normal"
+      },
+      "string": {
+        "color": "#f99d5f",
+        "weight": "normal"
+      },
+      "number": {
+        "color": "#aeef4b",
+        "weight": "normal"
+      },
+      "boolean": {
+        "color": "#aeef4b",
+        "weight": "normal"
+      },
+      "predictive": {
+        "color": "#808080",
+        "weight": "normal"
+      },
       "title": {
         "color": "#de900c",
         "weight": "bold"
       },
-      "emphasis": "#4f8ff7",
-      "emphasis_strong": {
+      "emphasis": {
+        "color": "#4f8ff7",
+        "weight": "normal"
+      },
+      "emphasis.strong": {
         "color": "#4f8ff7",
         "weight": "bold"
       },
       "link_uri": {
         "color": "#79ba16",
+        "weight": "normal",
         "underline": true
       },
       "link_text": {
         "color": "#ee670a",
+        "weight": "normal",
         "italic": true
-      },
-      "list_marker": "#c6c6c6"
+      }
     }
   },
   "project_diagnostics": {

assets/themes/light.json 🔗

@@ -692,33 +692,88 @@
       }
     },
     "syntax": {
-      "keyword": "#1819a1",
-      "function": "#bb550e",
-      "string": "#eb2d2d",
-      "type": "#a8820e",
-      "number": "#484bed",
-      "comment": "#717171",
-      "property": "#106c4e",
-      "variant": "#97142a",
-      "constant": "#1c1c1c",
+      "primary": {
+        "color": "#1c1c1c",
+        "weight": "normal"
+      },
+      "comment": {
+        "color": "#717171",
+        "weight": "normal"
+      },
+      "punctuation": {
+        "color": "#555555",
+        "weight": "normal"
+      },
+      "constant": {
+        "color": "#1c1c1c",
+        "weight": "normal"
+      },
+      "keyword": {
+        "color": "#1819a1",
+        "weight": "normal"
+      },
+      "function": {
+        "color": "#bb550e",
+        "weight": "normal"
+      },
+      "type": {
+        "color": "#a8820e",
+        "weight": "normal"
+      },
+      "variant": {
+        "color": "#97142a",
+        "weight": "normal"
+      },
+      "property": {
+        "color": "#106c4e",
+        "weight": "normal"
+      },
+      "enum": {
+        "color": "#eb2d2d",
+        "weight": "normal"
+      },
+      "operator": {
+        "color": "#eb2d2d",
+        "weight": "normal"
+      },
+      "string": {
+        "color": "#eb2d2d",
+        "weight": "normal"
+      },
+      "number": {
+        "color": "#484bed",
+        "weight": "normal"
+      },
+      "boolean": {
+        "color": "#eb2d2d",
+        "weight": "normal"
+      },
+      "predictive": {
+        "color": "#808080",
+        "weight": "normal"
+      },
       "title": {
         "color": "#1096d3",
         "weight": "bold"
       },
-      "emphasis": "#484bed",
-      "emphasis_strong": {
+      "emphasis": {
+        "color": "#484bed",
+        "weight": "normal"
+      },
+      "emphasis.strong": {
         "color": "#484bed",
         "weight": "bold"
       },
       "link_uri": {
         "color": "#79ba16",
+        "weight": "normal",
         "underline": true
       },
       "link_text": {
         "color": "#eb2d2d",
+        "weight": "normal",
         "italic": true
-      },
-      "list_marker": "#555555"
+      }
     }
   },
   "project_diagnostics": {

crates/language/src/highlight_map.rs 🔗

@@ -51,6 +51,10 @@ impl HighlightMap {
 }
 
 impl HighlightId {
+    pub fn is_default(&self) -> bool {
+        *self == DEFAULT_SYNTAX_HIGHLIGHT_ID
+    }
+
     pub fn style(&self, theme: &SyntaxTheme) -> Option<HighlightStyle> {
         theme
             .highlights

crates/language/src/language.rs 🔗

@@ -546,7 +546,9 @@ impl Language {
             {
                 let end_offset = offset + chunk.text.len();
                 if let Some(highlight_id) = chunk.syntax_highlight_id {
-                    result.push((offset..end_offset, highlight_id));
+                    if !highlight_id.is_default() {
+                        result.push((offset..end_offset, highlight_id));
+                    }
                 }
                 offset = end_offset;
             }

crates/zed/src/languages/rust/highlights.scm 🔗

@@ -34,6 +34,20 @@
 ((identifier) @constant
  (#match? @constant "^[A-Z][A-Z\\d_]+$"))
 
+[
+  "("
+  ")"
+  "{"
+  "}"
+  "["
+  "]"
+] @punctuation.bracket
+
+(_
+  .
+  "<" @punctuation.bracket
+  ">" @punctuation.bracket)
+
 [
   "as"
   "async"

crates/zed/src/languages/toml/highlights.scm 🔗

@@ -20,14 +20,18 @@
 ; Punctuation
 ;------------
 
-"." @punctuation.delimiter
-"," @punctuation.delimiter
+[
+  "."
+  ","
+] @punctuation.delimiter
 
 "=" @operator
 
-"[" @punctuation.bracket
-"]" @punctuation.bracket
-"[[" @punctuation.bracket
-"]]" @punctuation.bracket
-"{" @punctuation.bracket
-"}" @punctuation.bracket
+[
+  "["
+  "]"
+  "[["
+  "]]"
+  "{"
+  "}"
+]  @punctuation.bracket

crates/zed/src/main.rs 🔗

@@ -169,11 +169,19 @@ fn main() {
         .detach();
 
         languages.set_language_server_download_dir(zed::ROOT_PATH.clone());
-        languages.set_theme(&settings.theme.editor.syntax);
+        let languages = Arc::new(languages);
+
+        cx.observe_global::<Settings, _>({
+            let languages = languages.clone();
+            move |settings, _| {
+                languages.set_theme(&settings.theme.editor.syntax);
+            }
+        })
+        .detach();
         cx.set_global(settings);
 
         let app_state = Arc::new(AppState {
-            languages: Arc::new(languages),
+            languages,
             themes,
             channel_list,
             client,

styles/src/styleTree/editor.ts 🔗

@@ -37,8 +37,18 @@ export default function editor(theme: Theme) {
     };
   }
 
+  const syntax: any = {};
+  for (const syntaxKey in theme.syntax) {
+    const style = theme.syntax[syntaxKey];
+    syntax[syntaxKey] = {
+      color: style.color.value,
+      weight: style.weight.value,
+      underline: style.underline,
+      italic: style.italic,
+    };
+  }
+
   return {
-    // textColor: theme.syntax.primary.color,
     textColor: theme.syntax.primary.color.value,
     background: backgroundColor(theme, 500),
     activeLineBackground: theme.editor.line.active.value,
@@ -125,22 +135,6 @@ export default function editor(theme: Theme) {
     invalidHintDiagnostic: diagnostic(theme, "muted"),
     invalidInformationDiagnostic: diagnostic(theme, "muted"),
     invalidWarningDiagnostic: diagnostic(theme, "muted"),
-    syntax: {
-      keyword: theme.syntax.keyword.color.value,
-      function: theme.syntax.function.color.value,
-      string: theme.syntax.string.color.value,
-      type: theme.syntax.type.color.value,
-      number: theme.syntax.number.color.value,
-      comment: theme.syntax.comment.color.value,
-      property: theme.syntax.property.color.value,
-      variant: theme.syntax.variant.color.value,
-      constant: theme.syntax.constant.color.value,
-      title: { color: theme.syntax.title.color.value, weight: "bold" },
-      emphasis: theme.textColor.feature.value,
-      "emphasis.strong": { color: theme.textColor.feature.value, weight: "bold" },
-      link_uri: { color: theme.syntax.linkUrl.color.value, underline: true },
-      link_text: { color: theme.syntax.linkText.color.value, italic: true },
-      list_marker: theme.syntax.punctuation.color.value,
-    },
+    syntax,
   };
 }

styles/src/themes/dark.ts 🔗

@@ -202,22 +202,22 @@ const syntax: Syntax = {
     weight: fontWeights.bold,
   },
   emphasis: {
-    color: textColor.active,
+    color: textColor.feature,
     weight: fontWeights.normal,
   },
-  emphasisStrong: {
-    color: textColor.active,
+  "emphasis.strong": {
+    color: textColor.feature,
     weight: fontWeights.bold,
   },
-  linkUrl: {
+  linkUri: {
     color: colors.lime[500],
     weight: fontWeights.normal,
-    // TODO: add underline
+    underline: true,
   },
   linkText: {
     color: colors.orange[500],
     weight: fontWeights.normal,
-    // TODO: add italic
+    italic: true,
   },
 };
 

styles/src/themes/light.ts 🔗

@@ -200,22 +200,22 @@ const syntax: Syntax = {
     weight: fontWeights.bold,
   },
   emphasis: {
-    color: textColor.active,
+    color: textColor.feature,
     weight: fontWeights.normal,
   },
-  emphasisStrong: {
-    color: textColor.active,
+  "emphasis.strong": {
+    color: textColor.feature,
     weight: fontWeights.bold,
   },
-  linkUrl: {
+  linkUri: {
     color: colors.lime[500],
     weight: fontWeights.normal,
-    // TODO: add underline
+    underline: true
   },
   linkText: {
     color: colors.red[500],
     weight: fontWeights.normal,
-    // TODO: add italic
+    italic: true
   },
 };
 

styles/src/themes/theme.ts 🔗

@@ -3,7 +3,9 @@ import { withOpacity } from "../utils/color";
 
 export interface SyntaxHighlightStyle {
   color: ColorToken;
-  weight: FontWeightToken;
+  weight?: FontWeightToken;
+  underline?: boolean,
+  italic?: boolean,
 }
 
 export interface Player {
@@ -49,12 +51,12 @@ export interface Syntax {
   number: SyntaxHighlightStyle;
   boolean: SyntaxHighlightStyle;
   predictive: SyntaxHighlightStyle;
-  // TODO: Either move the following or rename
   title: SyntaxHighlightStyle;
   emphasis: SyntaxHighlightStyle;
-  emphasisStrong: SyntaxHighlightStyle;
-  linkUrl: SyntaxHighlightStyle;
+  linkUri: SyntaxHighlightStyle;
   linkText: SyntaxHighlightStyle;
+
+  [key: string]: SyntaxHighlightStyle;
 };
 
 export default interface Theme {

styles/src/utils/snakeCase.ts 🔗

@@ -17,7 +17,7 @@ type SnakeCased<Type> = {
 export default function snakeCaseTree<T>(object: T): SnakeCased<T> {
   const snakeObject: any = {};
   for (const key in object) {
-    snakeObject[snakeCase(key)] = snakeCaseValue(object[key]);
+    snakeObject[snakeCase(key, { keepSpecialCharacters: true })] = snakeCaseValue(object[key]);
   }
   return snakeObject;
 }