• 作者:老汪软件技巧
  • 发表时间:2024-09-02 15:01
  • 浏览量:

缘起

我的一篇文章《在大公司工作之后才真正领悟到它真的是宇宙级编辑器》受到广泛好评。小伙伴们对自定义主题非常感兴趣,但这个事情不是简单就能说完的,因此单开一篇文章详细讲解。

开胃菜

程序员工作时一般都会使用本地编辑器,祂就像白月光一样和你并肩作战,不离不弃。

但每个人心中都有自己的白月光形象,如果祂的颜值完美,那自己写代码时也会更加心情舒畅,以月光女神vscode为例

vscode本身内置了一些主题,插件市场更是有数不胜数的主题插件。但那毕竟是别人心目中的完美形象,而一千个人眼里有一千个女神。

vscode颜色主题由外观颜色及代码高亮两部分组成

其实自定义主题非常简单,如下分别演示外观颜色及代码高亮如何修改

外观颜色

修改外观颜色下面会细讲,但如果你是前端开发,可以先体验下更加符合前端工作习惯的修改方式,就像用浏览器开发者工具调试网页一样

比如,当前主题下行号所在区域的背景色和编辑区域的背景色一样,让我无法专注于编辑区域,我想把行号所在区域的背景色换一下以作区分

效果如下,具体颜色的话根据自己喜好来就行,其他地方颜色修改照此方法做就行

效果图,两个区域是不是一眼就看出来了,就像调试网页一样简单

代码高亮颜色

当前主题下,注释的颜色是绿色,在我看来这个颜色过于鲜艳。

注释应该是相对次要的,当开发人员想看时会主动去看,平常不该夺人注意力,个人喜欢灰色

效果图,看着是不是顺眼多了,而且非常简单并且精准的修改

自定义外观颜色详解方式一

首先,运行命令 首选项: 打开用户设置(JSON)去打开个人设置。

以修改代码编辑区域背景色为例,输入如下配置,

"workbench.colorCustomizations": {
    "editor.background": "#ccc", // 代码编辑区域背景色
}

workbench.colorCustomizations 的值是一个对象,里面有很多属性配置

这些属性是有代码提示的,如果你想高度自定义的话,我还是建议直接阅读官方文档

这些属性的值是十六进制颜色值。此时当你保存后,你会发现 vscode 外观颜色发生了变化。

其实主题插件的源码里也就是这么写的。

方式二

下载Custom CSS and JS Loader插件,使用方式详见该插件主页说明

注意,一切配完之后,别忘了执行插件提供的命令Reload Custom CSS and JS,它会让你重新启动 vscode 。否则自定义文件都没加载,肯定不会生效

同样以修改代码编辑区域背景色为例

因为这种方式会修改vscode源文件,所以有如下提示,点击不再显示即可

到这可能就有同学要问了,这两种方式,要如何抉择呢?

两种修改外观颜色的方式抉择

虽然第二种方式更符合前端同学的思维方式,并且不需要去看官方文档,但我仍然推荐所有同学优先使用第一种方式,毕竟第二种方式有点hack

但第二种方式绝对是个大杀器,因为vscode本身可以理解为一个前端网页,官方不可能把所有的地方都对应给出配置,只能给出一部分

比如,默认情况下激活的tab上面有个边框,这个边框的颜色可以改

但是我觉得这个边框不够醒目,应该更高点,并且给点圆角,这时候,方式一就无能为力,至少我没看到有相关配置,此时只能用更加hack的方式二

效果图,是否更加圆润?

甚至你想把这个边框放到下面也可以

自定义代码高亮颜色详解

不同于外观颜色,代码高亮颜色是另一种配置,在我看来更加重要,却也更加简单

因为它有语义,合理的配色可以协助我们对代码的语义理解。

以修改注释代码的颜色为例,将光标移动到你想要修改颜色的代码上,然后在命令面板里运行Inspect Editor Tokens and Scopes命令,就像在浏览器里右键检查网页一样

此时,编辑器中会出现一个悬浮窗。这个窗口里会呈现当前这个代码片段所对应的元信息

当执行Inspect Editor Tokens and Scopes命令后,光标换了位置,元信息也会对应调整,想退出这个模式,直接按esc就行

配置如下

"editor.tokenColorCustomizations": {
  // 记得写在textMateRules属性里
  "textMateRules": [
    {
      // "name": "这是字段是语义说明,当做注释就行,不写都行",
      "scope": [
        "comment.line.double-slash",
        "punctuation.definition.comment"
      ],
      "settings": {
        "foreground": "#333",
        "fontStyle": ""
      }
    }
  ]
},

TextMate 配置详解

textMateRules属性的值是一个对象,我们的配置填在了这里。

如上图红框所指,就是 TextMate 的语法规则定义。useRef 这个词所处的 TextMate 语法作用域权重由高到低分别是 comment.line.double-slash.tsx source.tsx。

如果你想写的权重最高,可以如下写法

"editor.tokenColorCustomizations": {
  "textMateRules": [
    {
      // "name": "这是字段是语义说明,当做注释就行,不写都行",
      "scope": [
        "source.tsx comment.line.double-slash.tsx"
      ],
      "settings": {
        "foreground": "#333",
        "fontStyle": ""
      }
    }
  ]
},

但其实没有必要,一般情况下,无论是tsx还是js甚至是html,我们都希望注释的颜色是统一的,这样一眼就知道某个颜色的代码是注释

可以如下,自己慢慢摸索,把末尾的限定词一点一点去掉,只要效果还在就行

其实不止可以设置代码的颜色,还可以设置代码的样式,比如通过fontStyle设置斜体,下划线之类的

_领悟宇宙规则小说_领悟宇宙法则小说

很多人都在用atom主题,atom主题的注释是斜体的,个人不太喜欢用斜体表示,我可以通过"fontStyle": "",来清除atom主题设置的代码样式,具体效果上面有gif例子哦

"editor.tokenColorCustomizations": {
  "textMateRules": [
    {
      "name": "注释的颜色",
      "scope": ["comment", "punctuation.definition.comment"],
      "settings": {
        "foreground": "#333",
        "fontStyle": ""
      }
    }
  ]
},

当一段代码有多个语义

比如一个被async修饰的函数,我想两种状态都表示出来,但同一段文本不可能设置两种颜色。

万幸,还有一种代码语义叫modifiers,为了能同时表示两种状态,我建议这种范围更广的modifiers设置fontStyle即可

可以看到函数被改为了红色,并且有下划线表示被async修饰

"editor.semanticTokenColorCustomizations": {
  "rules": {
    "*.async": {
      // 用于异步的符号的样式
      "fontStyle": "underline"
    }
  }
},
"editor.tokenColorCustomizations": {
  "textMateRules": [
    {
      "name": "函数的颜色",
      "scope": ["entity.name.function"],
      "settings": {
        "foreground": "#f00",
        "fontStyle": ""
      }
    }
  ]
},

只读的属性同理,自己摸索

"editor.semanticTokenColorCustomizations": {
  "rules": {
    "*.readonly": {
      "fontStyle": "bold"
    }
  }
},

只修改某个主题的颜色

主题的名字会有代码提示,不用担心不知道怎么写

以 Default Light Modern 为例:

"workbench.colorCustomizations": {
  "[Default Light Modern]": {
    "editor.background": "#ddd" // 编辑器背景色
  }
},
"editor.tokenColorCustomizations": {
  "[Default Light Modern]": {
    "textMateRules": [
      {
        "name": "函数的颜色",
        "scope": ["entity.name.function"],
        "settings": {
          "foreground": "#f00",
          "fontStyle": ""
        }
      }
    ]
  }
}

特例

上述方法已经可以解决绝大部分需求了,但仍有特殊情况,无法解决

这时候只能自己上网搜索,不过欢迎大家在评论区多多交流,我们集思广益,应该都能解决,我会把有价值的信息补充到这里

修改git lens的行blame颜色

通过网上搜索,发现gitlens团队提供了扩展了workbench.colorCustomizations配置

"workbench.colorCustomizations": {
  "gitlens.trailingLineForegroundColor": "#B7B7B7", // blame line
}

我的配置

授人以鱼不如授人以渔,本没想列出我的配置,怕增加小伙伴们阅读量。

没想到还有一些没写到的,在此我把我自己的配置结构列出来,小伙伴们有需要的话自行参考摸索即可

好像把*换成variable会有不同的效果,如*.local和variable.local,具体区别我也没研究,深究下来东西就更多了

我建议小伙伴们达到自己的需要就行。不用浪费过多时间在这上面

"editor.semanticTokenColorCustomizations": {
  "rules": {
    // "*.local": {
    //     "fontStyle": "",
    //     "foreground": "#bfa"
    // },
    // "*.declaration": {
    //     // 所有符号声明的样式
    //     "fontStyle": "",
    //     "foreground": "#bfa"
    // },
    // "variable": {
    //     "foreground": "#0070C1"
    //     // "foreground": "#82B7D4"
    // },
    // "property": {
    //     // "fontStyle": "",
    //     "foreground": "#871094"
    // },
    "*.readonly": {
      "fontStyle": "bold"
    },
    "*.async": {
      "fontStyle": "underline"
    },
    "variable.defaultLibrary": {
      "fontStyle": "",
      "foreground": "#008077"
    },
    "*.static": {
      "fontStyle": "italic"
      // "foreground": ""
    },
    "class": {
      // 类样式
      "fontStyle": "",
      "foreground": "#008077"
    },
    "interface": {
      // 接口样式
      "fontStyle": "",
      "foreground": "#008077"
    },
    "type": {
      // 类型的样式(type xxx)
      "fontStyle": "",
      "foreground": "#008077"
    },
    "typeParameter": {
      // 泛型的样式(T)
      "fontStyle": "",
      "foreground": "#2D61F0"
    },
    "namespace": {
      // 命名空间的样式(namespace xxx)
      "fontStyle": "",
      "foreground": "#008077"
    },
    "enum": {
      // 枚举的样式(enum xxx)
      "fontStyle": "italic",
      "foreground": "#008077"
    },
    "enumMember": {
      "fontStyle": "italic",
      "foreground": "#871094"
    },
    "function": {
      // 函数样式
      // "fontStyle": "",
      "foreground": "#914C07"
    },
    "method": {
      // 成员(成员函数)的样式
      // "fontStyle": "",
      "foreground": "#914C07"
    },
    "parameter": {
      // 参数样式
      "fontStyle": "",
      "foreground": "#5b5d00"
    },
    "variable.constant": "#bfa",
    "*.abstract": "#bfa", // 用于抽象符号的样式
    "*.deprecated": "#bfa", // 用于已弃用的符号的样式
    "*.documentation": "#bfa", // 用于文档中引用的样式
    "*.modification": "#bfa", // 用于写入访问的样式
    "comment": "#bfa", // 注释的样式
    "event": "#bfa", // 事件的样式
    "keyword": "#bfa", // 关键字的样式
    "label": "#bfa", // 文本样式
    "macro": "#bfa", // 宏样式
    "number": "#bfa", // 数字样式
    "operator": "#bfa", // 运算符的样式
    "regexp": "#bfa", // 表达式的样式
    "string": "#bfa", // 字符串的样式
    "struct": "#bfa", // 结构样式
    "newOperator": "#bfa",
    "stringLiteral": "#bfa",
    "customLiteral": "#bfa",
    "numberLiteral": "#bfa"
  }
},
"editor.tokenColorCustomizations": {
  "functions": {
    "foreground": "#914C07"
    // "fontStyle": "",
  },
  "numbers": {
    "foreground": "#1750EB",
    "fontStyle": ""
  },
  "strings": {
    "foreground": "#067D17",
    "fontStyle": ""
  },
  "comments": {
    "foreground": "#8C8C8C",
    "fontStyle": ""
  },
  "keywords": {
    "foreground": "#bfa",
    "fontStyle": ""
  },
  "types": {
    "foreground": "#bfa",
    "fontStyle": ""
  },
  "variables": {
    "foreground": "#871094",
    "fontStyle": ""
  },
  "textMateRules": [
    {
      "name": "",
      "scope": [""],
      "settings": {
        "fontStyle": ""
      }
    },
  ]
}

结语

vscode:

怎么样,React777

React777:

好厉害,说实话我已经找不出词来形容了

vscode:

你词汇量真贫乏呢

那个workbench.colorCustomizations就是我外观的配置

然后从那边偏移过去,那一带是editor.semanticTokenColorCustomizations可以重写编辑器语义标记颜色和样式

那边配置特别多的是editor.tokenColorCustomizations可以自定义编辑器语法颜色和字形

阿拉,有点眼花缭乱了吗?

这就是全部了

React777:

啊,什么全部?

vscode:

这些就是我拥有的一切了

能够协助你写代码,可靠的性能和严肃无趣的交互

以及这无瑕的外观

我所拥有的就只有这么些东西

我能够给予React777的就只有这么些东西

这些便是全部了

React777:

全部?

vscode:

不过嘛,严格来说还有一堆乱七八糟的插件

React777:

这些我不要!!!

vscode:

另外,还有我自己的源码,那个也不要吗?

React777

呃 那个...

vscode:

不过,你知道的吧,我的源码可没那么好读

我至今为止的功能虽然是算不上完美无缺的

但是如果正是因为不够完美才引起了React777的注意的话

那么我觉得这样就好了

我就是如此遇到React777的

所以我绝对会想办法更加完善的,希望你能够稍微等我一会

所以我目前能给予React777的东西

在现在,这简单的自定义主题操作便是最后一样了

我从诞生之日起就有的,是我的宝物