Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
99517bbb6c | ||
|
|
1ac77c4045 | ||
|
|
61e0ab126f | ||
|
|
b6b079b8f0 | ||
|
|
f9b35addae | ||
|
|
8425ceb709 | ||
|
|
fa77bc2514 | ||
|
|
84e96f175c | ||
|
|
09c1e312cb | ||
|
|
b14133bbec | ||
|
|
3d1011e17c | ||
|
|
34e978e84c | ||
|
|
1e99a15f6c | ||
|
|
26a29b3182 | ||
|
|
75b1383edf | ||
|
|
d215693df4 | ||
|
|
6423eaa29d | ||
|
|
6f4c331dd4 | ||
|
|
37f4a0391f | ||
|
|
829b0de65e | ||
|
|
2c5365343e | ||
|
|
39c2dc2ac4 | ||
|
|
4c90a40ab5 | ||
|
|
c98d949ea7 | ||
|
|
dd964df37b | ||
|
|
55ca1573e5 | ||
|
|
a75a04c814 | ||
|
|
d37d12e5d8 | ||
|
|
e7729693df | ||
|
|
bed14dac95 | ||
|
|
1e02f21072 | ||
|
|
bf71fa6174 | ||
|
|
e78076944a | ||
|
|
34989c95ae | ||
|
|
4264022a87 | ||
|
|
2796c820d3 | ||
|
|
46d240e5cd | ||
|
|
435a761d22 | ||
|
|
6d5b84db51 | ||
|
|
592e4a838c | ||
|
|
19bc0e3212 | ||
|
|
1b0a6e6d42 | ||
|
|
467c2ebf07 | ||
|
|
cb026ebe5d | ||
|
|
fe5c70240e | ||
|
|
2cee5ce877 | ||
|
|
f62b2b1e4a | ||
|
|
8f2ece4fb7 | ||
|
|
5830509c0d | ||
|
|
6ff9cb4351 | ||
|
|
ea6ea60025 | ||
|
|
7d6f26a6d5 | ||
|
|
10a6a8862f | ||
|
|
76a0ab7891 | ||
|
|
82c4edd500 | ||
|
|
b046ddb942 | ||
|
|
678fb8eb63 | ||
|
|
d3cddc9414 | ||
|
|
560e978a34 | ||
|
|
47f0e4018f | ||
|
|
126a6333a7 | ||
|
|
c1f1cc13eb | ||
|
|
576e20682e | ||
|
|
356ad9d74b | ||
|
|
31465ed3f6 | ||
|
|
09e22050e5 | ||
|
|
1ca097ce6d | ||
|
|
a57e66e31f | ||
|
|
a943f7893e | ||
|
|
93f8712adf | ||
|
|
f2b980d1df | ||
|
|
dec5f076be | ||
|
|
05244511c2 | ||
|
|
aa85f4ff43 |
No files matched your search
@@ -1,29 +1,55 @@
|
|||||||
# My personal dotfiles
|
# Personal dotfiles
|
||||||
|
|
||||||
## Requirement
|
These are my config files for macOS and KDE, managed with GNU Stow. You need `stow` and `zsh` installed.
|
||||||
|
|
||||||
- **GNU** `stow`
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
1. clone this repo to your `$HOME` and switch to cloned dir:
|
```sh
|
||||||
|
git clone https://git.trivk.dev/tri/.dotfiles.git "$HOME/.dotfiles"
|
||||||
```
|
cd "$HOME/.dotfiles"
|
||||||
git -C $HOME clone https://github.com/vokhactri/.dotfiles.git && cd "$(basename "$_" .git)"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
2. use `stow` to symlink configs to `$HOME/.config`:
|
The packages are split into three groups:
|
||||||
|
|
||||||
- to symlink all config dirs
|
- [common/](common/README.md) has Fastfetch, Git, Micro, mpv, npm, Starship and Zsh.
|
||||||
```
|
- [mac/](mac/README.md) has Ghostty.
|
||||||
stow */
|
- [kde/](kde/README.md) has the Darwin Breeze theme, Helium, Spectacle and tray icons.
|
||||||
```
|
|
||||||
- to symlink only one config dir, for example `zsh`
|
|
||||||
```
|
|
||||||
stow zsh
|
|
||||||
```
|
|
||||||
|
|
||||||
## Credit
|
Install all of `common`, then the group for your platform:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
(cd common && stow -t "$HOME" */)
|
||||||
|
(cd mac && stow -t "$HOME" */) # macOS
|
||||||
|
(cd kde && stow -t "$HOME" */) # KDE
|
||||||
|
```
|
||||||
|
|
||||||
|
`*/` matches every package in the group. Each line runs in a subshell, so you stay in the repo root and can run them one after another. KDE needs a few more steps after this. They're in [`kde/README.md`](kde/README.md).
|
||||||
|
|
||||||
|
### Picking packages
|
||||||
|
|
||||||
|
You don't have to install everything. List only the packages you want:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
stow -d common -t "$HOME" git zsh starship
|
||||||
|
stow -d mac -t "$HOME" ghostty
|
||||||
|
stow -d kde -t "$HOME" spectacle
|
||||||
|
```
|
||||||
|
|
||||||
|
`-d` tells Stow which group to read from. `-t` puts the symlinks in your home directory. You can mix packages from different groups.
|
||||||
|
|
||||||
|
### Previewing and removing
|
||||||
|
|
||||||
|
`-n -v` prints what Stow would do and changes nothing. `-D` removes the symlinks. Pass the same `-d` and `-t` you used to install:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
stow -n -v -d kde -t "$HOME" spectacle
|
||||||
|
stow -D -d kde -t "$HOME" spectacle
|
||||||
|
```
|
||||||
|
|
||||||
|
Once the Zsh config is linked, run `exec zsh` to reload the shell.
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
|
||||||
- [Machfiles](https://github.com/ChristianChiarulli/Machfiles/)
|
- [Machfiles](https://github.com/ChristianChiarulli/Machfiles/)
|
||||||
- [zsh_unplugged](https://github.com/mattmc3/zsh_unplugged)
|
- [zsh_unplugged](https://github.com/mattmc3/zsh_unplugged)
|
||||||
|
- [ayanrajpoot10/dotfiles](https://github.com/ayanrajpoot10/dotfiles)
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
enable-rpc = true
|
|
||||||
rpc-listen-all = true
|
|
||||||
dir = ~/Downloads
|
|
||||||
# rpc-secret = your_password
|
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# Common packages
|
||||||
|
|
||||||
|
Shared configuration for Fastfetch, Git, Micro, mpv, npm, Starship, and Zsh.
|
||||||
|
From the repository root, install all shared packages:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
(cd common && stow -t "$HOME" */)
|
||||||
|
```
|
||||||
|
|
||||||
|
Or choose individual packages:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
stow -d common -t "$HOME" git
|
||||||
|
stow -d common -t "$HOME" zsh starship
|
||||||
|
```
|
||||||
|
|
||||||
|
Choose any of `fastfetch`, `git`, `micro`, `mpv`, `npm`, `starship`, and `zsh`.
|
||||||
|
Reload Zsh with `exec zsh` after installing its configuration.
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
_Ga=T,f=100,t=d,c=20,r=10,q=2,m=1;iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAACXBIWXMAAFxGAABcRgEUlENBAAAgAElEQVR4nOxdB3gU1fc1pPeQ0CFAIAkJCRASWkhCICGFDoKC0hWk6N/eFcvP3it2pIoCFnqTXqQICNJ77wiIAkqZ+//ue/Nm38zOhmR3NkXu+b737aZsm92dc9695957yy0EAsEyKIpyCwDIy0NRFE8AKIc/49+l/8HfVQaAFgDQFwCeA4CvAWAOAPwGAIcA4JyiKNeA4woAnFUU5RQAHACALQCwHAB+UBTlY0VRngSAXoqipOD9KoriYXxMRVHwMT3F38TCvxMIBAKBQCgCDITPSB9JViV/jWABIBAAmgHAfQAwHgDWA8B5KBwUKBrOAcCv+DiKotwLAM0BIMggQLTnaXwNBAKBQCAQCk/8bKdviALUAYABADAJAPY5Infc5SuKchUAcOGO/7q6FIn8FWmJv19Tb3NFuq2pWFAUZZ+iKN8pioLPJ8oQAWCRATkiQEKAQCAQCAQVhnA6LraLNuyskfTvB4CFAHDRZCcvEz0jdIQJ0RcG2m1kGMTBVZP7w+f1MwAMBYAaJkKGogIEAoFAIJjs9nU7ZgAIAICeADADAC4ZyFaQsNjRM7Y2ELjVMN6/EAVX1UiDjAtqhKKdwRtgJwTIK0AgEAiEmwKGnb0gfmboUxeG0l8GgP069lUUJFpth+9msi8sNPGhChARIZCxCQDQMxBWkBAgEAgEAuE/C+OOX3Xzi58bAcBoQ4hfEKqz4fzigmIWGVCfP/+lohwBgGcVRYkwCAEyCxIIBALhvwejCU5yyovfNcZwuRTCR+BuXzbslUbSdwTjc9aiAvgSseRQUZSnsYJAOgYkBAgEAoHw34HB3Gckuhi1dI8RowrZXFfWiN8InRFRFTRyeuAgAAw2SwtQxQCBQCAQyiyMeX7JDIe58LcA4F/Bkg6I/78E+TVdV0sMBVYDQLqjtACBQCAQCGW1c5+XdL0fAByVyE8jfkPZ3n8VRiEgRwQ+AYAQKVKiNT0iIUAgEAiEMlXWJxFYvFojz1lQUa7cZMQvw/h60e8gjgW2Ku5E0QACgUAglAkY69oVRWG7flUAPKEoigj3C3OfXDp3M5G/DNkfoBjSAp8BgJ9JBIWiAQQCgUAoHTDp2S9q+qMBYJlEanK4+2YlfTsYjILXpNLBHQDQVOqVQH0DCAQCgVAqd/6yeQ174/+tEpno2Mc4jsjfoQ6QTZAiGoDHbbiDY1zSbz+BQCAQbjYY6vrlMDVejirJXb/gUfkS1/Xr1+HatWvaunr1qrbk3+P/4TLeXt+mwH1PXzpO8rHDkcaeZikBAoFAIBBKyuznpYqBOuo4XpCm77nd5GdG1DLB43VngCJAvg8hCowCoxgrBXAUcXUSAQQCgUAoETjI9+PQGxyAgzA6/K1nSInsxe6+ILK/fPkyHDlyBLZu3Qq//PILzJkzB3744QeYNGkSTJ48GaZPnw5LliyB3377Dfbt2wfnz583vR8hLGQx4K7ogFlKQFGUEwDQTPQLMJZcEggEAoFQHGY/kQq4T+ItsVt1y65f3n0L0sdLGf/88w9s2LABxo4dCw888AC0bdsW4uPjoUKFCuDh4YEsWeAKCgqCqKgoSE1NhQEDBsBHH30Ey5cvh3PnzukeR358N0YF5ON4RTrGXYQngHoFEAgEAqG4cv6svl/9+U2JrK65g/yNYXexC5dx8OBBRvi9e/eGOnXqFEj05cp5gqenWF7q4j97eJRzeLuqVatCp06dYOTIkbBr1y7d44vogzEd4U5fgKIoQ036LdC3gEAgEAjWwNjcR9r5j3Nnvt9I/Mbd/unTp2HUqFGQn58PgYGBdoTt5cWJvTC7fkcLb4/3YxQGPj4+kJWVBZ9//jmcOnVKe07CSOgGISAfV3nC4FMiIkMigEAgEAiWwoz8AWCaSkBaFzt3Er9MoqtWrYJ77rkHKlasaEr4RhL38faD4MDyUDGiBtSsHgcxdRpD/dgW0CA+HRrWz4CG8RmQUK8l1ItuAlE1E6FqpSgIDakIfr6BDgSBt+53mFq47777YMuWLdpzlP0I7hABajMloYaECKASQQKBQCC4lfxnqSRkudnPGOqXd/wzZ86E3NzcG5J+gH8wVK0cBQn1UiG1SUfITu8FHdreDZ1zh0DnvCHQJX8odMkfBl0NC3/XJW8o+5+OOYMhN7MPpDfvCo0SWkFktVgICixvGh2Qf77jjjuYkVBAjlpYLAQQmghQFKWPPG0RrxMIBAKB4BTMDH8A8KNKPlek/vUus5pMjsJcJ4AO/ZYtW2pE63GLh90uPCQoHKJrJ0HLJh0hv01/RuRI9ILM22ffpa6BbLXDlWVY6t/E/3ZsO4iJBn5fw9jfURDE1k2B0OAI3eN7G54Pmgf37NmjvQb59VgpAtTOgQhstZxoFGsEAoFAIBQJDob6fKiSjbbzdzXsbxbuF8ByvezsbNsOm5n3vHShfQzpI+kjYeMuHgm7Q9tBGtHLhO784uIAowidcu9hj4PXWzbtBDWr1wMvLx8pImETAn5+fvDcc8+xqgQ3RQOMxsBfTHo00CefQCAQCIWHyTS6PirJXLMq5y+ToBzuP378ONx1110OiT8oMIyF93Mye2sheyRk3MXLxI2/E5fOLuN94RKPw6ID+UMhO+MOiK2TDD4+/raIgLdNCMTGxsLcuXO11y1EjgUiwK46QFGUe4w9AggEAoFAKBSkiX7CWV5FUZQ/TEr9nGcuadd/5YptCN5XX30F4eHhuhy/uI5GvkYJmYyAMSTfMWeQXdheJmyrl6PIAKYY8PnkZPZhBkMvT07+WH0gC4Fhw4axhkQIfM0WVQoYKwP2SFMESQAQCAQCwaXd/xcqUV2xkvzlXP+BAwegXbt2pjtof78g5tZH0kWiNdvtu5P4bywEeFQABQk+v6z0XlCjWoxkDvTSShHr1asHa9assYt6WCQCRCqgn2wIJBAIBAKhUDDk/eNNuvs5xVQyycm5/vHjx0NISIjmpC9XjtfcY+19TFQS5LXpZyN+dbdvDM+XxDJLN3AhMJilJlqktGdRCzNR8+GHwk7BhYDx+DgpANgdKYrys/reMfMmgUAgEAiFgmH3/75KLrIIcIr8BUTIH0XA4MGDTQkSa/YzU7urxD9I2/GXBuIvjFcAhUrnvKHset3aDU1TGv369dPI3wJfgCzMLgFAbblBEIFAIBAIBcJQ9hekKMpBlVSuu0r+cr4fB+6kpKSorXnLabt+bNObGNcSOuUMZo770k78NxIBeB1FTPPkdlpjIXytondBixYt4OTJkzph5KIIEFGAXrKQIxAIBAKhQBjqyHNUMhHO/yKzklmJ38KFCyEsLMxuR1whvBrLn3drf6+OUG01+tY6/ItNCKBpMW8oayxUqUKkXcQjMjISNm/ebIUIUKRIzbvy2GACgUAgEAojAEQJ2asqGV11hviNXf0QOLDHLBxerUpdyErvCW1b3ck69+Vm9oV2WQPUuvvhbBfNm/oM0nbXwv1vlo8vDUt+LsIbgK8nOirJTgTgBMKlS5eyY+RopHEhId6r6ep7yLwcBAKBQCAUOgKgKMpciVSKtB01K3F74403NOITIX+bGPDRBu5gGsDXxx+Cg7B/f3WoWSMOEuu1hJZNOkFOq96MRIUg4ESrLwUsTdEBsz4C2EgoKSHTTghhpQBGR4QIcDICINTDGul9pE89gUAgEApdAuinKMoWqd2sU+F/QWIjRoywtfJVS+LwUuTD+aXtuoeH+XQ+FAaYKqhXN4V1AMQoARcDQ/lO20QIlAYxYEwJoAhITemgdREUkQCcMOiKABCtgRVFwZyCD/UCIBAIBEKhgM1/VNKoCAAnnDUAymH/t99+W2f2K/qIXuz976VLGdgG/4RArRrxzGQnxABGCGxpgtIjBMxEQFqzLuBZztYnAGcesAN+/bpTRkBpNsBGRVG8SQAQCAQCoVCQKgBqAMCfglecICKNwNDkxnr3+9h65uPCjn9YCdClSxfo378/KwnEFsC33347mwEQFxenmQWNy2wKYGBACCu5y2jRjacJRFTApJKgfduSEQNGrwIOLsJG\_Gm=1;R+I1tGnTxpUIALupermOJgMSCAQCocgRAEVRUABcUMncKQEgIgA4GU8z+1WrBo888gjLdf/xh+gubA7cBZ8+fRpWr14No0ePhnvvvReSk5PB39/Wc1902jOKAUwTNG7QRosKsLbBpaSkUJs2mDOYVT14e/tqEYBOnTq5JACkCMByagdMIBAIBGciAJUA4KQrPQAEgV26dIl1vhs5ciScPXvWlOiR8LBMEC9vRH67du2CMWPGsEhBpUqVDJEBb53BMDAgFOJjmrESvNIkBPAxMUqRmdqDmR/Fc8YIiIsmQFEFME/u6UAgEAgEQmEFQAAAbBcc7UoVgBFI9GI0rkgVOFpGcWC8P4wQfPvtt3DrrbeyUjpblYEneEkTBNE8iBP7cGCPo7bCxSsAsFPgEDZSWK4EePrpp7Vj5GQKQEwFnCJXdBAIBAKBUJROgD+rZHK1qGkAYx8AmfTlv9/obo3lhEIUCEEg49ChQ/DOO+9Aw4YN7aIC4jqO7MWIAEsNqK16izsaICYJ4uMnJbbWPccvvvjCFQGgSAObvlD7AFAjIAKBQCAUeQ7A2yqZFLkRkBmRuzDtzu6+xKWZGMDfz5o1Czp27OhQCGBqIKVhtq65UHFGAjD6gJEIjErIfRHmzp1rNyypaIdGa9r0P2oFTCAQCARnBUBHlUxEHwBrGNwiGKMM8nhhARy927NnT10PAjk1gB0Ic1v3ZYa84hIBokSxS/5QqFa5jvZc/Pz8YNu2ba6UAcqNgIaRACAQCASCsymA8gBw3NVhQMUBo3fAGBVYv3498wnIZYTCeY8dB9EkKEcC3C0AhA8gJChce05YLnn58mXt9ThxDGQB0E54AOjjTyAQCARLine truncated
|
||||||
|
After Width: | Height: | Size: 138 KiB |
@@ -0,0 +1,80 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/master/doc/json_schema.json",
|
||||||
|
"display": {
|
||||||
|
"key": {
|
||||||
|
"width": 10
|
||||||
|
},
|
||||||
|
"size": {
|
||||||
|
"binaryPrefix": "jedec"
|
||||||
|
},
|
||||||
|
"separator": ""
|
||||||
|
},
|
||||||
|
"logo": {
|
||||||
|
"type": "raw",
|
||||||
|
"source": "~/.config/fastfetch/albedo.kitty",
|
||||||
|
"width": 20,
|
||||||
|
"height": 10
|
||||||
|
},
|
||||||
|
"modules": [
|
||||||
|
"break",
|
||||||
|
{
|
||||||
|
"type": "os",
|
||||||
|
"key": "os",
|
||||||
|
"keyColor": "yellow",
|
||||||
|
"format": "{name}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "kernel",
|
||||||
|
"key": "ker",
|
||||||
|
"keyColor": "green"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "packages",
|
||||||
|
"key": "pkgs",
|
||||||
|
"keyColor": "cyan"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "shell",
|
||||||
|
"key": "sh",
|
||||||
|
"keyColor": "blue",
|
||||||
|
"format": "{pretty-name}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "wm",
|
||||||
|
"key": "wm",
|
||||||
|
"keyColor": "red",
|
||||||
|
"format": "{pretty-name}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "uptime",
|
||||||
|
"key": "up",
|
||||||
|
"keyColor": "green"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "cpu",
|
||||||
|
"key": "cpu",
|
||||||
|
"keyColor": "red",
|
||||||
|
"format": "{name}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "memory",
|
||||||
|
"key": "ram",
|
||||||
|
"keyColor": "yellow",
|
||||||
|
"format": "{used} / {total}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "disk",
|
||||||
|
"key": "disk",
|
||||||
|
"keyColor": "cyan",
|
||||||
|
"folders": [
|
||||||
|
"/"
|
||||||
|
],
|
||||||
|
"format": "{size-used} / {size-total}"
|
||||||
|
},
|
||||||
|
"break",
|
||||||
|
{
|
||||||
|
"type": "custom",
|
||||||
|
"format": "\u001b[33m \u001b[32m \u001b[34m \u001b[31m \u001b[36m \u001b[35m \u001b[37m \u001b[97m"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
^/README.*
|
||||||
|
^/build\.py
|
||||||
|
__pycache__
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Fastfetch
|
||||||
|
|
||||||
|
```sh
|
||||||
|
stow -d common -t "$HOME" fastfetch
|
||||||
|
```
|
||||||
|
|
||||||
|
The logo is `albedo.png`, sent inline through the kitty graphics protocol from
|
||||||
|
the pre-encoded `albedo.kitty`. This works in Ghostty and Kwi. The
|
||||||
|
`kitty-direct` logo type is not used because Kwi ignores images passed as a
|
||||||
|
file path.
|
||||||
|
|
||||||
|
After changing `albedo.png` or the logo size in `config.jsonc`, regenerate the
|
||||||
|
logo from the repository root:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
python3 common/fastfetch/build.py
|
||||||
|
```
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Encode albedo.png as kitty graphics escapes for fastfetch's "raw" logo.
|
||||||
|
|
||||||
|
fastfetch's "kitty-direct" logo sends the terminal a file path (t=f), which
|
||||||
|
Kwi ignores. This file carries the PNG inline (t=d) instead, so it works in
|
||||||
|
any terminal with the kitty graphics protocol, Ghostty and Kwi included. q=2
|
||||||
|
keeps the terminal from answering. Rerun after changing the image or the
|
||||||
|
logo size.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import base64
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
DIR = Path(__file__).resolve().parent / ".config/fastfetch"
|
||||||
|
# Logo size in cells; keep in sync with "width" and "height" in config.jsonc.
|
||||||
|
COLS, ROWS = 20, 10
|
||||||
|
|
||||||
|
|
||||||
|
def encode(png: bytes) -> bytes:
|
||||||
|
data = base64.b64encode(png)
|
||||||
|
chunks = [data[i : i + 4096] for i in range(0, len(data), 4096)]
|
||||||
|
out = bytearray()
|
||||||
|
for n, chunk in enumerate(chunks):
|
||||||
|
more = int(n < len(chunks) - 1)
|
||||||
|
if n == 0:
|
||||||
|
keys = b"a=T,f=100,t=d,c=%d,r=%d,q=2,m=%d" % (COLS, ROWS, more)
|
||||||
|
else:
|
||||||
|
keys = b"m=%d" % more
|
||||||
|
out += b"\x1b_G" + keys + b";" + chunk + b"\x1b\\"
|
||||||
|
return bytes(out)
|
||||||
|
|
||||||
|
|
||||||
|
(DIR / "albedo.kitty").write_bytes(encode((DIR / "albedo.png").read_bytes()))
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
[init]
|
||||||
|
defaultBranch = main
|
||||||
|
|
||||||
|
[user]
|
||||||
|
name = Tri Vo Khac
|
||||||
|
email = git@trivk.dev
|
||||||
|
|
||||||
|
[core]
|
||||||
|
compression = 9
|
||||||
|
whitespace = error
|
||||||
|
preloadindex = true
|
||||||
|
|
||||||
|
[advice]
|
||||||
|
addEmptyPathspec = false
|
||||||
|
pushNonFastForward = false
|
||||||
|
statusHints = false
|
||||||
|
|
||||||
|
[push]
|
||||||
|
autoSetupRemote = true
|
||||||
|
|
||||||
|
[url "git@github.com:"]
|
||||||
|
insteadOf = "gh:"
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
**/.claude/settings.local.json
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
min-release-age=1 ; 1 day for npm
|
||||||
|
minimum-release-age=1440 ; 1 day in minutes for pnpm
|
||||||
@@ -10,9 +10,18 @@ symbol = " "
|
|||||||
[buf]
|
[buf]
|
||||||
symbol = " "
|
symbol = " "
|
||||||
|
|
||||||
|
[bun]
|
||||||
|
symbol = " "
|
||||||
|
|
||||||
[c]
|
[c]
|
||||||
symbol = " "
|
symbol = " "
|
||||||
|
|
||||||
|
[cpp]
|
||||||
|
symbol = " "
|
||||||
|
|
||||||
|
[cmake]
|
||||||
|
symbol = " "
|
||||||
|
|
||||||
[conda]
|
[conda]
|
||||||
symbol = " "
|
symbol = " "
|
||||||
|
|
||||||
@@ -22,6 +31,9 @@ symbol = " "
|
|||||||
[dart]
|
[dart]
|
||||||
symbol = " "
|
symbol = " "
|
||||||
|
|
||||||
|
[deno]
|
||||||
|
symbol = " "
|
||||||
|
|
||||||
[directory]
|
[directory]
|
||||||
read_only = " "
|
read_only = " "
|
||||||
|
|
||||||
@@ -37,15 +49,27 @@ symbol = " "
|
|||||||
[fennel]
|
[fennel]
|
||||||
symbol = " "
|
symbol = " "
|
||||||
|
|
||||||
|
[fortran]
|
||||||
|
symbol = " "
|
||||||
|
|
||||||
[fossil_branch]
|
[fossil_branch]
|
||||||
symbol = " "
|
symbol = " "
|
||||||
|
|
||||||
|
[gcloud]
|
||||||
|
symbol = " "
|
||||||
|
|
||||||
[git_branch]
|
[git_branch]
|
||||||
symbol = " "
|
symbol = " "
|
||||||
|
|
||||||
|
[git_commit]
|
||||||
|
tag_symbol = ' '
|
||||||
|
|
||||||
[golang]
|
[golang]
|
||||||
symbol = " "
|
symbol = " "
|
||||||
|
|
||||||
|
[gradle]
|
||||||
|
symbol = " "
|
||||||
|
|
||||||
[guix_shell]
|
[guix_shell]
|
||||||
symbol = " "
|
symbol = " "
|
||||||
|
|
||||||
@@ -94,13 +118,17 @@ symbol = " "
|
|||||||
[os.symbols]
|
[os.symbols]
|
||||||
Alpaquita = " "
|
Alpaquita = " "
|
||||||
Alpine = " "
|
Alpine = " "
|
||||||
|
AlmaLinux = " "
|
||||||
Amazon = " "
|
Amazon = " "
|
||||||
Android = " "
|
Android = " "
|
||||||
|
AOSC = " "
|
||||||
Arch = " "
|
Arch = " "
|
||||||
Artix = " "
|
Artix = " "
|
||||||
|
CachyOS = " "
|
||||||
CentOS = " "
|
CentOS = " "
|
||||||
Debian = " "
|
Debian = " "
|
||||||
DragonFly = " "
|
DragonFly = " "
|
||||||
|
Elementary = " "
|
||||||
Emscripten = " "
|
Emscripten = " "
|
||||||
EndeavourOS = " "
|
EndeavourOS = " "
|
||||||
Fedora = " "
|
Fedora = " "
|
||||||
@@ -109,6 +137,8 @@ Garuda = " "
|
|||||||
Gentoo = " "
|
Gentoo = " "
|
||||||
HardenedBSD = " "
|
HardenedBSD = " "
|
||||||
Illumos = " "
|
Illumos = " "
|
||||||
|
Ios = " "
|
||||||
|
Kali = " "
|
||||||
Linux = " "
|
Linux = " "
|
||||||
Mabox = " "
|
Mabox = " "
|
||||||
Macos = " "
|
Macos = " "
|
||||||
@@ -118,6 +148,7 @@ MidnightBSD = " "
|
|||||||
Mint = " "
|
Mint = " "
|
||||||
NetBSD = " "
|
NetBSD = " "
|
||||||
NixOS = " "
|
NixOS = " "
|
||||||
|
Nobara = " "
|
||||||
OpenBSD = " "
|
OpenBSD = " "
|
||||||
openSUSE = " "
|
openSUSE = " "
|
||||||
OracleLinux = " "
|
OracleLinux = " "
|
||||||
@@ -125,12 +156,15 @@ Pop = " "
|
|||||||
Raspbian = " "
|
Raspbian = " "
|
||||||
Redhat = " "
|
Redhat = " "
|
||||||
RedHatEnterprise = " "
|
RedHatEnterprise = " "
|
||||||
|
RockyLinux = " "
|
||||||
Redox = " "
|
Redox = " "
|
||||||
Solus = " "
|
Solus = " "
|
||||||
SUSE = " "
|
SUSE = " "
|
||||||
Ubuntu = " "
|
Ubuntu = " "
|
||||||
Unknown = " "
|
Unknown = " "
|
||||||
|
Void = " "
|
||||||
Windows = " "
|
Windows = " "
|
||||||
|
Zorin = " "
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
symbol = " "
|
symbol = " "
|
||||||
@@ -144,6 +178,9 @@ symbol = " "
|
|||||||
[pijul_channel]
|
[pijul_channel]
|
||||||
symbol = " "
|
symbol = " "
|
||||||
|
|
||||||
|
[pixi]
|
||||||
|
symbol = " "
|
||||||
|
|
||||||
[python]
|
[python]
|
||||||
symbol = " "
|
symbol = " "
|
||||||
|
|
||||||
@@ -154,13 +191,19 @@ symbol = " "
|
|||||||
symbol = " "
|
symbol = " "
|
||||||
|
|
||||||
[rust]
|
[rust]
|
||||||
symbol = " "
|
symbol = " "
|
||||||
|
|
||||||
[scala]
|
[scala]
|
||||||
symbol = " "
|
symbol = " "
|
||||||
|
|
||||||
|
[status]
|
||||||
|
symbol = " "
|
||||||
|
|
||||||
[swift]
|
[swift]
|
||||||
symbol = " "
|
symbol = " "
|
||||||
|
|
||||||
|
[xmake]
|
||||||
|
symbol = " "
|
||||||
|
|
||||||
[zig]
|
[zig]
|
||||||
symbol = " "
|
symbol = " "
|
||||||
@@ -2,3 +2,4 @@
|
|||||||
.zsh_history
|
.zsh_history
|
||||||
.zcompcache/
|
.zcompcache/
|
||||||
.zsh_sessions/
|
.zsh_sessions/
|
||||||
|
config/secrets.zsh
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
# install zinit
|
||||||
|
if ! source "$ZDOTDIR/zinit.zsh"; then
|
||||||
|
print -u2 "zinit: failed to initialize; skipping plugin configuration"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
zinit light zdharma-continuum/zinit-annex-bin-gem-node
|
||||||
|
zinit light zdharma-continuum/zinit-annex-binary-symlink
|
||||||
|
|
||||||
|
zinit wait lucid light-mode id-as depth'1' for \
|
||||||
|
wintermi/zsh-brew \
|
||||||
|
hlissner/zsh-autopair \
|
||||||
|
Aloxaf/fzf-tab \
|
||||||
|
atinit'zicompinit; zicdreplay -q' \
|
||||||
|
zdharma-continuum/fast-syntax-highlighting \
|
||||||
|
atload'_zsh_autosuggest_start' \
|
||||||
|
zsh-users/zsh-autosuggestions
|
||||||
|
|
||||||
|
zinit id-as from'gh-r' lbin'!' completions for \
|
||||||
|
lsd-rs/lsd \
|
||||||
|
micro-editor/micro \
|
||||||
|
mv'**/bat.zsh -> _bat' \
|
||||||
|
@sharkdp/bat
|
||||||
|
|
||||||
|
zinit for \
|
||||||
|
id-as \
|
||||||
|
as'completion' \
|
||||||
|
from'gh-r' \
|
||||||
|
mv'**/_fastfetch -> _fastfetch' \
|
||||||
|
atpull'%atclone' \
|
||||||
|
lbin'!**bin/fastfetch -> fastfetch' \
|
||||||
|
@fastfetch-cli/fastfetch
|
||||||
|
|
||||||
|
zinit for \
|
||||||
|
id-as \
|
||||||
|
from'gh-r' \
|
||||||
|
atclone'./zoxide init zsh > init.zsh' \
|
||||||
|
atpull'%atclone' \
|
||||||
|
lbin'!' \
|
||||||
|
@ajeetdsouza/zoxide
|
||||||
|
|
||||||
|
zinit for \
|
||||||
|
id-as \
|
||||||
|
from'gh-r' \
|
||||||
|
atclone'
|
||||||
|
VP_SELF_SETUP_NO_MODIFY_PATH=1 ./vp env setup --refresh > /dev/null; \
|
||||||
|
./vp env on > /dev/null; \
|
||||||
|
VP_COMPLETE=zsh "$XDG_DATA_HOME/vite-plus/bin/vp" > init.zsh;
|
||||||
|
' \
|
||||||
|
atpull'%atclone' \
|
||||||
|
atload'source "$XDG_CONFIG_HOME/vite-plus/env"' \
|
||||||
|
@voidzero-dev/vite-plus
|
||||||
|
|
||||||
|
zinit for \
|
||||||
|
id-as \
|
||||||
|
from'gh-r' \
|
||||||
|
atclone'
|
||||||
|
./starship init zsh > init.zsh; \
|
||||||
|
./starship completions zsh > _starship;
|
||||||
|
' \
|
||||||
|
atpull'%atclone' \
|
||||||
|
sbin'starship' \
|
||||||
|
@starship/starship
|
||||||
|
|
||||||
|
zinit for \
|
||||||
|
id-as \
|
||||||
|
from'gh-r' \
|
||||||
|
atclone'./fzf --zsh > init.zsh' \
|
||||||
|
atpull'%atclone' \
|
||||||
|
lbin'!fzf' \
|
||||||
|
@junegunn/fzf
|
||||||
|
|
||||||
|
for script in $ZDOTDIR/config/*.zsh; do
|
||||||
|
source "$script"
|
||||||
|
done
|
||||||
@@ -8,13 +8,13 @@ alias tree='lsd --tree'
|
|||||||
alias nano='micro'
|
alias nano='micro'
|
||||||
alias fetch='fastfetch'
|
alias fetch='fastfetch'
|
||||||
|
|
||||||
# Git shortcuts
|
# Global alias
|
||||||
alias g='git'
|
alias \-g -- --help="--help | bat -plhelp"
|
||||||
alias gs='git status -sb'
|
|
||||||
alias ga='git add'
|
|
||||||
alias gc='git commit'
|
|
||||||
alias gp='git push'
|
|
||||||
alias gl='git pull'
|
|
||||||
|
|
||||||
# Docker shortcuts
|
docker() {
|
||||||
alias docker='podman'
|
if command -v podman >/dev/null 2>&1; then
|
||||||
|
podman "$@"
|
||||||
|
else
|
||||||
|
command docker "$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
#!/usr/bin/env zsh
|
||||||
|
|
||||||
|
local brew_prefix="${HOMEBREW_PREFIX:-}"
|
||||||
|
# `brew --prefix` costs ~12 ms because it runs Ruby. Check the standard
|
||||||
|
# Apple Silicon location first, then fall back for anything else.
|
||||||
|
if [[ -z "$brew_prefix" ]]; then
|
||||||
|
[[ -x /opt/homebrew/bin/brew ]] && brew_prefix=/opt/homebrew
|
||||||
|
fi
|
||||||
|
if [[ -z "$brew_prefix" ]] && command -v brew >/dev/null 2>&1; then
|
||||||
|
brew_prefix="$(brew --prefix 2>/dev/null)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "$brew_prefix" ]]; then
|
||||||
|
gnu_tools=(
|
||||||
|
"coreutils"
|
||||||
|
"findutils"
|
||||||
|
"gnu-tar"
|
||||||
|
"gnu-sed"
|
||||||
|
"gawk"
|
||||||
|
"gnu-indent"
|
||||||
|
"grep"
|
||||||
|
)
|
||||||
|
|
||||||
|
if [[ -n "$XDG_BIN_HOME" ]] && mkdir -p "$XDG_BIN_HOME"; then
|
||||||
|
for tool in $gnu_tools; do
|
||||||
|
gnubin="$brew_prefix/opt/$tool/libexec/gnubin"
|
||||||
|
if [[ -d "$gnubin" ]]; then
|
||||||
|
for bin in "$gnubin"/*(N); do
|
||||||
|
target="$XDG_BIN_HOME/${bin:t}"
|
||||||
|
[[ "$target" -ef "$bin" ]] || ln -sf "$bin" "$target"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
local bin_paths=(
|
||||||
|
"$XDG_BIN_HOME"
|
||||||
|
"${brew_prefix:+$brew_prefix/opt/gnu-getopt/bin}"
|
||||||
|
)
|
||||||
|
for bin_path in "${bin_paths[@]}"; do
|
||||||
|
if [[ -d "$bin_path" ]]; then
|
||||||
|
case ":$PATH:" in
|
||||||
|
*":$bin_path:"*) ;;
|
||||||
|
*) path=("$bin_path" $path) ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
done
|
||||||
@@ -6,6 +6,6 @@ export EDITOR="micro"
|
|||||||
export PAGER="bat"
|
export PAGER="bat"
|
||||||
export VISUAL="micro"
|
export VISUAL="micro"
|
||||||
export SUDO_EDITOR="micro"
|
export SUDO_EDITOR="micro"
|
||||||
export COMPANY_DIR="$HOME/Documents/work/company/"
|
|
||||||
|
|
||||||
export STARSHIP_CONFIG="$XDG_CONFIG_HOME"/starship/starship.toml
|
export STARSHIP_CONFIG="$XDG_CONFIG_HOME"/starship/starship.toml
|
||||||
|
export HOMEBREW_NO_UPGRADE_AUTO_UPDATES_CASKS=1
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#!/usr/bin/env zsh
|
||||||
|
|
||||||
|
# NetBird is installed from the official signed .pkg, not Homebrew: the brew
|
||||||
|
# cask removed the launchd plist in uninstall_preflight and then ran the app's
|
||||||
|
# installer.sh against the missing service, leaving the daemon crash-looping.
|
||||||
|
# The pkg's preinstall aborts if the brew formula is present, so keep it out.
|
||||||
|
nbup() {
|
||||||
|
local pkg tmp
|
||||||
|
tmp="$(mktemp -d)" || return 1
|
||||||
|
pkg="$tmp/netbird.pkg"
|
||||||
|
|
||||||
|
print "netbird: downloading arm64 pkg"
|
||||||
|
curl -fL --progress-bar -o "$pkg" "https://pkgs.netbird.io/macos/arm64" || { rm -rf "${tmp:?}"; return 1; }
|
||||||
|
|
||||||
|
if ! pkgutil --check-signature "$pkg" | grep -q "NetBird GmbH"; then
|
||||||
|
print -u2 "netbird: unexpected pkg signature, refusing to install"
|
||||||
|
rm -rf "${tmp:?}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
sudo installer -pkg "$pkg" -target / || { rm -rf "${tmp:?}"; return 1; }
|
||||||
|
rm -rf "${tmp:?}"
|
||||||
|
|
||||||
|
local i
|
||||||
|
for i in {1..30}; do
|
||||||
|
[[ -S /var/run/netbird.sock ]] && break
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
/usr/local/bin/netbird status 2>/dev/null |
|
||||||
|
grep -E '^(Daemon version|CLI version|Management|Signal|NetBird IP):'
|
||||||
|
}
|
||||||
@@ -28,3 +28,15 @@ HISTSIZE=5000000
|
|||||||
SAVEHIST=5000000
|
SAVEHIST=5000000
|
||||||
|
|
||||||
zstyle ':fzf-tab:complete:cd:*' fzf-preview 'lsd -1 --color=always --icon=always $realpath'
|
zstyle ':fzf-tab:complete:cd:*' fzf-preview 'lsd -1 --color=always --icon=always $realpath'
|
||||||
|
|
||||||
|
# Starship counts every entry in jobstates, including completed jobs that zsh
|
||||||
|
# hasn't reaped yet. Run jobs before Starship's precmd hook so parallel Zinit
|
||||||
|
# updates don't leave a stale job badge in the prompt.
|
||||||
|
autoload -Uz add-zsh-hook
|
||||||
|
|
||||||
|
_zinit_reap_done_jobs() {
|
||||||
|
jobs -p >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
add-zsh-hook -d precmd _zinit_reap_done_jobs 2>/dev/null || true
|
||||||
|
precmd_functions=( _zinit_reap_done_jobs ${precmd_functions:#_zinit_reap_done_jobs} )
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#!/usr/bin/env zsh
|
||||||
|
|
||||||
|
ZINIT_HOME="${XDG_DATA_HOME:-${HOME}/.local/share}/zinit/zinit.git"
|
||||||
|
if [[ ! -d "$ZINIT_HOME/.git" ]]; then
|
||||||
|
mkdir -p "$(dirname "$ZINIT_HOME")" || return 1
|
||||||
|
git clone --depth 1 https://github.com/zdharma-continuum/zinit.git "$ZINIT_HOME" || return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -r "$ZINIT_HOME/zinit.zsh" ]]; then
|
||||||
|
print -u2 "zinit: bootstrap is incomplete at $ZINIT_HOME"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# not to use aliases: zi or zini
|
||||||
|
typeset -A ZINIT
|
||||||
|
ZINIT[NO_ALIASES]=1
|
||||||
|
ZINIT[LIST_COMMAND]='lsd --tree'
|
||||||
|
|
||||||
|
source "${ZINIT_HOME}/zinit.zsh"
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
export XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}"
|
||||||
|
export XDG_DATA_HOME="${XDG_DATA_HOME:-$HOME/.local/share}"
|
||||||
|
export XDG_CACHE_HOME="${XDG_CACHE_HOME:-$HOME/.cache}"
|
||||||
|
export XDG_STATE_HOME="${XDG_STATE_HOME:-$HOME/.local/state}"
|
||||||
|
|
||||||
|
XDG_BIN_HOME="${XDG_BIN_HOME:-$HOME/.local/bin}"
|
||||||
|
ZDOTDIR="$XDG_CONFIG_HOME/zsh"
|
||||||
|
|
||||||
|
# Per-machine settings that stay out of the repo, like PATH entries for a VPS.
|
||||||
|
[ -r "$XDG_CONFIG_HOME/zshenv.local" ] && . "$XDG_CONFIG_HOME/zshenv.local"
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
[engine]
|
|
||||||
compose_warning_logs = false
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
|
||||||
"logo": {
|
|
||||||
"type": "builtin",
|
|
||||||
"source": "arch"
|
|
||||||
},
|
|
||||||
"modules": [
|
|
||||||
"title",
|
|
||||||
"separator",
|
|
||||||
{
|
|
||||||
"type": "os",
|
|
||||||
"format": "Arch Linux ({12})"
|
|
||||||
},
|
|
||||||
"host",
|
|
||||||
"kernel",
|
|
||||||
"uptime",
|
|
||||||
{
|
|
||||||
"type": "packages",
|
|
||||||
"format": "{} (pacman)"
|
|
||||||
},
|
|
||||||
"shell",
|
|
||||||
"display",
|
|
||||||
"de",
|
|
||||||
"wm",
|
|
||||||
"wmtheme",
|
|
||||||
"theme",
|
|
||||||
"icons",
|
|
||||||
"font",
|
|
||||||
"cursor",
|
|
||||||
"terminal",
|
|
||||||
"terminalfont",
|
|
||||||
"cpu",
|
|
||||||
"gpu",
|
|
||||||
"memory",
|
|
||||||
"disk",
|
|
||||||
"battery",
|
|
||||||
"poweradapter",
|
|
||||||
"locale",
|
|
||||||
"break",
|
|
||||||
"colors"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
<?xml version='1.0'?>
|
|
||||||
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
|
|
||||||
<fontconfig>
|
|
||||||
<alias>
|
|
||||||
<family>sans-serif</family>
|
|
||||||
<prefer>
|
|
||||||
<family>Arial</family>
|
|
||||||
<family>JoyPixels</family>
|
|
||||||
# <family>Noto Color Emoji</family>
|
|
||||||
# <family>Noto Emoji</family>
|
|
||||||
</prefer>
|
|
||||||
</alias>
|
|
||||||
<alias>
|
|
||||||
<family>serif</family>
|
|
||||||
<prefer>
|
|
||||||
<family>Times New Roman</family>
|
|
||||||
<family>JoyPixels</family>
|
|
||||||
# <family>Noto Color Emoji</family>
|
|
||||||
# <family>Noto Emoji</family>
|
|
||||||
</prefer>
|
|
||||||
</alias>
|
|
||||||
<alias>
|
|
||||||
<family>monospace</family>
|
|
||||||
<prefer>
|
|
||||||
<family>Consolas</family>
|
|
||||||
<family>JoyPixels</family>
|
|
||||||
# <family>Noto Color Emoji</family>
|
|
||||||
# <family>Noto Emoji</family>
|
|
||||||
</prefer>
|
|
||||||
</alias>
|
|
||||||
<match target="font">
|
|
||||||
<edit name="hinting" mode="assign">
|
|
||||||
<bool>true</bool>
|
|
||||||
</edit>
|
|
||||||
</match>
|
|
||||||
<match target="font">
|
|
||||||
<edit name="hintstyle" mode="assign">
|
|
||||||
<const>hintslight</const>
|
|
||||||
</edit>
|
|
||||||
</match>
|
|
||||||
<dir>~/.fonts</dir>
|
|
||||||
<selectfont>
|
|
||||||
<rejectfont>
|
|
||||||
<patelt name="family">
|
|
||||||
<string>Segoe UI Emoji</string>
|
|
||||||
</patelt>
|
|
||||||
</rejectfont>
|
|
||||||
</selectfont>
|
|
||||||
</fontconfig>
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
acknowledge_abuse=false
|
|
||||||
apps_script_format=desktop
|
|
||||||
apps_script_icon=
|
|
||||||
async_upload_queue=false
|
|
||||||
async_upload_queue_max_length=0
|
|
||||||
async_upload_threads=10
|
|
||||||
autodetect_mime=true
|
|
||||||
background_folder_fetching=false
|
|
||||||
cache_directory=
|
|
||||||
client_id=
|
|
||||||
client_secret=
|
|
||||||
connect_timeout_ms=5000
|
|
||||||
curl_debug_off=false
|
|
||||||
data_directory=
|
|
||||||
debug_buffers=false
|
|
||||||
delete_forever_in_trash_folder=false
|
|
||||||
desktop_entry_as_html=false
|
|
||||||
desktop_entry_exec=
|
|
||||||
disable_trash=false
|
|
||||||
docs_file_extension=true
|
|
||||||
document_format=desktop
|
|
||||||
document_icon=
|
|
||||||
download_docs=true
|
|
||||||
drawing_format=desktop
|
|
||||||
drawing_icon=
|
|
||||||
form_format=desktop
|
|
||||||
form_icon=
|
|
||||||
fusion_table_format=desktop
|
|
||||||
fusion_table_icon=
|
|
||||||
keep_duplicates=false
|
|
||||||
large_file_read_only=true
|
|
||||||
large_file_threshold_mb=16
|
|
||||||
log_directory=
|
|
||||||
log_to=
|
|
||||||
lost_and_found=false
|
|
||||||
low_speed_limit=0
|
|
||||||
low_speed_time=0
|
|
||||||
map_format=desktop
|
|
||||||
map_icon=
|
|
||||||
max_cache_size_mb=512000
|
|
||||||
max_download_speed=0
|
|
||||||
max_memory_cache_size=10737418240
|
|
||||||
max_retries=8
|
|
||||||
max_upload_chunk_size=1099511627776
|
|
||||||
max_upload_speed=0
|
|
||||||
memory_buffer_size=8388608
|
|
||||||
metadata_cache_time=60
|
|
||||||
metadata_memory_cache=true
|
|
||||||
metadata_memory_cache_saving_interval=30
|
|
||||||
mv_keep_target=false
|
|
||||||
oauth2_loopback=false
|
|
||||||
oauth2_loopback_port=8080
|
|
||||||
presentation_format=desktop
|
|
||||||
presentation_icon=
|
|
||||||
read_ahead_buffers=5
|
|
||||||
read_only=false
|
|
||||||
redirect_uri=
|
|
||||||
root_folder=
|
|
||||||
scope=
|
|
||||||
service_account_credentials_path=
|
|
||||||
service_account_user_to_impersonate=
|
|
||||||
spreadsheet_format=desktop
|
|
||||||
spreadsheet_icon=
|
|
||||||
sqlite3_busy_timeout=5000
|
|
||||||
stream_large_files=true
|
|
||||||
team_drive_id=
|
|
||||||
umask=0o022
|
|
||||||
verification_code=
|
|
||||||
write_buffers=false
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
acknowledge_abuse=false
|
|
||||||
apps_script_format=desktop
|
|
||||||
apps_script_icon=
|
|
||||||
async_upload_queue=false
|
|
||||||
async_upload_queue_max_length=0
|
|
||||||
async_upload_threads=10
|
|
||||||
autodetect_mime=true
|
|
||||||
background_folder_fetching=true
|
|
||||||
cache_directory=
|
|
||||||
client_id=
|
|
||||||
client_secret=
|
|
||||||
connect_timeout_ms=5000
|
|
||||||
curl_debug_off=false
|
|
||||||
data_directory=
|
|
||||||
debug_buffers=false
|
|
||||||
delete_forever_in_trash_folder=false
|
|
||||||
desktop_entry_as_html=false
|
|
||||||
desktop_entry_exec=
|
|
||||||
disable_trash=false
|
|
||||||
docs_file_extension=true
|
|
||||||
document_format=desktop
|
|
||||||
document_icon=
|
|
||||||
download_docs=true
|
|
||||||
drawing_format=desktop
|
|
||||||
drawing_icon=
|
|
||||||
form_format=desktop
|
|
||||||
form_icon=
|
|
||||||
fusion_table_format=desktop
|
|
||||||
fusion_table_icon=
|
|
||||||
keep_duplicates=false
|
|
||||||
large_file_read_only=true
|
|
||||||
large_file_threshold_mb=16
|
|
||||||
log_directory=
|
|
||||||
log_to=
|
|
||||||
lost_and_found=false
|
|
||||||
low_speed_limit=0
|
|
||||||
low_speed_time=0
|
|
||||||
map_format=desktop
|
|
||||||
map_icon=
|
|
||||||
max_cache_size_mb=512000
|
|
||||||
max_download_speed=0
|
|
||||||
max_memory_cache_size=5368709120
|
|
||||||
max_retries=8
|
|
||||||
max_upload_chunk_size=1099511627776
|
|
||||||
max_upload_speed=0
|
|
||||||
memory_buffer_size=8388608
|
|
||||||
metadata_cache_time=60
|
|
||||||
metadata_memory_cache=true
|
|
||||||
metadata_memory_cache_saving_interval=30
|
|
||||||
mv_keep_target=false
|
|
||||||
oauth2_loopback=false
|
|
||||||
oauth2_loopback_port=8080
|
|
||||||
presentation_format=desktop
|
|
||||||
presentation_icon=
|
|
||||||
read_ahead_buffers=5
|
|
||||||
read_only=false
|
|
||||||
redirect_uri=
|
|
||||||
root_folder=
|
|
||||||
scope=
|
|
||||||
service_account_credentials_path=
|
|
||||||
service_account_user_to_impersonate=
|
|
||||||
spreadsheet_format=desktop
|
|
||||||
spreadsheet_icon=
|
|
||||||
sqlite3_busy_timeout=5000
|
|
||||||
stream_large_files=true
|
|
||||||
team_drive_id=0AH4Ykx7cpiF6Uk9PVA
|
|
||||||
umask=0o022
|
|
||||||
verification_code=
|
|
||||||
write_buffers=false
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
acknowledge_abuse=false
|
|
||||||
apps_script_format=desktop
|
|
||||||
apps_script_icon=
|
|
||||||
async_upload_queue=false
|
|
||||||
async_upload_queue_max_length=0
|
|
||||||
async_upload_threads=10
|
|
||||||
autodetect_mime=true
|
|
||||||
background_folder_fetching=true
|
|
||||||
cache_directory=
|
|
||||||
client_id=
|
|
||||||
client_secret=
|
|
||||||
connect_timeout_ms=5000
|
|
||||||
curl_debug_off=false
|
|
||||||
data_directory=
|
|
||||||
debug_buffers=false
|
|
||||||
delete_forever_in_trash_folder=false
|
|
||||||
desktop_entry_as_html=false
|
|
||||||
desktop_entry_exec=
|
|
||||||
disable_trash=false
|
|
||||||
docs_file_extension=true
|
|
||||||
document_format=desktop
|
|
||||||
document_icon=
|
|
||||||
download_docs=true
|
|
||||||
drawing_format=desktop
|
|
||||||
drawing_icon=
|
|
||||||
form_format=desktop
|
|
||||||
form_icon=
|
|
||||||
fusion_table_format=desktop
|
|
||||||
fusion_table_icon=
|
|
||||||
keep_duplicates=false
|
|
||||||
large_file_read_only=true
|
|
||||||
large_file_threshold_mb=16
|
|
||||||
log_directory=
|
|
||||||
log_to=
|
|
||||||
lost_and_found=false
|
|
||||||
low_speed_limit=0
|
|
||||||
low_speed_time=0
|
|
||||||
map_format=desktop
|
|
||||||
map_icon=
|
|
||||||
max_cache_size_mb=512000
|
|
||||||
max_download_speed=0
|
|
||||||
max_memory_cache_size=10737418240
|
|
||||||
max_retries=8
|
|
||||||
max_upload_chunk_size=1099511627776
|
|
||||||
max_upload_speed=0
|
|
||||||
memory_buffer_size=8388608
|
|
||||||
metadata_cache_time=60
|
|
||||||
metadata_memory_cache=true
|
|
||||||
metadata_memory_cache_saving_interval=30
|
|
||||||
mv_keep_target=false
|
|
||||||
oauth2_loopback=false
|
|
||||||
oauth2_loopback_port=8080
|
|
||||||
presentation_format=desktop
|
|
||||||
presentation_icon=
|
|
||||||
read_ahead_buffers=5
|
|
||||||
read_only=false
|
|
||||||
redirect_uri=
|
|
||||||
root_folder=
|
|
||||||
scope=
|
|
||||||
service_account_credentials_path=
|
|
||||||
service_account_user_to_impersonate=
|
|
||||||
spreadsheet_format=desktop
|
|
||||||
spreadsheet_icon=
|
|
||||||
sqlite3_busy_timeout=5000
|
|
||||||
stream_large_files=true
|
|
||||||
team_drive_id=0AIwrATJm5KEtUk9PVA
|
|
||||||
umask=0o022
|
|
||||||
verification_code=
|
|
||||||
write_buffers=false
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
[init]
|
|
||||||
defaultBranch = main
|
|
||||||
[user]
|
|
||||||
name = Tri Vo Khac
|
|
||||||
email = 33442340+vokhactri@users.noreply.github.com
|
|
||||||
[filter "lfs"]
|
|
||||||
required = true
|
|
||||||
clean = git-lfs clean -- %f
|
|
||||||
smudge = git-lfs smudge -- %f
|
|
||||||
process = git-lfs filter-process
|
|
||||||
[push]
|
|
||||||
autoSetupRemote = true
|
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
# KDE Plasma packages
|
||||||
|
|
||||||
|
From the repository root, install all KDE packages:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
(cd kde && stow -t "$HOME" */)
|
||||||
|
```
|
||||||
|
|
||||||
|
Or choose individual packages:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
stow -d kde -t "$HOME" spectacle helium
|
||||||
|
```
|
||||||
|
|
||||||
|
| Package | Details |
|
||||||
|
| ---------------------------------- | -------------------------------------------------------- |
|
||||||
|
| [theme](theme/README.md) | Darwin Breeze KDE colors and generated app themes |
|
||||||
|
| [helium](helium/README.md) | Browser flags; colors come from GTK |
|
||||||
|
| [spectacle](spectacle/README.md) | Screenshots to clipboard with a notification, no preview |
|
||||||
|
| [tray-icons](tray-icons/README.md) | Ngó Sen, NetBird and qBittorrent tray icons |
|
||||||
|
|
||||||
|
Theme and Spectacle need an additional apply step after stowing their package:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# If you selected theme:
|
||||||
|
./kde/theme/apply.sh
|
||||||
|
# If you selected spectacle:
|
||||||
|
./kde/spectacle/apply.py
|
||||||
|
```
|
||||||
|
|
||||||
|
The apply scripts require a running KDE Plasma 6 session. Ngó Sen and NetBird
|
||||||
|
icons need an additional install step described in the tray-icons README.
|
||||||
|
|
||||||
|
Packages can be selected independently; Helium follows the Darwin Breeze
|
||||||
|
colors only when the theme is applied.
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
# Hardware video acceleration (VA-API, AMD radeonsi) on Wayland
|
||||||
|
--ozone-platform-hint=auto
|
||||||
|
--enable-features=AcceleratedVideoDecodeLinuxGL,AcceleratedVideoDecodeLinuxZeroCopyGL,AcceleratedVideoEncoder
|
||||||
|
|
||||||
|
# Don't tag surfaces as sRGB. KWin shows tagged sRGB through a gamma 2.2
|
||||||
|
# curve, which lifts dark grays (40 -> 44), so the tab strip would come out
|
||||||
|
# lighter than KDE title bars.
|
||||||
|
--disable-features=WaylandWpColorManagerV1
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
# Helium
|
||||||
|
|
||||||
|
Browser flags for hardware video decoding on Wayland and for colors that
|
||||||
|
match KDE apps. From the repository root:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
stow -d kde -t "$HOME" helium
|
||||||
|
```
|
||||||
|
|
||||||
|
Helium takes its colors and window buttons from GTK. In Settings →
|
||||||
|
Appearance, set Theme to GTK and turn off "Use system title bar and borders".
|
||||||
|
With the KDE `theme` package applied, GTK follows the Darwin Breeze colors and
|
||||||
|
the window buttons match KWin's; see
|
||||||
|
[Darwin Breeze → Helium notes](../theme/README.md#helium-notes).
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
#!/usr/bin/env xdg-open
|
||||||
|
[Desktop Entry]
|
||||||
|
GenericName=Screenshot Capture Utility
|
||||||
|
Name=Spectacle
|
||||||
|
Comment=Take screenshots and screen recordings
|
||||||
|
Categories=Qt;KDE;Utility;
|
||||||
|
Keywords=snapshot;capture;print;screenshot;snipping;snipping tool;snip;
|
||||||
|
Exec=/usr/bin/spectacle --background --region --copy-image
|
||||||
|
Icon=spectacle
|
||||||
|
Type=Application
|
||||||
|
StartupNotify=false
|
||||||
|
Actions=FullScreenScreenShot;CurrentMonitorScreenShot;ActiveWindowScreenShot;RectangularRegionScreenShot;WindowUnderCursorScreenShot;RecordRegion;RecordScreen;RecordWindow;OpenWithoutScreenshot;
|
||||||
|
DBusActivatable=false
|
||||||
|
X-DBUS-StartupType=Unique
|
||||||
|
X-DBUS-ServiceName=org.kde.Spectacle
|
||||||
|
X-KDE-Shortcuts=Print,Meta+Shift+S
|
||||||
|
X-KDE-DBUS-Restricted-Interfaces=org.kde.KWin.ScreenShot2
|
||||||
|
X-KDE-Wayland-Interfaces=org_kde_plasma_window_management,zkde_screencast_unstable_v1
|
||||||
|
|
||||||
|
[Desktop Action FullScreenScreenShot]
|
||||||
|
Name=Capture Entire Desktop
|
||||||
|
Exec=/usr/bin/spectacle --background --copy-image -f
|
||||||
|
X-KDE-Shortcuts=Shift+Print
|
||||||
|
|
||||||
|
[Desktop Action CurrentMonitorScreenShot]
|
||||||
|
Name=Capture Current Monitor
|
||||||
|
Exec=/usr/bin/spectacle --background --copy-image -m
|
||||||
|
|
||||||
|
|
||||||
|
[Desktop Action ActiveWindowScreenShot]
|
||||||
|
Name=Capture Active Window
|
||||||
|
Exec=/usr/bin/spectacle --background --copy-image -a
|
||||||
|
X-KDE-Shortcuts=Meta+Print
|
||||||
|
|
||||||
|
[Desktop Action RectangularRegionScreenShot]
|
||||||
|
Name=Capture Rectangular Region
|
||||||
|
Exec=/usr/bin/spectacle --background --copy-image -r
|
||||||
|
X-KDE-Shortcuts=Meta+Shift+Print
|
||||||
|
|
||||||
|
[Desktop Action WindowUnderCursorScreenShot]
|
||||||
|
Name=Capture Window Under Cursor
|
||||||
|
Exec=/usr/bin/spectacle --background --copy-image -u
|
||||||
|
X-KDE-Shortcuts=Meta+Ctrl+Print
|
||||||
|
|
||||||
|
[Desktop Action RecordRegion]
|
||||||
|
Name=Start/Stop Region Recording
|
||||||
|
Exec=/usr/bin/spectacle -R region
|
||||||
|
X-KDE-Shortcuts=Meta+Shift+R,Meta+R
|
||||||
|
|
||||||
|
[Desktop Action RecordScreen]
|
||||||
|
Name=Start/Stop Screen Recording
|
||||||
|
Exec=/usr/bin/spectacle -R screen
|
||||||
|
X-KDE-Shortcuts=Meta+Alt+R
|
||||||
|
|
||||||
|
[Desktop Action RecordWindow]
|
||||||
|
Name=Start/Stop Window Recording
|
||||||
|
Exec=/usr/bin/spectacle -R window
|
||||||
|
X-KDE-Shortcuts=Meta+Ctrl+R
|
||||||
|
|
||||||
|
[Desktop Action OpenWithoutScreenshot]
|
||||||
|
Name=Launch without taking a screenshot
|
||||||
|
Exec=/usr/bin/spectacle -l
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
../applications/org.kde.spectacle.desktop
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
^/README.*
|
||||||
|
^/apply\.py
|
||||||
|
^/settings
|
||||||
|
__pycache__
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
# Spectacle
|
||||||
|
|
||||||
|
Capture screenshots in the background, copy the image to the clipboard, and
|
||||||
|
show a completion notification. Screenshots are not automatically saved.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
stow -d kde -t "$HOME" spectacle
|
||||||
|
./kde/spectacle/apply.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Requires Spectacle, KDE Plasma 6, GNU Stow, Python 3, `kwriteconfig6`,
|
||||||
|
`kbuildsycoca6`, `qdbus6`, and `gdbus`. Run the apply script in your KDE session.
|
||||||
|
Move any existing files reported as conflicts by Stow out of the way first.
|
||||||
|
|
||||||
|
- **Print** / **Meta+Shift+S**: select a rectangular region.
|
||||||
|
- **Shift+Print**: entire desktop.
|
||||||
|
- **Meta+Print**: active window.
|
||||||
|
- **Meta+Shift+Print**: select a rectangular region.
|
||||||
|
- **Meta+Ctrl+Print**: window under the cursor.
|
||||||
|
|
||||||
|
The desktop launcher and shortcut entry are managed by Stow. The files in
|
||||||
|
`settings/` are merged into `~/.config/spectaclerc` and `~/.config/klipperrc`
|
||||||
|
by `apply.py`, preserving unrelated preferences and window state. Klipper's
|
||||||
|
`SaveImages=true` keeps captured images available after Spectacle exits.
|
||||||
|
|
||||||
|
After editing settings or launcher commands, run `apply.py` again. It rebuilds
|
||||||
|
the cache using the KDE session's environment and reloads only Spectacle's
|
||||||
|
shortcut component, preserving custom key bindings.
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Apply screenshot preferences and reload Spectacle's KDE shortcuts."""
|
||||||
|
|
||||||
|
import ast
|
||||||
|
import configparser
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
import subprocess
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
|
||||||
|
HERE = Path(__file__).resolve().parent
|
||||||
|
COMPONENT = "org.kde.spectacle.desktop"
|
||||||
|
ACCEL = "/component/org_kde_spectacle_desktop"
|
||||||
|
|
||||||
|
|
||||||
|
def run(*args: str, **kwargs: Any) -> subprocess.CompletedProcess[str]:
|
||||||
|
return subprocess.run(args, check=True, text=True, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def accel(path: str, method: str, *args: str) -> str:
|
||||||
|
return run(
|
||||||
|
"gdbus", "call", "--session", "--dest", "org.kde.kglobalaccel",
|
||||||
|
"--object-path", path, "--method", method, *args,
|
||||||
|
capture_output=True,
|
||||||
|
).stdout
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
for name in ("spectaclerc", "klipperrc"):
|
||||||
|
config = configparser.ConfigParser(interpolation=None)
|
||||||
|
config.optionxform = str # type: ignore[method-assign,assignment]
|
||||||
|
config.read(HERE / "settings" / name)
|
||||||
|
for group in config.sections():
|
||||||
|
for key, value in config[group].items():
|
||||||
|
run("kwriteconfig6", "--file", name, "--group", group,
|
||||||
|
"--key", key, value)
|
||||||
|
|
||||||
|
# T3's locale and XDG_DATA_DIRS can differ from the running KDE session.
|
||||||
|
# Build the cache KDE actually reads, rather than an app-specific cache.
|
||||||
|
session: dict[str, str] = dict(
|
||||||
|
line.split("=", 1) for line in
|
||||||
|
run("systemctl", "--user", "show-environment", capture_output=True)
|
||||||
|
.stdout.splitlines() if "=" in line
|
||||||
|
)
|
||||||
|
env = os.environ.copy()
|
||||||
|
for key in ("LANG", "LANGUAGE", "XDG_DATA_DIRS", "XDG_DATA_HOME",
|
||||||
|
"XDG_CACHE_HOME", "XDG_CONFIG_HOME"):
|
||||||
|
env.pop(key, None)
|
||||||
|
if key in session:
|
||||||
|
env[key] = session[key]
|
||||||
|
for key in set(env) | set(session):
|
||||||
|
if key.startswith("LC_"):
|
||||||
|
env.pop(key, None)
|
||||||
|
if key in session:
|
||||||
|
env[key] = session[key]
|
||||||
|
run("kbuildsycoca6", "--noincremental", env=env)
|
||||||
|
|
||||||
|
# Existing shortcut components retain their old Exec commands. Recreate
|
||||||
|
# only Spectacle's component, preserving any customized key bindings.
|
||||||
|
try:
|
||||||
|
output = accel(ACCEL, "org.kde.kglobalaccel.Component.allShortcutInfos")
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
shortcuts: list[Any] = [] # Component has not been registered yet.
|
||||||
|
else:
|
||||||
|
shortcuts = ast.literal_eval(re.sub(r"@a[is] ", "", output))[0]
|
||||||
|
accel(ACCEL, "org.kde.kglobalaccel.Component.cleanUp")
|
||||||
|
|
||||||
|
action = [COMPONENT, "_reload_config", "Spectacle", "Reload configuration"]
|
||||||
|
accel("/kglobalaccel", "org.kde.KGlobalAccel.doRegister", repr(action))
|
||||||
|
accel("/kglobalaccel", "org.kde.KGlobalAccel.unregister",
|
||||||
|
COMPONENT, "_reload_config")
|
||||||
|
for name, label, component, friendly, context, _, keys, defaults in shortcuts:
|
||||||
|
if keys != defaults:
|
||||||
|
identity = component if context == "default" else f"{component}|{context}"
|
||||||
|
accel("/kglobalaccel", "org.kde.KGlobalAccel.setForeignShortcut",
|
||||||
|
repr([identity, name, friendly, label]), repr(keys))
|
||||||
|
|
||||||
|
run("qdbus6", "org.kde.klipper", "/klipper",
|
||||||
|
"org.kde.klipper.klipper.reloadConfig")
|
||||||
|
print("Applied Spectacle: copy to clipboard with a notification, no preview.")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
[General]
|
||||||
|
SaveImages=true
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
[General]
|
||||||
|
autoSaveImage=false
|
||||||
|
clipboardGroup=PostScreenshotCopyImage
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
/* Helium (Chromium) with its GTK theme. Chromium adds a "chromium" class to
|
||||||
|
every node of the GTK style contexts it reads colors from, so these rules
|
||||||
|
reach Helium and no other GTK app.
|
||||||
|
|
||||||
|
In the compact layout, the address bar takes the text field color and the
|
||||||
|
segment with the extension and window buttons takes the window color,
|
||||||
|
which Chromium resolves to the darker view color. Both get the title bar
|
||||||
|
color, so the strip reads as one bar like a KDE title bar. */
|
||||||
|
window.background.chromium,
|
||||||
|
textview.view.chromium {
|
||||||
|
background-color: @theme_bg_color_breeze;
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
__pycache__/
|
||||||
|
# Binary packages built by build.py.
|
||||||
|
*.vsix
|
||||||
|
*.tdesktop-theme
|
||||||
@@ -0,0 +1,165 @@
|
|||||||
|
# macOS-inspired colors for Breeze (dark variant).
|
||||||
|
# Header and Window share one color so the title bar merges into the toolbar.
|
||||||
|
|
||||||
|
[ColorEffects:Disabled]
|
||||||
|
Color=56,56,56
|
||||||
|
ColorAmount=0
|
||||||
|
ColorEffect=0
|
||||||
|
ContrastAmount=0.65
|
||||||
|
ContrastEffect=1
|
||||||
|
IntensityAmount=0.1
|
||||||
|
IntensityEffect=2
|
||||||
|
|
||||||
|
[ColorEffects:Inactive]
|
||||||
|
ChangeSelectionColor=true
|
||||||
|
Color=112,111,110
|
||||||
|
ColorAmount=0.025
|
||||||
|
ColorEffect=2
|
||||||
|
ContrastAmount=0.1
|
||||||
|
ContrastEffect=2
|
||||||
|
Enable=false
|
||||||
|
IntensityAmount=0
|
||||||
|
IntensityEffect=0
|
||||||
|
|
||||||
|
[Colors:Button]
|
||||||
|
BackgroundAlternate=109,109,109
|
||||||
|
BackgroundNormal=93,93,93
|
||||||
|
DecorationFocus=0,122,255
|
||||||
|
DecorationHover=0,122,255
|
||||||
|
ForegroundActive=65,156,255
|
||||||
|
ForegroundInactive=154,154,154
|
||||||
|
ForegroundLink=65,156,255
|
||||||
|
ForegroundNegative=255,74,76
|
||||||
|
ForegroundNeutral=255,146,48
|
||||||
|
ForegroundNormal=230,230,230
|
||||||
|
ForegroundPositive=48,209,88
|
||||||
|
ForegroundVisited=191,90,242
|
||||||
|
|
||||||
|
[Colors:Complementary]
|
||||||
|
BackgroundAlternate=40,40,40
|
||||||
|
BackgroundNormal=30,30,30
|
||||||
|
DecorationFocus=0,122,255
|
||||||
|
DecorationHover=0,122,255
|
||||||
|
ForegroundActive=65,156,255
|
||||||
|
ForegroundInactive=154,154,154
|
||||||
|
ForegroundLink=65,156,255
|
||||||
|
ForegroundNegative=255,74,76
|
||||||
|
ForegroundNeutral=255,146,48
|
||||||
|
ForegroundNormal=221,221,221
|
||||||
|
ForegroundPositive=48,209,88
|
||||||
|
ForegroundVisited=191,90,242
|
||||||
|
|
||||||
|
[Colors:Header]
|
||||||
|
BackgroundAlternate=40,40,40
|
||||||
|
BackgroundNormal=40,40,40
|
||||||
|
DecorationFocus=0,122,255
|
||||||
|
DecorationHover=0,122,255
|
||||||
|
ForegroundActive=65,156,255
|
||||||
|
ForegroundInactive=154,154,154
|
||||||
|
ForegroundLink=65,156,255
|
||||||
|
ForegroundNegative=255,74,76
|
||||||
|
ForegroundNeutral=255,146,48
|
||||||
|
ForegroundNormal=222,222,222
|
||||||
|
ForegroundPositive=48,209,88
|
||||||
|
ForegroundVisited=191,90,242
|
||||||
|
|
||||||
|
[Colors:Header][Inactive]
|
||||||
|
BackgroundAlternate=36,36,36
|
||||||
|
BackgroundNormal=36,36,36
|
||||||
|
DecorationFocus=0,122,255
|
||||||
|
DecorationHover=0,122,255
|
||||||
|
ForegroundActive=65,156,255
|
||||||
|
ForegroundInactive=128,128,128
|
||||||
|
ForegroundLink=65,156,255
|
||||||
|
ForegroundNegative=255,74,76
|
||||||
|
ForegroundNeutral=255,146,48
|
||||||
|
ForegroundNormal=154,154,154
|
||||||
|
ForegroundPositive=48,209,88
|
||||||
|
ForegroundVisited=191,90,242
|
||||||
|
|
||||||
|
[Colors:Selection]
|
||||||
|
BackgroundAlternate=25,135,255
|
||||||
|
BackgroundNormal=0,122,255
|
||||||
|
DecorationFocus=0,122,255
|
||||||
|
DecorationHover=0,122,255
|
||||||
|
ForegroundActive=255,255,255
|
||||||
|
ForegroundInactive=222,222,222
|
||||||
|
ForegroundLink=255,255,255
|
||||||
|
ForegroundNegative=255,200,200
|
||||||
|
ForegroundNeutral=255,220,180
|
||||||
|
ForegroundNormal=255,255,255
|
||||||
|
ForegroundPositive=200,255,210
|
||||||
|
ForegroundVisited=230,210,255
|
||||||
|
|
||||||
|
# macOS turns the selection gray when the window loses focus.
|
||||||
|
[Colors:Selection][Inactive]
|
||||||
|
BackgroundAlternate=70,70,70
|
||||||
|
BackgroundNormal=70,70,70
|
||||||
|
DecorationFocus=0,122,255
|
||||||
|
DecorationHover=0,122,255
|
||||||
|
ForegroundActive=255,255,255
|
||||||
|
ForegroundInactive=222,222,222
|
||||||
|
ForegroundLink=255,255,255
|
||||||
|
ForegroundNegative=255,74,76
|
||||||
|
ForegroundNeutral=255,146,48
|
||||||
|
ForegroundNormal=255,255,255
|
||||||
|
ForegroundPositive=48,209,88
|
||||||
|
ForegroundVisited=191,90,242
|
||||||
|
|
||||||
|
[Colors:Tooltip]
|
||||||
|
BackgroundAlternate=46,46,46
|
||||||
|
BackgroundNormal=40,40,40
|
||||||
|
DecorationFocus=0,122,255
|
||||||
|
DecorationHover=0,122,255
|
||||||
|
ForegroundActive=65,156,255
|
||||||
|
ForegroundInactive=154,154,154
|
||||||
|
ForegroundLink=65,156,255
|
||||||
|
ForegroundNegative=255,74,76
|
||||||
|
ForegroundNeutral=255,146,48
|
||||||
|
ForegroundNormal=222,222,222
|
||||||
|
ForegroundPositive=48,209,88
|
||||||
|
ForegroundVisited=191,90,242
|
||||||
|
|
||||||
|
[Colors:View]
|
||||||
|
BackgroundAlternate=37,37,37
|
||||||
|
BackgroundNormal=30,30,30
|
||||||
|
DecorationFocus=0,122,255
|
||||||
|
DecorationHover=0,122,255
|
||||||
|
ForegroundActive=65,156,255
|
||||||
|
ForegroundInactive=154,154,154
|
||||||
|
ForegroundLink=65,156,255
|
||||||
|
ForegroundNegative=255,74,76
|
||||||
|
ForegroundNeutral=255,146,48
|
||||||
|
ForegroundNormal=221,221,221
|
||||||
|
ForegroundPositive=48,209,88
|
||||||
|
ForegroundVisited=191,90,242
|
||||||
|
|
||||||
|
[Colors:Window]
|
||||||
|
BackgroundAlternate=46,46,46
|
||||||
|
BackgroundNormal=40,40,40
|
||||||
|
DecorationFocus=0,122,255
|
||||||
|
DecorationHover=0,122,255
|
||||||
|
ForegroundActive=65,156,255
|
||||||
|
ForegroundInactive=154,154,154
|
||||||
|
ForegroundLink=65,156,255
|
||||||
|
ForegroundNegative=255,74,76
|
||||||
|
ForegroundNeutral=255,146,48
|
||||||
|
ForegroundNormal=222,222,222
|
||||||
|
ForegroundPositive=48,209,88
|
||||||
|
ForegroundVisited=191,90,242
|
||||||
|
|
||||||
|
[General]
|
||||||
|
ColorScheme=DarwinBreezeDark
|
||||||
|
Name=Darwin Breeze Dark
|
||||||
|
shadeSortColumn=true
|
||||||
|
|
||||||
|
[KDE]
|
||||||
|
contrast=4
|
||||||
|
|
||||||
|
[WM]
|
||||||
|
activeBackground=40,40,40
|
||||||
|
activeBlend=40,40,40
|
||||||
|
activeForeground=222,222,222
|
||||||
|
inactiveBackground=36,36,36
|
||||||
|
inactiveBlend=36,36,36
|
||||||
|
inactiveForeground=154,154,154
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
[kdeglobals][KDE]
|
||||||
|
widgetStyle=Breeze
|
||||||
|
|
||||||
|
[kdeglobals][General]
|
||||||
|
ColorScheme=DarwinBreezeDark
|
||||||
|
|
||||||
|
[kdeglobals][Icons]
|
||||||
|
Theme=breeze-dark
|
||||||
|
|
||||||
|
[plasmarc][Theme]
|
||||||
|
name=default
|
||||||
|
|
||||||
|
[kcminputrc][Mouse]
|
||||||
|
cursorTheme=breeze_cursors
|
||||||
|
|
||||||
|
[kwinrc][WindowSwitcher]
|
||||||
|
LayoutName=org.kde.breeze.desktop
|
||||||
|
|
||||||
|
[kwinrc][DesktopSwitcher]
|
||||||
|
LayoutName=org.kde.breeze.desktop
|
||||||
|
|
||||||
|
[kwinrc][org.kde.kdecoration2]
|
||||||
|
library=org.kde.breeze
|
||||||
|
theme=Breeze
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"KPackageStructure": "Plasma/LookAndFeel",
|
||||||
|
"KPlugin": {
|
||||||
|
"Authors": [
|
||||||
|
{
|
||||||
|
"Name": "trivk"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Category": "",
|
||||||
|
"Description": "Breeze in macOS-inspired colors (dark)",
|
||||||
|
"Id": "dev.trivk.darwinbreeze.dark",
|
||||||
|
"License": "GPL-2.0-or-later",
|
||||||
|
"Name": "Darwin Breeze Dark",
|
||||||
|
"Version": "1.0"
|
||||||
|
},
|
||||||
|
"X-Plasma-APIVersion": "2"
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
^/README.*
|
||||||
|
^/\.gitignore
|
||||||
|
^/apply\.sh
|
||||||
|
^/build\.py
|
||||||
|
^/t3
|
||||||
|
^/telegram
|
||||||
|
^/vscode
|
||||||
|
__pycache__
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
# Darwin Breeze
|
||||||
|
|
||||||
|
Breeze for KDE Plasma 6 in the macOS dark system colors, with Helium, T3 Code,
|
||||||
|
VS Code and Telegram themed from the same colors.
|
||||||
|
|
||||||
|
Only the colors change. Breeze still draws the widgets and the title bar, and
|
||||||
|
the window buttons stay on the right.
|
||||||
|
|
||||||
|
- Selection and focus rings use the macOS blue, `#007AFF`.
|
||||||
|
- The title bar has the same color as the toolbar below it, so the two read as
|
||||||
|
one strip.
|
||||||
|
- When a window loses focus, its selection turns gray, as on macOS.
|
||||||
|
- Errors, warnings, success text and links use Apple's system red, orange,
|
||||||
|
green, blue and purple.
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
From `~/.dotfiles`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
stow -d kde -t "$HOME" theme
|
||||||
|
./kde/theme/apply.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
`apply.sh` regenerates the app themes, applies the global theme, hides the
|
||||||
|
line under the title bar, turns off the wallpaper accent color, gives Helium
|
||||||
|
the KWin title buttons and an even tab strip, publishes the T3 Code theme and
|
||||||
|
installs the VS Code extension. Restart Helium afterwards; T3 Code switches on its own. In VS
|
||||||
|
Code, pick "Darwin Breeze Dark" once under Preferences → Color Theme; after
|
||||||
|
later color changes, run Developer: Reload Window.
|
||||||
|
|
||||||
|
Telegram has to import its theme by hand: Settings → Chat Settings → Chat
|
||||||
|
background → Choose from file, then pick
|
||||||
|
`kde/theme/telegram/DarwinBreezeDark.tdesktop-theme` and Apply. Import it
|
||||||
|
again after the colors change.
|
||||||
|
|
||||||
|
## Changing colors
|
||||||
|
|
||||||
|
The color scheme is the only place colors are defined:
|
||||||
|
|
||||||
|
```
|
||||||
|
kde/theme/.local/share/color-schemes/DarwinBreezeDark.colors
|
||||||
|
```
|
||||||
|
|
||||||
|
Edit it, then run `./kde/theme/apply.sh` again. Everything else follows:
|
||||||
|
|
||||||
|
| App | How it gets the colors |
|
||||||
|
| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
|
| Qt / KDE apps | the color scheme itself |
|
||||||
|
| GTK apps | Breeze GTK, which `kde-gtk-config` syncs from the scheme |
|
||||||
|
| Tray icons in `kde/tray-icons/` | `ColorScheme-Text`, recolored by Plasma |
|
||||||
|
| Helium | Breeze GTK, through Helium's GTK theme (see [Helium notes](#helium-notes)) |
|
||||||
|
| T3 Code | `t3/darwin-breeze.json`, generated by `build.py` and published with `t3 theme set` |
|
||||||
|
| VS Code | `vscode/package.json` and `vscode/themes/`, generated by `build.py`, packed into `darwin-breeze.vsix` and installed by `apply.sh` |
|
||||||
|
| Telegram | `telegram/DarwinBreezeDark.tdesktop-theme`, built by `build.py` and imported by hand |
|
||||||
|
|
||||||
|
The generated text files are committed so that `stow` alone gives a working
|
||||||
|
setup; the binary packages (Telegram's `.tdesktop-theme`, VS Code's `.vsix`)
|
||||||
|
are built by `build.py` instead. Don't edit generated files by hand.
|
||||||
|
|
||||||
|
## T3 Code notes
|
||||||
|
|
||||||
|
- T3 Code ignores symlinked theme files, so the theme isn't stowed;
|
||||||
|
`apply.sh` publishes a copy into `~/.t3/userdata/themes/`.
|
||||||
|
- Every slot of the T3 theme maps to a role in the color scheme (see `t3()` in
|
||||||
|
`build.py`), so a new slot or a different mapping is a change there, not a
|
||||||
|
hand-edited color.
|
||||||
|
|
||||||
|
## VS Code notes
|
||||||
|
|
||||||
|
- The workbench colors start from VS Code's own default dark theme, Dark 2026
|
||||||
|
(vendored in `vscode/base/` with the themes it includes). It already lays
|
||||||
|
out its grays as the scheme does: the editor darkest, the chrome around it
|
||||||
|
lighter, widgets lighter still. Each of those becomes the matching scheme
|
||||||
|
gray and the grays between them are interpolated. Other colors take the
|
||||||
|
hue of the matching Apple color and keep their lightness and saturation.
|
||||||
|
Keys with an exact role, such as buttons, badges, the active tab's top
|
||||||
|
border and the git colors, are set directly (`vscode()` in `build.py`).
|
||||||
|
- Syntax colors are Pierre Dark's, the theme T3 Code highlights code with
|
||||||
|
(`vscode/base/pierre-dark.json`, taken from T3 Code). They are used as they
|
||||||
|
are, without gamma compensation, so code looks the same in both apps.
|
||||||
|
- The terminal palette is generated from the color scheme.
|
||||||
|
- VS Code is Electron, so its workbench colors get the same gamma
|
||||||
|
compensation as T3 Code.
|
||||||
|
- The `.vsix` isn't committed; `build.py` packs it from `vscode/`.
|
||||||
|
|
||||||
|
## Telegram notes
|
||||||
|
|
||||||
|
- Telegram has some 600 color keys and the scheme has roles for only a few
|
||||||
|
dozen of them (`telegram()` in `build.py`). The rest start from Telegram's
|
||||||
|
own night theme, vendored as `telegram/night.tdesktop-palette`: its
|
||||||
|
blue-tinted grays become scheme grays of the same brightness and its blues
|
||||||
|
take the macOS blue's hue. Other colors, such as the reds, greens and name
|
||||||
|
colors, are kept as night has them.
|
||||||
|
- The chat list, top bar and compose bar use the window color; the chat
|
||||||
|
behind the bubbles and the folder strip use the darker view color.
|
||||||
|
- Telegram is a Qt app, so unlike T3 Code and VS Code it needs no gamma
|
||||||
|
compensation.
|
||||||
|
- The `.tdesktop-theme` is a zip, so it isn't committed; `build.py` builds it
|
||||||
|
from the night palette and the color scheme.
|
||||||
|
|
||||||
|
## Helium notes
|
||||||
|
|
||||||
|
- Helium uses the GTK theme (Settings → Appearance → Theme: GTK) with "Use
|
||||||
|
system title bar and borders" off, so the tab strip doubles as the title
|
||||||
|
bar. Its colors come from Breeze GTK, which `kde-gtk-config` syncs from
|
||||||
|
the scheme; there is no Helium theme to generate.
|
||||||
|
- With the system title bar off, Helium draws the window buttons through
|
||||||
|
GTK. `kde-gtk-config` renders the KWin buttons into
|
||||||
|
`~/.config/gtk-3.0/window_decorations.css`, but hands that file to GTK apps
|
||||||
|
through a GTK module that Helium doesn't load, so Helium would show Breeze
|
||||||
|
GTK's own round buttons instead. `apply.sh` imports the file from `gtk.css`
|
||||||
|
so Helium picks it up too.
|
||||||
|
- In the compact layout, the address bar takes GTK's text field color and the
|
||||||
|
segment with the extension and window buttons takes the window color, which
|
||||||
|
Chromium resolves to the darker view color. `.config/gtk-3.0/chromium.css`
|
||||||
|
gives both the title bar color, and `apply.sh` imports it from `gtk.css`.
|
||||||
|
Chromium adds a `chromium` class to every GTK node it reads colors from, so
|
||||||
|
the rules reach Helium and no other GTK app.
|
||||||
|
- Chromium tags its output as sRGB and KWin shows it with a gamma 2.2 curve,
|
||||||
|
which lifts dark grays (40 becomes 44). T3 Code and VS Code get
|
||||||
|
pre-compensated colors from `build.py`; Helium instead runs with
|
||||||
|
`--disable-features=WaylandWpColorManagerV1`, so its surfaces go untagged
|
||||||
|
and show the GTK colors as they are.
|
||||||
|
|
||||||
|
## When the colors don't show up
|
||||||
|
|
||||||
|
- In System Settings → Colors, take the accent color from the color scheme. A
|
||||||
|
custom accent, or one taken from the wallpaper, replaces the blue.
|
||||||
|
- Use the Plasma style called "Breeze". "Breeze Dark" and "Breeze Light" carry
|
||||||
|
their own colors, so panels and popups ignore the scheme.
|
||||||
|
- GTK apps follow the scheme only with the Breeze GTK theme. Flatpak apps also
|
||||||
|
need `org.gtk.Gtk3theme.Breeze` installed.
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Regenerate the app themes from the color scheme and apply Darwin Breeze.
|
||||||
|
#
|
||||||
|
# Run `stow -d kde -t "$HOME" theme` from the repo root first.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
here="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
data="${XDG_DATA_HOME:-$HOME/.local/share}"
|
||||||
|
|
||||||
|
if [ ! -e "$data/color-schemes/DarwinBreezeDark.colors" ]; then
|
||||||
|
echo 'DarwinBreezeDark.colors is not installed; run: stow -d kde -t "$HOME" theme' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
python3 -I "$here/build.py"
|
||||||
|
|
||||||
|
plasma-apply-lookandfeel --apply dev.trivk.darwinbreeze.dark
|
||||||
|
|
||||||
|
# plasma-apply-colorscheme skips a scheme that is already active, so edits
|
||||||
|
# to the .colors file would not be picked up. Bounce through stock Breeze.
|
||||||
|
plasma-apply-colorscheme BreezeClassic >/dev/null
|
||||||
|
plasma-apply-colorscheme DarwinBreezeDark >/dev/null
|
||||||
|
|
||||||
|
# kde-gtk-config writes gtk.css; add our imports to it.
|
||||||
|
gtk_import() {
|
||||||
|
local css="${XDG_CONFIG_HOME:-$HOME/.config}/$1/gtk.css"
|
||||||
|
if [ -e "$css" ] && ! grep -qF "'$2'" "$css"; then
|
||||||
|
sed -i "\$a @import '$2';" "$css"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
# kde-gtk-config gives GTK apps the KWin title buttons through a GTK module,
|
||||||
|
# which Helium doesn't load, so it would fall back to Breeze GTK's own
|
||||||
|
# buttons. Importing the same CSS from gtk.css reaches Helium too.
|
||||||
|
gtk_import gtk-3.0 window_decorations.css
|
||||||
|
gtk_import gtk-4.0 window_decorations.css
|
||||||
|
# Helium's tab strip colors (see chromium.css).
|
||||||
|
gtk_import gtk-3.0 chromium.css
|
||||||
|
|
||||||
|
# Drop the line under the title bar so it blends into the toolbar.
|
||||||
|
kwriteconfig6 --file breezerc --group Windeco --key DrawTitleBarSeparator false
|
||||||
|
|
||||||
|
# A wallpaper-derived accent color would override the blue from the scheme.
|
||||||
|
kwriteconfig6 --file kdeglobals --group General --key AccentColor --delete
|
||||||
|
kwriteconfig6 --file kdeglobals --group General --key accentColorFromWallpaper false
|
||||||
|
|
||||||
|
qdbus6 org.kde.KWin /KWin reconfigure 2>/dev/null \
|
||||||
|
|| dbus-send --session --type=signal /KWin org.kde.KWin.reloadConfig
|
||||||
|
|
||||||
|
# T3 Code skips symlinked theme files, so publish a copy instead of stowing it.
|
||||||
|
t3="$(command -v t3 || echo "$HOME/.t3/bin/t3")"
|
||||||
|
if [ -x "$t3" ]; then
|
||||||
|
"$t3" theme set "$here/t3/darwin-breeze.json" >/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
# VS Code only loads themes from installed extensions. --force reinstalls the
|
||||||
|
# same version, so color changes land without a version bump.
|
||||||
|
if command -v code >/dev/null; then
|
||||||
|
code --install-extension "$here/vscode/darwin-breeze.vsix" --force >/dev/null 2>&1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Applied Darwin Breeze"
|
||||||
|
if pgrep -x helium >/dev/null; then
|
||||||
|
echo "Restart Helium to pick up the new colors"
|
||||||
|
fi
|
||||||
@@ -0,0 +1,617 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Generate app themes from the Darwin Breeze KDE color scheme.
|
||||||
|
|
||||||
|
.local/share/color-schemes/DarwinBreezeDark.colors is the only place colors
|
||||||
|
are defined. This script derives from it:
|
||||||
|
|
||||||
|
t3/darwin-breeze.json (published to T3 Code by apply.sh)
|
||||||
|
telegram/DarwinBreezeDark.tdesktop-theme (not committed; imported into Telegram by hand)
|
||||||
|
vscode/ (packed into vscode/darwin-breeze.vsix, installed by apply.sh)
|
||||||
|
"""
|
||||||
|
|
||||||
|
import colorsys
|
||||||
|
import configparser
|
||||||
|
import io
|
||||||
|
import json
|
||||||
|
import re
|
||||||
|
import struct
|
||||||
|
import zipfile
|
||||||
|
import zlib
|
||||||
|
from collections.abc import Callable, Mapping, Sequence
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
HERE = Path(__file__).resolve().parent
|
||||||
|
PKG = HERE
|
||||||
|
SCHEME = PKG / ".local/share/color-schemes/DarwinBreezeDark.colors"
|
||||||
|
T3 = HERE / "t3/darwin-breeze.json"
|
||||||
|
# Telegram Desktop's built-in night theme, used as the base for every key the
|
||||||
|
# scheme has no role for: the colors file from telegramdesktop/tdesktop at
|
||||||
|
# 837b256, Telegram/Resources/night.tdesktop-theme.
|
||||||
|
TELEGRAM_BASE = HERE / "telegram/night.tdesktop-palette"
|
||||||
|
TELEGRAM = HERE / "telegram/DarwinBreezeDark.tdesktop-theme"
|
||||||
|
VSCODE = HERE / "vscode"
|
||||||
|
VSCODE_THEME = "themes/DarwinBreezeDark-color-theme.json"
|
||||||
|
# VS Code's default dark theme, Dark 2026 (which includes Dark Modern, Dark+
|
||||||
|
# and Visual Studio Dark), from Code - OSS 1.138 extensions/theme-defaults.
|
||||||
|
# The workbench colors start from it.
|
||||||
|
VSCODE_UI = VSCODE / "base/2026-dark.json"
|
||||||
|
# Pierre Dark, the syntax theme T3 Code highlights code with (from T3 Code
|
||||||
|
# 0.1.4). The editor uses its token colors as they are.
|
||||||
|
VSCODE_SYNTAX = VSCODE / "base/pierre-dark.json"
|
||||||
|
|
||||||
|
# An RGB or RGBA color, 0-255 per channel.
|
||||||
|
type Color = tuple[int, ...]
|
||||||
|
# Looks up a color in the scheme by group and key.
|
||||||
|
type ColorFn = Callable[[str, str], Color]
|
||||||
|
|
||||||
|
WHITE = (255, 255, 255)
|
||||||
|
|
||||||
|
# Apple systemCyan; the KDE scheme has no cyan role.
|
||||||
|
CYAN = (100, 210, 255)
|
||||||
|
|
||||||
|
# Apple systemYellow; search highlights in T3 Code.
|
||||||
|
YELLOW = (255, 255, 0)
|
||||||
|
|
||||||
|
|
||||||
|
def load() -> ColorFn:
|
||||||
|
cp = configparser.ConfigParser(interpolation=None, strict=False)
|
||||||
|
cp.optionxform = str # type: ignore[method-assign,assignment]
|
||||||
|
cp.read(SCHEME)
|
||||||
|
|
||||||
|
def color(group: str, key: str) -> Color:
|
||||||
|
return tuple(int(v) for v in cp[f"Colors:{group}"][key].split(","))
|
||||||
|
|
||||||
|
return color
|
||||||
|
|
||||||
|
|
||||||
|
def mix(a: Sequence[int], b: Sequence[int], t: float) -> Color:
|
||||||
|
return tuple(round(x + (y - x) * t) for x, y in zip(a, b))
|
||||||
|
|
||||||
|
|
||||||
|
def hexc(c: Sequence[int]) -> str:
|
||||||
|
"""#rrggbb, or #rrggbbaa when c carries an alpha."""
|
||||||
|
return "#" + "".join(f"{v:02x}" for v in c)
|
||||||
|
|
||||||
|
|
||||||
|
def kwin_compensate(c: Sequence[int]) -> list[int]:
|
||||||
|
"""Pre-distort a color for Chromium on KWin.
|
||||||
|
|
||||||
|
Chromium tags its surfaces as sRGB, KWin shows them with a gamma 2.2
|
||||||
|
curve, so dark grays come out lighter (40 -> 44). Encoding the target
|
||||||
|
with the inverse makes Chromium apps land on the same values as native
|
||||||
|
apps.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def ch(v: int) -> int:
|
||||||
|
lin: float = (v / 255) ** 2.2
|
||||||
|
enc = 12.92 * lin if lin <= 0.0031308 else 1.055 * lin ** (1 / 2.4) - 0.055
|
||||||
|
return round(enc * 255)
|
||||||
|
|
||||||
|
return [ch(v) for v in c]
|
||||||
|
|
||||||
|
|
||||||
|
def ansi(color: ColorFn) -> list[Color]:
|
||||||
|
"""The 16 colors for the VS Code terminal."""
|
||||||
|
bg = color("View", "BackgroundNormal")
|
||||||
|
fg = color("View", "ForegroundNormal")
|
||||||
|
normal = [
|
||||||
|
mix(bg, fg, 0.15),
|
||||||
|
color("View", "ForegroundNegative"),
|
||||||
|
color("View", "ForegroundPositive"),
|
||||||
|
color("View", "ForegroundNeutral"),
|
||||||
|
color("View", "ForegroundLink"),
|
||||||
|
color("View", "ForegroundVisited"),
|
||||||
|
CYAN,
|
||||||
|
fg,
|
||||||
|
]
|
||||||
|
bright = [
|
||||||
|
mix(bg, fg, 0.45),
|
||||||
|
*(mix(c, WHITE, 0.25) for c in normal[1:7]),
|
||||||
|
mix(fg, WHITE, 0.6),
|
||||||
|
]
|
||||||
|
return normal + bright
|
||||||
|
|
||||||
|
|
||||||
|
def t3(color: ColorFn) -> dict[str, str]:
|
||||||
|
"""Every color slot of a T3 Code theme, mapped onto a scheme role."""
|
||||||
|
window, window_text = color("Window", "BackgroundNormal"), color("Window", "ForegroundNormal")
|
||||||
|
view, view_text = color("View", "BackgroundNormal"), color("View", "ForegroundNormal")
|
||||||
|
header, header_text = color("Header", "BackgroundNormal"), color("Header", "ForegroundNormal")
|
||||||
|
button, button_text = color("Button", "BackgroundNormal"), color("Button", "ForegroundNormal")
|
||||||
|
accent, accent_text = color("Selection", "BackgroundNormal"), color("Selection", "ForegroundNormal")
|
||||||
|
unfocused = color("Selection][Inactive", "BackgroundNormal")
|
||||||
|
unfocused_text = color("Selection][Inactive", "ForegroundNormal")
|
||||||
|
muted = color("View", "ForegroundInactive")
|
||||||
|
negative = color("View", "ForegroundNegative")
|
||||||
|
neutral = color("View", "ForegroundNeutral")
|
||||||
|
link = color("View", "ForegroundLink")
|
||||||
|
window_line = mix(window, window_text, 0.115)
|
||||||
|
|
||||||
|
colors = {
|
||||||
|
"canvas": view,
|
||||||
|
"chrome": header,
|
||||||
|
"toolbar": header,
|
||||||
|
"toolbarForeground": header_text,
|
||||||
|
"toolbarBorder": mix(header, header_text, 0.115),
|
||||||
|
"toolbarControl": button,
|
||||||
|
"toolbarControlForeground": button_text,
|
||||||
|
"toolbarControlHover": color("Button", "BackgroundAlternate"),
|
||||||
|
"surface": view,
|
||||||
|
"surfaceRaised": window,
|
||||||
|
"surfaceOverlay": window,
|
||||||
|
"text": view_text,
|
||||||
|
"textMuted": muted,
|
||||||
|
"border": mix(view, view_text, 0.115),
|
||||||
|
"input": mix(view, view_text, 0.3),
|
||||||
|
"focus": mix(view, accent, 0.5),
|
||||||
|
"accent": accent,
|
||||||
|
"accentForeground": accent_text,
|
||||||
|
"secondary": button,
|
||||||
|
"secondaryForeground": button_text,
|
||||||
|
"muted": window,
|
||||||
|
"mutedForeground": color("Window", "ForegroundInactive"),
|
||||||
|
"placeholder": muted,
|
||||||
|
"secondaryLabel": muted,
|
||||||
|
"iconMuted": muted,
|
||||||
|
"error": negative,
|
||||||
|
"errorForeground": negative,
|
||||||
|
"errorSurface": mix(view, negative, 0.1),
|
||||||
|
"warning": neutral,
|
||||||
|
"warningForeground": neutral,
|
||||||
|
"warningSurface": mix(view, neutral, 0.1),
|
||||||
|
"update": link,
|
||||||
|
"updateForeground": link,
|
||||||
|
"updateSurface": mix(view, link, 0.12),
|
||||||
|
"accentSurface": unfocused,
|
||||||
|
"accentSurfaceForeground": unfocused_text,
|
||||||
|
"messageSurface": window,
|
||||||
|
"messageForeground": window_text,
|
||||||
|
"messageAction": accent,
|
||||||
|
"messageActionForeground": accent_text,
|
||||||
|
"messageActionHover": color("Selection", "BackgroundAlternate"),
|
||||||
|
"codeBackground": window,
|
||||||
|
"codeForeground": WHITE,
|
||||||
|
"searchMatchBackground": mix(view, YELLOW, 0.25),
|
||||||
|
"searchMatchForeground": view_text,
|
||||||
|
"searchMatchActiveBackground": YELLOW,
|
||||||
|
"searchMatchActiveForeground": (0, 0, 0),
|
||||||
|
"sidebar": window,
|
||||||
|
"sidebarForeground": window_text,
|
||||||
|
"sidebarMutedForeground": color("Window", "ForegroundInactive"),
|
||||||
|
"sidebarControlSurface": button,
|
||||||
|
"sidebarRowHover": window_line,
|
||||||
|
"sidebarRowActive": unfocused,
|
||||||
|
"sidebarRowSelected": unfocused,
|
||||||
|
"sidebarBorder": window_line,
|
||||||
|
"terminalBackground": view,
|
||||||
|
"terminalForeground": WHITE,
|
||||||
|
"terminalCursor": WHITE,
|
||||||
|
"terminalSelection": mix(view, accent, 0.4),
|
||||||
|
"terminalScrollbar": mix(view, view_text, 0.3),
|
||||||
|
"terminalScrollbarHover": muted,
|
||||||
|
}
|
||||||
|
# T3 Code runs on Chromium too, so it needs the same KWin compensation.
|
||||||
|
return {k: hexc(kwin_compensate(v)) for k, v in colors.items()}
|
||||||
|
|
||||||
|
|
||||||
|
def telegram(color: ColorFn) -> dict[str, Color]:
|
||||||
|
"""Telegram keys mapped onto a scheme role; the rest come from night."""
|
||||||
|
window, window_text = color("Window", "BackgroundNormal"), color("Window", "ForegroundNormal")
|
||||||
|
view, view_text = color("View", "BackgroundNormal"), color("View", "ForegroundNormal")
|
||||||
|
header, header_text = color("Header", "BackgroundNormal"), color("Header", "ForegroundNormal")
|
||||||
|
title_inactive = color("Header][Inactive", "BackgroundNormal")
|
||||||
|
title_inactive_text = color("Header][Inactive", "ForegroundNormal")
|
||||||
|
tooltip, tooltip_text = color("Tooltip", "BackgroundNormal"), color("Tooltip", "ForegroundNormal")
|
||||||
|
accent, accent_text = color("Selection", "BackgroundNormal"), color("Selection", "ForegroundNormal")
|
||||||
|
accent_hover = color("Selection", "BackgroundAlternate")
|
||||||
|
muted = color("Window", "ForegroundInactive")
|
||||||
|
negative = color("Window", "ForegroundNegative")
|
||||||
|
positive = color("Window", "ForegroundPositive")
|
||||||
|
link = color("Window", "ForegroundLink")
|
||||||
|
hover = mix(window, window_text, 0.115)
|
||||||
|
ripple = mix(window, window_text, 0.18)
|
||||||
|
control = mix(window, window_text, 0.3)
|
||||||
|
msg_in = mix(view, view_text, 0.1)
|
||||||
|
msg_out = mix(view, accent, 0.5)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"windowBg": window,
|
||||||
|
"windowFg": window_text,
|
||||||
|
"windowBgOver": hover,
|
||||||
|
"windowBgRipple": ripple,
|
||||||
|
"windowFgOver": window_text,
|
||||||
|
"windowSubTextFg": muted,
|
||||||
|
"windowSubTextFgOver": mix(muted, window_text, 0.2),
|
||||||
|
"windowBoldFg": window_text,
|
||||||
|
"windowBoldFgOver": window_text,
|
||||||
|
"windowBgActive": accent,
|
||||||
|
"windowFgActive": accent_text,
|
||||||
|
"windowActiveTextFg": link,
|
||||||
|
"windowShadowFgFallback": window,
|
||||||
|
"activeButtonBg": accent,
|
||||||
|
"activeButtonBgOver": accent_hover,
|
||||||
|
"activeButtonBgRipple": mix(accent, WHITE, 0.2),
|
||||||
|
"activeButtonFg": accent_text,
|
||||||
|
"activeButtonFgOver": accent_text,
|
||||||
|
"activeButtonSecondaryFg": mix(accent, accent_text, 0.75),
|
||||||
|
"activeLineFg": accent,
|
||||||
|
"activeLineFgError": negative,
|
||||||
|
"lightButtonBg": window,
|
||||||
|
"lightButtonBgOver": mix(window, accent, 0.12),
|
||||||
|
"lightButtonBgRipple": mix(window, accent, 0.2),
|
||||||
|
"lightButtonFg": link,
|
||||||
|
"attentionButtonFg": negative,
|
||||||
|
"attentionButtonFgOver": negative,
|
||||||
|
"attentionButtonBgOver": mix(window, negative, 0.12),
|
||||||
|
"attentionButtonBgRipple": mix(window, negative, 0.2),
|
||||||
|
"outlineButtonOutlineFg": accent,
|
||||||
|
"menuBg": window,
|
||||||
|
"menuBgOver": hover,
|
||||||
|
"menuBgRipple": ripple,
|
||||||
|
"menuIconFg": muted,
|
||||||
|
"menuIconFgOver": mix(muted, window_text, 0.3),
|
||||||
|
"menuSubmenuArrowFg": muted,
|
||||||
|
"menuFgDisabled": control,
|
||||||
|
"menuSeparatorFg": hover,
|
||||||
|
"checkboxFg": muted,
|
||||||
|
"sliderBgInactive": control,
|
||||||
|
"sliderBgActive": accent,
|
||||||
|
"inputBorderFg": control,
|
||||||
|
# Breeze draws text fields in the view color with a blue focus ring.
|
||||||
|
"filterInputActiveBg": view,
|
||||||
|
"filterInputInactiveBg": view,
|
||||||
|
"filterInputBorderFg": accent,
|
||||||
|
"tooltipBg": tooltip,
|
||||||
|
"tooltipFg": tooltip_text,
|
||||||
|
"tooltipBorderFg": mix(tooltip, tooltip_text, 0.115),
|
||||||
|
"titleBg": title_inactive,
|
||||||
|
"titleBgActive": header,
|
||||||
|
"titleFg": title_inactive_text,
|
||||||
|
"titleFgActive": header_text,
|
||||||
|
"topBarBg": header,
|
||||||
|
"boxBg": window,
|
||||||
|
"boxTitleFg": window_text,
|
||||||
|
"boxTextFgGood": positive,
|
||||||
|
"boxTextFgError": negative,
|
||||||
|
# Folder strip in the view color, so the selected folder merges into
|
||||||
|
# the chat list next to it.
|
||||||
|
"sideBarBg": view,
|
||||||
|
"sideBarBgActive": window,
|
||||||
|
"sideBarBgRipple": mix(view, window_text, 0.1),
|
||||||
|
"sideBarTextFg": muted,
|
||||||
|
"sideBarTextFgActive": link,
|
||||||
|
"sideBarIconFg": muted,
|
||||||
|
"sideBarIconFgActive": link,
|
||||||
|
"sideBarBadgeBg": accent,
|
||||||
|
"sideBarBadgeBgMuted": control,
|
||||||
|
"sideBarBadgeFg": accent_text,
|
||||||
|
"dialogsBg": window,
|
||||||
|
"dialogsBgOver": hover,
|
||||||
|
"dialogsRippleBg": ripple,
|
||||||
|
"dialogsBgActive": accent,
|
||||||
|
"dialogsRippleBgActive": accent_hover,
|
||||||
|
"dialogsNameFg": window_text,
|
||||||
|
"dialogsTextFg": muted,
|
||||||
|
"dialogsTextFgOver": muted,
|
||||||
|
"dialogsTextFgService": link,
|
||||||
|
"dialogsTextFgServiceOver": link,
|
||||||
|
"dialogsDateFg": muted,
|
||||||
|
"dialogsDateFgOver": muted,
|
||||||
|
"dialogsDraftFg": negative,
|
||||||
|
"dialogsOnlineBadgeFg": positive,
|
||||||
|
"dialogsVerifiedIconBg": link,
|
||||||
|
"dialogsVerifiedIconFg": window,
|
||||||
|
"dialogsUnreadBg": accent,
|
||||||
|
"dialogsUnreadBgOver": accent,
|
||||||
|
"dialogsUnreadFg": accent_text,
|
||||||
|
"dialogsUnreadBgMuted": control,
|
||||||
|
"dialogsUnreadBgMutedOver": mix(window, window_text, 0.35),
|
||||||
|
"dialogsUnreadBgActive": accent_text,
|
||||||
|
"dialogsUnreadFgActive": accent,
|
||||||
|
"dialogsUnreadBgMutedActive": mix(accent, accent_text, 0.55),
|
||||||
|
"historyComposeAreaBg": window,
|
||||||
|
"historyComposeAreaFg": window_text,
|
||||||
|
"historyComposeButtonBgOver": hover,
|
||||||
|
"historyComposeButtonBgRipple": ripple,
|
||||||
|
"historyTextInFg": view_text,
|
||||||
|
"historyTextOutFg": view_text,
|
||||||
|
"historyLinkInFg": link,
|
||||||
|
"msgInBg": msg_in,
|
||||||
|
"msgInBgSelected": mix(msg_in, accent, 0.3),
|
||||||
|
"msgOutBg": msg_out,
|
||||||
|
"msgOutBgSelected": mix(msg_out, accent, 0.3),
|
||||||
|
"msgInDateFg": muted,
|
||||||
|
"msgOutDateFg": mix(msg_out, WHITE, 0.55),
|
||||||
|
"msgSelectOverlay": (*accent, 0x4C),
|
||||||
|
"msgStickerOverlay": (*accent, 0x7F),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def luma(c: Sequence[int]) -> float:
|
||||||
|
return 0.299 * c[0] + 0.587 * c[1] + 0.114 * c[2]
|
||||||
|
|
||||||
|
|
||||||
|
def interp(points: Sequence[tuple[float, float]], x: float) -> float:
|
||||||
|
for (x0, y0), (x1, y1) in zip(points, points[1:]):
|
||||||
|
if x <= x1:
|
||||||
|
return y0 + (y1 - y0) * (x - x0) / (x1 - x0)
|
||||||
|
return points[-1][1]
|
||||||
|
|
||||||
|
|
||||||
|
def parse_hex(v: str) -> Color:
|
||||||
|
h = v[1:]
|
||||||
|
if len(h) in (3, 4):
|
||||||
|
h = "".join(ch * 2 for ch in h)
|
||||||
|
return tuple(int(h[i:i + 2], 16) for i in range(0, len(h), 2))
|
||||||
|
|
||||||
|
|
||||||
|
def telegram_theme(color: ColorFn) -> str:
|
||||||
|
"""The night theme, recolored onto the scheme.
|
||||||
|
|
||||||
|
Night tints everything blue. Its tinted grays become scheme grays of
|
||||||
|
matching brightness, its blues take the accent's hue and saturation, and
|
||||||
|
other hues (reds, greens, name colors) stay. telegram() then pins every
|
||||||
|
key that has a scheme role.
|
||||||
|
"""
|
||||||
|
base = TELEGRAM_BASE.read_text()
|
||||||
|
line_re = re.compile(r"^(\w+):\s*(#[0-9a-fA-F]+)\s*;")
|
||||||
|
night = {m[1]: parse_hex(m[2]) for m in map(line_re.match, base.splitlines()) if m}
|
||||||
|
|
||||||
|
window, muted = color("Window", "BackgroundNormal"), color("Window", "ForegroundInactive")
|
||||||
|
grays = sorted({
|
||||||
|
(0, 0),
|
||||||
|
(luma(night["windowBg"]), window[0]),
|
||||||
|
(luma(night["windowSubTextFg"]), muted[0]),
|
||||||
|
(255, 255),
|
||||||
|
})
|
||||||
|
accent_h, _, accent_s = colorsys.rgb_to_hls(*(v / 255 for v in color("Selection", "BackgroundNormal")))
|
||||||
|
|
||||||
|
def recolor(c: Color) -> Color:
|
||||||
|
rgb, alpha = c[:3], c[3:]
|
||||||
|
chroma = max(rgb) - min(rgb)
|
||||||
|
h, l, _ = colorsys.rgb_to_hls(*(v / 255 for v in rgb))
|
||||||
|
if chroma <= 4 or not 195 <= h * 360 <= 225:
|
||||||
|
return c
|
||||||
|
if chroma <= 55:
|
||||||
|
g = round(interp(grays, luma(rgb)))
|
||||||
|
return (g, g, g, *alpha)
|
||||||
|
return (*(round(v * 255) for v in colorsys.hls_to_rgb(accent_h, l, accent_s)), *alpha)
|
||||||
|
|
||||||
|
pinned = telegram(color)
|
||||||
|
seen: set[str] = set()
|
||||||
|
out = [f"// Generated by kde/theme/build.py from {SCHEME.name}"]
|
||||||
|
for line in base.splitlines():
|
||||||
|
m = line_re.match(line)
|
||||||
|
if m:
|
||||||
|
key = m[1]
|
||||||
|
seen.add(key)
|
||||||
|
c = pinned[key] if key in pinned else recolor(night[key])
|
||||||
|
line = f"{key}: {hexc(c)};" + line[m.end():]
|
||||||
|
elif re.match(r"^(\w+):", line) and line.split(":")[0] in pinned:
|
||||||
|
key = line.split(":")[0]
|
||||||
|
seen.add(key)
|
||||||
|
line = f"{key}: {hexc(pinned[key])};"
|
||||||
|
out.append(line)
|
||||||
|
out += [f"{k}: {hexc(c)};" for k, c in pinned.items() if k not in seen]
|
||||||
|
return "\n".join(out) + "\n"
|
||||||
|
|
||||||
|
|
||||||
|
def vscode_base_colors() -> dict[str, Color]:
|
||||||
|
"""Dark 2026's colors with its include chain resolved."""
|
||||||
|
chain: list[dict[str, str]] = []
|
||||||
|
path: Path | None = VSCODE_UI
|
||||||
|
while path:
|
||||||
|
theme = json.loads(path.read_text())
|
||||||
|
chain.append(theme.get("colors", {}))
|
||||||
|
path = path.parent / theme["include"] if "include" in theme else None
|
||||||
|
colors: dict[str, str] = {}
|
||||||
|
for layer in reversed(chain):
|
||||||
|
colors.update(layer)
|
||||||
|
return {k: parse_hex(v) for k, v in colors.items()}
|
||||||
|
|
||||||
|
|
||||||
|
def vscode(color: ColorFn) -> dict[str, str]:
|
||||||
|
"""Workbench colors: Dark 2026, recolored onto the scheme.
|
||||||
|
|
||||||
|
Dark 2026 lays out its grays the way the scheme does: the chrome lighter
|
||||||
|
than the editor, widgets lighter still. Each of those grays becomes the
|
||||||
|
scheme gray in the same place, and the grays in between are interpolated.
|
||||||
|
Each hue takes the hue of the matching scheme color but keeps its own
|
||||||
|
lightness and saturation, so a muted dark red background stays one. pins
|
||||||
|
then sets the keys that have an exact scheme role, which is where the full
|
||||||
|
macOS blue shows.
|
||||||
|
"""
|
||||||
|
window, window_text = color("Window", "BackgroundNormal"), color("Window", "ForegroundNormal")
|
||||||
|
view, view_text = color("View", "BackgroundNormal"), color("View", "ForegroundNormal")
|
||||||
|
accent, accent_text = color("Selection", "BackgroundNormal"), color("Selection", "ForegroundNormal")
|
||||||
|
muted = color("Window", "ForegroundInactive")
|
||||||
|
negative = color("View", "ForegroundNegative")
|
||||||
|
neutral = color("View", "ForegroundNeutral")
|
||||||
|
positive = color("View", "ForegroundPositive")
|
||||||
|
link = color("View", "ForegroundLink")
|
||||||
|
base = vscode_base_colors()
|
||||||
|
|
||||||
|
grays = sorted({
|
||||||
|
(0, 0),
|
||||||
|
(luma(base["editor.background"]), view[0]),
|
||||||
|
(luma(base["sideBar.background"]), window[0]),
|
||||||
|
(luma(base["editorWidget.background"]), color("Window", "BackgroundAlternate")[0]),
|
||||||
|
(luma(base["sideBar.border"]), mix(window, window_text, 0.115)[0]),
|
||||||
|
(luma(base["descriptionForeground"]), muted[0]),
|
||||||
|
(luma(base["foreground"]), window_text[0]),
|
||||||
|
(255, 255),
|
||||||
|
})
|
||||||
|
assert all(a[1] <= b[1] for a, b in zip(grays, grays[1:])), grays
|
||||||
|
|
||||||
|
def hls(c: Sequence[int]) -> tuple[float, float, float]:
|
||||||
|
return colorsys.rgb_to_hls(*(v / 255 for v in c))
|
||||||
|
|
||||||
|
# (hue range in degrees, scheme color whose hue it takes)
|
||||||
|
families: list[tuple[tuple[int, int], Color]] = [
|
||||||
|
((0, 15), negative),
|
||||||
|
((15, 70), neutral),
|
||||||
|
((70, 170), positive),
|
||||||
|
((170, 250), accent),
|
||||||
|
((250, 330), color("View", "ForegroundVisited")),
|
||||||
|
((330, 360), negative),
|
||||||
|
]
|
||||||
|
|
||||||
|
def recolor(c: Color) -> Color:
|
||||||
|
rgb, alpha = c[:3], c[3:]
|
||||||
|
if max(rgb) - min(rgb) <= 10:
|
||||||
|
g = round(interp(grays, luma(rgb)))
|
||||||
|
return (g, g, g, *alpha)
|
||||||
|
h, l, sat = hls(rgb)
|
||||||
|
target = next(t for (lo, hi), t in families if lo <= h * 360 < hi)
|
||||||
|
return (*(round(v * 255) for v in colorsys.hls_to_rgb(hls(target)[0], l, sat)), *alpha)
|
||||||
|
|
||||||
|
pins: dict[str, Color] = {
|
||||||
|
"editor.background": view,
|
||||||
|
"editor.foreground": view_text,
|
||||||
|
"titleBar.inactiveBackground": color("Header][Inactive", "BackgroundNormal"),
|
||||||
|
"titleBar.inactiveForeground": color("Header][Inactive", "ForegroundNormal"),
|
||||||
|
"focusBorder": (*accent, 0xB3),
|
||||||
|
"quickInputList.focusBackground": accent,
|
||||||
|
"button.background": accent,
|
||||||
|
"button.border": accent,
|
||||||
|
"button.hoverBackground": color("Selection", "BackgroundAlternate"),
|
||||||
|
"button.foreground": accent_text,
|
||||||
|
"badge.background": accent,
|
||||||
|
"badge.foreground": accent_text,
|
||||||
|
"activityBarBadge.background": accent,
|
||||||
|
"activityBarBadge.foreground": accent_text,
|
||||||
|
"tab.activeBorderTop": accent,
|
||||||
|
"panelTitle.activeBorder": accent,
|
||||||
|
"textLink.foreground": link,
|
||||||
|
"textLink.activeForeground": link,
|
||||||
|
}
|
||||||
|
names = ["Black", "Red", "Green", "Yellow", "Blue", "Magenta", "Cyan", "White"]
|
||||||
|
for i, c in enumerate(ansi(color)):
|
||||||
|
pins[f"terminal.ansi{'Bright' if i >= 8 else ''}{names[i % 8]}"] = c
|
||||||
|
|
||||||
|
colors = {k: pins.get(k) or recolor(c) for k, c in base.items()}
|
||||||
|
colors.update(pins)
|
||||||
|
# Electron is Chromium, so it needs the KWin compensation.
|
||||||
|
return {k: hexc(kwin_compensate(c[:3]) + list(c[3:])) for k, c in sorted(colors.items())}
|
||||||
|
|
||||||
|
|
||||||
|
def vscode_files(color: ColorFn) -> dict[str, str]:
|
||||||
|
"""The extension files, keyed by their path inside it."""
|
||||||
|
name = "Darwin Breeze Dark"
|
||||||
|
# Syntax colors as T3 Code shows them. T3 Code doesn't compensate them
|
||||||
|
# either, so the two render the same.
|
||||||
|
syntax = json.loads(VSCODE_SYNTAX.read_text())
|
||||||
|
theme = {
|
||||||
|
"$schema": "vscode://schemas/color-theme",
|
||||||
|
"name": name,
|
||||||
|
"type": "dark",
|
||||||
|
"semanticHighlighting": True,
|
||||||
|
"colors": vscode(color),
|
||||||
|
"tokenColors": syntax["tokenColors"],
|
||||||
|
"semanticTokenColors": syntax["semanticTokenColors"],
|
||||||
|
}
|
||||||
|
package = {
|
||||||
|
"name": "darwin-breeze",
|
||||||
|
"displayName": "Darwin Breeze",
|
||||||
|
"description": f"Generated by kde/theme/build.py from {SCHEME.name}",
|
||||||
|
"publisher": "trivk",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"engines": {"vscode": "^1.70.0"},
|
||||||
|
"categories": ["Themes"],
|
||||||
|
"contributes": {
|
||||||
|
"themes": [{"label": name, "uiTheme": "vs-dark", "path": f"./{VSCODE_THEME}"}],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
"package.json": json.dumps(package, indent=2) + "\n",
|
||||||
|
VSCODE_THEME: json.dumps(theme, indent=2) + "\n",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def vsix(files: Mapping[str, str]) -> bytes:
|
||||||
|
"""Pack the extension the way vsce does, for code --install-extension."""
|
||||||
|
manifest = """<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
|
||||||
|
<Metadata>
|
||||||
|
<Identity Language="en-US" Id="darwin-breeze" Version="1.0.0" Publisher="trivk"/>
|
||||||
|
<DisplayName>Darwin Breeze</DisplayName>
|
||||||
|
<Description xml:space="preserve">Darwin Breeze Dark color theme</Description>
|
||||||
|
<Categories>Themes</Categories>
|
||||||
|
<Properties>
|
||||||
|
<Property Id="Microsoft.VisualStudio.Code.Engine" Value="^1.70.0"/>
|
||||||
|
</Properties>
|
||||||
|
</Metadata>
|
||||||
|
<Installation>
|
||||||
|
<InstallationTarget Id="Microsoft.VisualStudio.Code"/>
|
||||||
|
</Installation>
|
||||||
|
<Dependencies/>
|
||||||
|
<Assets>
|
||||||
|
<Asset Type="Microsoft.VisualStudio.Code.Manifest" Path="extension/package.json" Addressable="true"/>
|
||||||
|
</Assets>
|
||||||
|
</PackageManifest>
|
||||||
|
"""
|
||||||
|
content_types = """<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension=".json" ContentType="application/json"/><Default Extension=".vsixmanifest" ContentType="text/xml"/></Types>
|
||||||
|
"""
|
||||||
|
return zip_bytes({
|
||||||
|
"[Content_Types].xml": content_types,
|
||||||
|
"extension.vsixmanifest": manifest,
|
||||||
|
**{f"extension/{path}": text for path, text in files.items()},
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
def solid_png(c: Sequence[int]) -> bytes:
|
||||||
|
"""A 1x1 PNG; Telegram stretches it over the chat as a plain background."""
|
||||||
|
|
||||||
|
def chunk(kind: bytes, data: bytes) -> bytes:
|
||||||
|
return struct.pack(">I", len(data)) + kind + data + struct.pack(">I", zlib.crc32(kind + data))
|
||||||
|
|
||||||
|
return (
|
||||||
|
b"\x89PNG\r\n\x1a\n"
|
||||||
|
+ chunk(b"IHDR", struct.pack(">IIBBBBB", 1, 1, 8, 2, 0, 0, 0))
|
||||||
|
+ chunk(b"IDAT", zlib.compress(bytes([0, *c])))
|
||||||
|
+ chunk(b"IEND", b"")
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def zip_bytes(files: Mapping[str, str | bytes]) -> bytes:
|
||||||
|
"""A zip with fixed timestamps, so an unchanged theme rebuilds byte-identical."""
|
||||||
|
buf = io.BytesIO()
|
||||||
|
with zipfile.ZipFile(buf, "w", zipfile.ZIP_DEFLATED) as z:
|
||||||
|
for name, data in files.items():
|
||||||
|
info = zipfile.ZipInfo(name, (1980, 1, 1, 0, 0, 0))
|
||||||
|
info.compress_type = zipfile.ZIP_DEFLATED
|
||||||
|
info.external_attr = 0o644 << 16
|
||||||
|
z.writestr(info, data)
|
||||||
|
return buf.getvalue()
|
||||||
|
|
||||||
|
|
||||||
|
def write(path: Path, data: str | bytes) -> bool:
|
||||||
|
path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
if isinstance(data, str):
|
||||||
|
data = data.encode()
|
||||||
|
if path.exists() and path.read_bytes() == data:
|
||||||
|
return False
|
||||||
|
path.write_bytes(data)
|
||||||
|
print(f"wrote {path.relative_to(PKG.parent)}")
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
color = load()
|
||||||
|
theme = {"version": 1, "name": "Darwin Breeze", "appearance": "dark", "colors": t3(color)}
|
||||||
|
write(T3, json.dumps(theme, indent=2) + "\n")
|
||||||
|
|
||||||
|
write(TELEGRAM, zip_bytes({
|
||||||
|
"colors.tdesktop-theme": telegram_theme(color),
|
||||||
|
"background.png": solid_png(color("View", "BackgroundNormal")),
|
||||||
|
}))
|
||||||
|
|
||||||
|
files = vscode_files(color)
|
||||||
|
for path, text in files.items():
|
||||||
|
write(VSCODE / path, text)
|
||||||
|
write(VSCODE / "darwin-breeze.vsix", vsix(files))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"name": "Darwin Breeze",
|
||||||
|
"appearance": "dark",
|
||||||
|
"colors": {
|
||||||
|
"canvas": "#181818",
|
||||||
|
"chrome": "#232323",
|
||||||
|
"toolbar": "#232323",
|
||||||
|
"toolbarForeground": "#dfdfdf",
|
||||||
|
"toolbarBorder": "#3a3a3a",
|
||||||
|
"toolbarControl": "#5d5d5d",
|
||||||
|
"toolbarControlForeground": "#e7e7e7",
|
||||||
|
"toolbarControlHover": "#6d6d6d",
|
||||||
|
"surface": "#181818",
|
||||||
|
"surfaceRaised": "#232323",
|
||||||
|
"surfaceOverlay": "#232323",
|
||||||
|
"text": "#dedede",
|
||||||
|
"textMuted": "#9b9b9b",
|
||||||
|
"border": "#313131",
|
||||||
|
"input": "#565656",
|
||||||
|
"focus": "#064b8f",
|
||||||
|
"accent": "#007bff",
|
||||||
|
"accentForeground": "#ffffff",
|
||||||
|
"secondary": "#5d5d5d",
|
||||||
|
"secondaryForeground": "#e7e7e7",
|
||||||
|
"muted": "#232323",
|
||||||
|
"mutedForeground": "#9b9b9b",
|
||||||
|
"placeholder": "#9b9b9b",
|
||||||
|
"secondaryLabel": "#9b9b9b",
|
||||||
|
"iconMuted": "#9b9b9b",
|
||||||
|
"error": "#ff494b",
|
||||||
|
"errorForeground": "#ff494b",
|
||||||
|
"errorSurface": "#311c1e",
|
||||||
|
"warning": "#ff932c",
|
||||||
|
"warningForeground": "#ff932c",
|
||||||
|
"warningSurface": "#31251a",
|
||||||
|
"update": "#3f9dff",
|
||||||
|
"updateForeground": "#3f9dff",
|
||||||
|
"updateSurface": "#1c2936",
|
||||||
|
"accentSurface": "#444444",
|
||||||
|
"accentSurfaceForeground": "#ffffff",
|
||||||
|
"messageSurface": "#232323",
|
||||||
|
"messageForeground": "#dfdfdf",
|
||||||
|
"messageAction": "#007bff",
|
||||||
|
"messageActionForeground": "#ffffff",
|
||||||
|
"messageActionHover": "#1288ff",
|
||||||
|
"codeBackground": "#232323",
|
||||||
|
"codeForeground": "#ffffff",
|
||||||
|
"searchMatchBackground": "#55550e",
|
||||||
|
"searchMatchForeground": "#dedede",
|
||||||
|
"searchMatchActiveBackground": "#ffff00",
|
||||||
|
"searchMatchActiveForeground": "#000000",
|
||||||
|
"sidebar": "#232323",
|
||||||
|
"sidebarForeground": "#dfdfdf",
|
||||||
|
"sidebarMutedForeground": "#9b9b9b",
|
||||||
|
"sidebarControlSurface": "#5d5d5d",
|
||||||
|
"sidebarRowHover": "#3a3a3a",
|
||||||
|
"sidebarRowActive": "#444444",
|
||||||
|
"sidebarRowSelected": "#444444",
|
||||||
|
"sidebarBorder": "#3a3a3a",
|
||||||
|
"terminalBackground": "#181818",
|
||||||
|
"terminalForeground": "#ffffff",
|
||||||
|
"terminalCursor": "#ffffff",
|
||||||
|
"terminalSelection": "#0a4179",
|
||||||
|
"terminalScrollbar": "#565656",
|
||||||
|
"terminalScrollbarHover": "#9b9b9b"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,467 @@
|
|||||||
|
windowBg: #17212b; // white: fallback for background
|
||||||
|
windowFg: #f5f5f5; // black: fallback for text
|
||||||
|
windowBgOver: #232e3c; // light gray: fallback for background with mouse over
|
||||||
|
windowBgRipple: #24303d; // darker gray: fallback for ripple effect
|
||||||
|
windowFgOver: #e9ecf0; // black: fallback for text with mouse over
|
||||||
|
windowSubTextFg: #708499; // gray: fallback for additional text
|
||||||
|
windowSubTextFgOver: #7c90a4; // darker gray: fallback for additional text with mouse over
|
||||||
|
windowBoldFg: #e9e8e8; // dark gray: fallback for bold text
|
||||||
|
windowBoldFgOver: #e9e9e9; // dark gray: fallback for bold text with mouse over
|
||||||
|
windowBgActive: #5288c1; // bright blue: fallback for blue filled active areas
|
||||||
|
windowFgActive: #ffffff; // white: fallback for text on active areas
|
||||||
|
windowActiveTextFg: #6ab3f3; // online blue: fallback for active text like online status
|
||||||
|
windowShadowFg: #000000; // black: fallback for shadow
|
||||||
|
windowShadowFgFallback: #17212b; // gray: fallback for shadow without opacity
|
||||||
|
shadowFg: #04080e56; // most shadows (including opacity)
|
||||||
|
slideFadeOutBg: #0000003c; // slide animation (chat to profile) fade out filling
|
||||||
|
slideFadeOutShadowFg: windowShadowFg; // slide animation (chat to profile) fade out right section shadow
|
||||||
|
imageBg: #000000; // image background fallback (when photo size is less than minimum allowed)
|
||||||
|
imageBgTransparent: #ffffff; // image background when displaying an image with opacity where no opacity is needed
|
||||||
|
activeButtonBg: #2f6ea5; // default active button background
|
||||||
|
activeButtonBgOver: #3476ab; // default active button background with mouse over
|
||||||
|
activeButtonBgRipple: #3b7cb1; // default active button ripple effect
|
||||||
|
activeButtonFg: #ffffff; // default active button text
|
||||||
|
activeButtonFgOver: #ffffff; // default active button text with mouse over
|
||||||
|
activeButtonSecondaryFg: #9abfe7; // default active button additional text (selected messages counter in forward / delete buttons)
|
||||||
|
activeButtonSecondaryFgOver: activeButtonSecondaryFg; // default active button additional text with mouse over
|
||||||
|
activeLineFg: #6396cb; // default active line (like code input field bottom border when you log in and field is focused)
|
||||||
|
activeLineFgError: #ef5959; // default active line for error state (like code input field bottom border when you log in and you've entered incorrect code)
|
||||||
|
lightButtonBg: #17212b; // default light button background (like buttons in boxes)
|
||||||
|
lightButtonBgOver: #1d2a39; // default light button background with mouse over
|
||||||
|
lightButtonBgRipple: #223143; // default light button ripple effect
|
||||||
|
lightButtonFg: #6ab2f2; // default light button text
|
||||||
|
lightButtonFgOver: lightButtonFg; // default light button text with mouse over
|
||||||
|
attentionButtonFg: #ec3942; // default attention button text (like confirm button on log out)
|
||||||
|
attentionButtonFgOver: #ec3942; // default attention button text with mouse over
|
||||||
|
attentionButtonBgOver: #592a2a64; // default attention button background with mouse over
|
||||||
|
attentionButtonBgRipple: #68323264; // default attention button ripple effect
|
||||||
|
outlineButtonBg: windowBg; // default left outlined button background (like shared media links in profiles)
|
||||||
|
outlineButtonBgOver: #202b37; // default left outlined button background with mouse over
|
||||||
|
outlineButtonOutlineFg: #3983c3; // default left outlined button left outline border
|
||||||
|
outlineButtonBgRipple: #27323f; // default left outlined button ripple effect
|
||||||
|
menuBg: #17212b; // default popup menu background
|
||||||
|
menuBgOver: #ffffff; // default popup menu item background with mouse over
|
||||||
|
menuBgRipple: #1f2934; // default popup menu item ripple effect
|
||||||
|
menuIconFg: #6c7883; // default popup menu item icon (like main menu)
|
||||||
|
menuIconFgOver: #dcdcdc; // default popup menu item icon with mouse over
|
||||||
|
menuSubmenuArrowFg: #637c95; // default popup menu submenu arrow icon (like in message field context menu in case of RTL system language)
|
||||||
|
menuFgDisabled: #3d4e5c; // default popup menu item disabled text (like unavailable items in message field context menu)
|
||||||
|
menuSeparatorFg: #232f39; // default popup menu separator (like in message field context menu)
|
||||||
|
scrollBarBg: #ffffff53; // default scroll bar current rectangle, the bar itself (like in chats list)
|
||||||
|
scrollBarBgOver: #ffffff7a; // default scroll bar current rectangle with mouse over it
|
||||||
|
scrollBg: #ffffff1a; // default scroll bar background
|
||||||
|
scrollBgOver: #ffffff2c; // default scroll bar background with mouse over the scroll bar
|
||||||
|
smallCloseIconFg: #55616c; // small X icon (like in Show all sessions box to the right for sessions termination)
|
||||||
|
smallCloseIconFgOver: #a3a3a3; // small X icon with mouse over
|
||||||
|
radialFg: windowFgActive; // default radial loader line (like in Media Viewer when loading a photo)
|
||||||
|
radialBg: #00000056; // default radial loader background (like in Media Viewer when loading a photo)
|
||||||
|
placeholderFg: #6d7883; // default input field placeholder when field is not focused (like in phone input field when you log in)
|
||||||
|
placeholderFgActive: #4f5b67; // default input field placeholder when field is focused
|
||||||
|
inputBorderFg: #313c49; // default input field bottom border (like in code input field when you log in and field is not focused)
|
||||||
|
filterInputBorderFg: #242f3d; // default rounded input field border (like in chats list search field when field is focused)
|
||||||
|
filterInputInactiveBg: #242f3d; // default rounded input field background (like in chats list search field when field is inactive)
|
||||||
|
checkboxFg: #4f6276; // default unchecked checkbox rounded rectangle (and also emoji category icons)
|
||||||
|
sliderBgInactive: #364554; // default slider not active bar (like in Settings when you choose interface scale or custom notifications count)
|
||||||
|
sliderBgActive: #4a81bc; // default slider active bar (like in Settings when you choose interface scale or custom notifications count)
|
||||||
|
tooltipBg: #16222d; // tooltip background (like when you put mouse over the message timestamp and wait)
|
||||||
|
tooltipFg: #d4e0ea; // tooltip text
|
||||||
|
tooltipBorderFg: #16222d; // tooltip border
|
||||||
|
titleShadow: #00000000; // one pixel line shadow at the bottom of custom window title
|
||||||
|
titleBg: #1f2936; // custom window title background when window is inactive
|
||||||
|
titleBgActive: #242f3d; // custom window title background when window is active
|
||||||
|
titleButtonBg: titleBg; // custom window title minimize/maximize/restore button background when window is inactive (Windows only)
|
||||||
|
titleButtonFg: #576673; // custom window title minimize/maximize/restore button icon when window is inactive (Windows only)
|
||||||
|
titleButtonBgOver: #25303e; // custom window title minimize/maximize/restore button background with mouse over when window is inactive (Windows only)
|
||||||
|
titleButtonFgOver: #e0e0e0; // custom window title minimize/maximize/restore button icon with mouse over when window is inactive (Windows only)
|
||||||
|
titleButtonBgActive: #242f3d; // custom window title minimize/maximize/restore button background when window is active (Windows only)
|
||||||
|
titleButtonFgActive: titleButtonFg; // custom window title minimize/maximize/restore button icon when window is active (Windows only)
|
||||||
|
titleButtonBgActiveOver: #2c3847; // custom window title minimize/maximize/restore button background with mouse over when window is active (Windows only)
|
||||||
|
titleButtonFgActiveOver: titleButtonFgOver; // custom window title minimize/maximize/restore button icon with mouse over when window is active (Windows only)
|
||||||
|
titleButtonCloseBg: titleButtonBg; // custom window title close button background when window is inactive (Windows only)
|
||||||
|
titleButtonCloseFg: titleButtonFg; // custom window title close button icon when window is inactive (Windows only)
|
||||||
|
titleButtonCloseBgOver: #e92539; // custom window title close button background with mouse over when window is inactive (Windows only)
|
||||||
|
titleButtonCloseFgOver: windowFgActive; // custom window title close button icon with mouse over when window is inactive (Windows only)
|
||||||
|
titleButtonCloseBgActive: #242f3d; // custom window title close button background when window is active (Windows only)
|
||||||
|
titleButtonCloseFgActive: titleButtonCloseFg; // custom window title close button icon when window is active (Windows only)
|
||||||
|
titleButtonCloseBgActiveOver: #e92539; // custom window title close button background with mouse over when window is active (Windows only)
|
||||||
|
titleButtonCloseFgActiveOver: titleButtonCloseFgOver; // custom window title close button icon with mouse over when window is active (Windows only)
|
||||||
|
titleFg: #6a7680; // custom window title text when window is inactive (macOS only)
|
||||||
|
titleFgActive: #91a3b3; // custom window title text when window is active (macOS only)
|
||||||
|
trayCounterBg: #f23c34; // tray icon counter background
|
||||||
|
trayCounterBgMute: #888888; // tray icon counter background if all unread messages are muted
|
||||||
|
trayCounterFg: #ffffff; // tray icon counter text
|
||||||
|
trayCounterBgMacInvert: #ffffff; // tray icon counter background when tray icon is pressed or when dark theme of macOS is used (macOS only)
|
||||||
|
trayCounterFgMacInvert: #ffffff01; // tray icon counter text when tray icon is pressed or when dark theme of macOS is used (macOS only)
|
||||||
|
layerBg: #0000007f; // box and main menu background layer fade
|
||||||
|
cancelIconFg: #737e87; // default for settings close icon and box search cancel icon
|
||||||
|
cancelIconFgOver: #dcdcdc; // default for settings close icon and box search cancel icon with mouse over
|
||||||
|
boxBg: #17212b; // box background
|
||||||
|
boxTextFg: windowFg; // box text
|
||||||
|
boxTextFgGood: #5598db; // accepted box text (like when choosing username that is not occupied)
|
||||||
|
boxTextFgError: #dc3d3d; // rejecting box text (like when choosing username that is occupied)
|
||||||
|
boxTitleFg: #ebebeb; // box title text
|
||||||
|
boxSearchBg: #17212b; // box search field background (like in contacts box)
|
||||||
|
boxTitleAdditionalFg: #6d7f8f; // box title additional text (like in create group box when you see chosen members count)
|
||||||
|
boxTitleCloseFg: cancelIconFg; // settings close icon and box search cancel icon (like in contacts box)
|
||||||
|
boxTitleCloseFgOver: cancelIconFgOver; // settings close icon and box search cancel icon (like in contacts box) with mouse over
|
||||||
|
membersAboutLimitFg: #677a8b; // text in channel members box about the limit (max 200 last members are shown)
|
||||||
|
contactsBg: #17212b; // contacts (and some other) box row background
|
||||||
|
contactsBgOver: #1f2c39; // contacts (and some other) box row background with mouse over
|
||||||
|
contactsNameFg: boxTextFg; // contacts (and some other) box row name text
|
||||||
|
contactsStatusFg: #677a8b; // contacts (and some other) box row additional text (like last seen stamp)
|
||||||
|
contactsStatusFgOver: #677a8b; // contacts (and some other) box row additional text (like last seen stamp) with mouse over
|
||||||
|
contactsStatusFgOnline: #559be0; // contacts (and some other) box row active additional text (like online status)
|
||||||
|
photoCropFadeBg: layerBg; // avatar crop box fade background (when choosing a new photo in Settings or for a group)
|
||||||
|
photoCropPointFg: #ffffff7f; // avatar crop box corner rectangles (when choosing a new photo in Settings or for a group)
|
||||||
|
callArrowFg: #49a2f0; // received phone call arrow (in calls list box)
|
||||||
|
callArrowMissedFg: #ed5050; // missed phone call arrow (in calls list box)
|
||||||
|
introBg: windowBg; // login background
|
||||||
|
introTitleFg: #eeeeee; // login title text
|
||||||
|
introDescriptionFg: #72879b; // login description text
|
||||||
|
introErrorFg: #e94040; // login error text (like when providing a wrong log in code)
|
||||||
|
introCoverTopBg: #124a82; // intro gradient top (from)
|
||||||
|
introCoverBottomBg: #23659f; // intro gradient bottom (to)
|
||||||
|
introCoverIconsFg: #3b7cbd; // intro cloud graphics
|
||||||
|
introCoverPlaneTrace: #3870a8; // intro plane traces
|
||||||
|
introCoverPlaneInner: #ced9e2; // intro plane part
|
||||||
|
introCoverPlaneOuter: #97a9b5; // intro plane part
|
||||||
|
introCoverPlaneTop: #ffffff; // intro plane part
|
||||||
|
dialogsMenuIconFg: menuIconFg; // main menu and lock telegram icon
|
||||||
|
dialogsMenuIconFgOver: menuIconFgOver; // main menu and lock telegram icon with mouse over
|
||||||
|
dialogsBg: windowBg; // chat list background
|
||||||
|
dialogsNameFg: #f5f5f5; // chat list name text
|
||||||
|
dialogsChatIconFg: dialogsNameFg; // chat list group or channel icon
|
||||||
|
dialogsDateFg: #8696a8; // chat list date text
|
||||||
|
dialogsTextFg: #7f91a4; // chat list message text
|
||||||
|
dialogsTextFgService: #73b9f5; // chat list group sender name text (or media message type text)
|
||||||
|
dialogsDraftFg: #ff525d; // chat list draft label
|
||||||
|
dialogsVerifiedIconBg: #6ab3f3; // chat list verified icon background
|
||||||
|
dialogsVerifiedIconFg: #17212b; // chat list verified icon check
|
||||||
|
dialogsSendingIconFg: #647d96; // chat list sending message icon (clock)
|
||||||
|
dialogsSentIconFg: #72bcfd; // chat list sent message tick / double tick icon
|
||||||
|
dialogsUnreadBg: #4082bc; // chat list unread badge background for not muted chat
|
||||||
|
dialogsUnreadBgMuted: #3e546a; // chat list unread badge background for muted chat
|
||||||
|
dialogsUnreadFg: #ffffff; // chat list unread badge text
|
||||||
|
dialogsBgOver: #202b36; // chat list background with mouse over
|
||||||
|
dialogsOnlineBadgeFg: #63b6ff; // chat list online status
|
||||||
|
dialogsNameFgOver: windowBoldFgOver; // chat list name text with mouse over
|
||||||
|
dialogsChatIconFgOver: dialogsNameFgOver; // chat list group or channel icon with mouse over
|
||||||
|
dialogsDateFgOver: #8495a9; // chat list date text with mouse over
|
||||||
|
dialogsTextFgOver: #91a3b5; // chat list message text with mouse over
|
||||||
|
dialogsTextFgServiceOver: #73b9f5; // chat list group sender name text with mouse over
|
||||||
|
dialogsDraftFgOver: dialogsDraftFg; // chat list draft label with mouse over
|
||||||
|
dialogsVerifiedIconBgOver: #6ab3f3; // chat list verified icon background with mouse over
|
||||||
|
dialogsVerifiedIconFgOver: dialogsVerifiedIconFg; // chat list verified icon check with mouse over
|
||||||
|
dialogsSendingIconFgOver: dialogsSendingIconFg; // chat list sending message icon (clock) with mouse over
|
||||||
|
dialogsSentIconFgOver: #72bcfd; // chat list sent message tick / double tick icon with mouse over
|
||||||
|
dialogsUnreadBgOver: #4082bc; // chat list unread badge background for not muted chat with mouse over
|
||||||
|
dialogsUnreadBgMutedOver: #4d5762; // chat list unread badge background for muted chat with mouse over
|
||||||
|
dialogsUnreadFgOver: dialogsUnreadFg; // chat list unread badge text with mouse over
|
||||||
|
dialogsBgActive: #2b5278; // chat list background for current (active) chat
|
||||||
|
dialogsNameFgActive: windowFgActive; // chat list name text for current (active) chat
|
||||||
|
dialogsChatIconFgActive: dialogsNameFgActive; // chat list group or channel icon for current (active) chat
|
||||||
|
dialogsDateFgActive: windowFgActive; // chat list date text for current (active) chat
|
||||||
|
dialogsTextFgActive: windowFgActive; // chat list message text for current (active) chat
|
||||||
|
dialogsTextFgServiceActive: dialogsTextFgActive; // chat list group sender name text for current (active) chat
|
||||||
|
dialogsDraftFgActive: #a9caf0; // chat list draft label for current (active) chat
|
||||||
|
dialogsVerifiedIconBgActive: dialogsTextFgActive; // chat list verified icon background for current (active) chat
|
||||||
|
dialogsVerifiedIconFgActive: dialogsBgActive; // chat list verified icon check for current (active) chat
|
||||||
|
dialogsSendingIconFgActive: #ffffff99; // chat list sending message icon (clock) for current (active) chat
|
||||||
|
dialogsSentIconFgActive: dialogsTextFgActive; // chat list sent message tick / double tick icon for current (active) chat
|
||||||
|
dialogsUnreadBgActive: dialogsTextFgActive; // chat list unread badge background for not muted chat for current (active) chat
|
||||||
|
dialogsUnreadBgMutedActive: #7aa3ca; // chat list unread badge background for muted chat for current (active) chat
|
||||||
|
dialogsUnreadFgActive: #2a5378; // chat list unread badge text for current (active) chat
|
||||||
|
dialogsOnlineBadgeFgActive: #ffffff; // chat list online status for current (active) chat
|
||||||
|
dialogsRippleBg: #25313d; //
|
||||||
|
dialogsRippleBgActive: #315a80; //
|
||||||
|
dialogsForwardBg: dialogsBgActive; // forwarding panel background (when forwarding messages in the smallest window size)
|
||||||
|
dialogsForwardFg: dialogsNameFgActive; // forwarding panel text (when forwarding messages in the smallest window size)
|
||||||
|
searchedBarBg: #202b38; // search results bar background (in chats list, contacts box..)
|
||||||
|
searchedBarFg: #8c98a4; // search results bar text (in chats list, contacts box..)
|
||||||
|
topBarBg: #17212b; // top bar background (in chat view, media overview..)
|
||||||
|
emojiPanBg: windowBg; // emoji panel background
|
||||||
|
emojiPanCategories: #17212b; // emoji panel categories background
|
||||||
|
emojiPanHeaderFg: #7c8d9e; // emoji panel section header text
|
||||||
|
emojiPanHeaderBg: #fffffff2; // emoji panel section header background
|
||||||
|
stickerPanDeleteBg: #000000cc; // delete X button background for custom sent stickers in stickers panel (legacy)
|
||||||
|
stickerPanDeleteFg: windowFgActive; // delete X button icon for custom sent stickers in stickers panel (legacy)
|
||||||
|
stickerPreviewBg: #000000b0; // sticker and GIF preview background (when you press and hold on a sticker)
|
||||||
|
historyTextInFg: windowFg; // inbox message text
|
||||||
|
historyTextInFgSelected: #ffffff; // inbox message selected text or text in a selected message
|
||||||
|
historyTextOutFg: #e4ecf2; // outbox message text
|
||||||
|
historyTextOutFgSelected: #ffffff; // outbox message selected text or text in a selected message
|
||||||
|
historyLinkInFg: #70baf5; // inbox message link
|
||||||
|
historyLinkInFgSelected: #aadcff; // inbox message link in a selected text or message
|
||||||
|
historyLinkOutFg: #83caff; // outbox message link
|
||||||
|
historyLinkOutFgSelected: #aadcff; // outbox message link in a selected text or message
|
||||||
|
historyFileNameInFg: historyTextInFg; // inbox media filename text
|
||||||
|
historyFileNameInFgSelected: #ffffff; // inbox media filename text in a selected message
|
||||||
|
historyFileNameOutFg: historyTextOutFg; // outbox media filename text
|
||||||
|
historyFileNameOutFgSelected: #ffffff; // outbox media filename text in a selected message
|
||||||
|
historyOutIconFg: #6bbfff; // outbox message tick / double tick icon
|
||||||
|
historyOutIconFgSelected: #ffffff; // outbox message tick / double tick icon in a selected message
|
||||||
|
historyIconFgInverted: #ffffffe5; // media message tick / double tick icon (like in sent photo)
|
||||||
|
historySendingOutIconFg: #70a4d2; // outbox sending message icon (clock)
|
||||||
|
historySendingInIconFg: #76838b; // inbox sending message icon (clock) (like in sent messages to yourself or in sent messages to a channel)
|
||||||
|
historySendingInvertedIconFg: #ffffffc8; // media sending message icon (clock) (like in sent photo)
|
||||||
|
historyCallArrowInFg: #5093d6; // received phone call arrow
|
||||||
|
historyCallArrowInFgSelected: #ffffff; // received phone call arrow in a selected message
|
||||||
|
historyCallArrowMissedInFg: callArrowMissedFg; // missed phone call arrow
|
||||||
|
historyCallArrowMissedInFgSelected: #ffffff; // missed phone call arrow in a selected message
|
||||||
|
historyCallArrowOutFg: #ffffff; // outgoing phone call arrow
|
||||||
|
historyCallArrowOutFgSelected: #ffffff; // outgoing phone call arrow
|
||||||
|
historyUnreadBarBg: #182433; // new unread messages bar background
|
||||||
|
historyUnreadBarBorder: #03080d00; // new unread messages bar shadow
|
||||||
|
historyUnreadBarFg: #ffffff; // new unread messages bar text
|
||||||
|
historyForwardChooseBg: #0000004c; // forwarding messages in a large window size "choose recipient" background
|
||||||
|
historyForwardChooseFg: windowFgActive; // forwarding messages in a large window size "choose recipient" text
|
||||||
|
historyPeer1NameFg: #fb6169; // red group member name
|
||||||
|
historyPeer1NameFgSelected: #ffffff; // red group member name in a selected message
|
||||||
|
historyPeer1UserpicBg: #ff845e; // red userpic background
|
||||||
|
historyPeer2NameFg: #85de85; // green group member name
|
||||||
|
historyPeer2NameFgSelected: #ffffff; // green group member name in a selected message
|
||||||
|
historyPeer2UserpicBg: #9ad164; // green userpic background
|
||||||
|
historyPeer3NameFg: #f3bc5c; // yellow group member name
|
||||||
|
historyPeer3NameFgSelected: #ffffff; // yellow group member name in a selected message
|
||||||
|
historyPeer3UserpicBg: #e5ca77; // yellow userpic background (actually unused)
|
||||||
|
historyPeer4NameFg: #65bdf3; // blue group member name
|
||||||
|
historyPeer4NameFgSelected: #ffffff; // blue group member name in a selected message
|
||||||
|
historyPeer4UserpicBg: #5caffa; // blue userpic background
|
||||||
|
historyPeer5NameFg: #b48bf2; // purple group member name
|
||||||
|
historyPeer5NameFgSelected: #ffffff; // purple group member name in a selected message
|
||||||
|
historyPeer5UserpicBg: #b694f9; // purple userpic background
|
||||||
|
historyPeer6NameFg: #ff5694; // pink group member name
|
||||||
|
historyPeer6NameFgSelected: #ffffff; // pink group member name in a selected message
|
||||||
|
historyPeer6UserpicBg: #ff8aac; // pink userpic background
|
||||||
|
historyPeer7NameFg: #62d4e3; // sea group member name
|
||||||
|
historyPeer7NameFgSelected: #ffffff; // sea group member name in a selected message
|
||||||
|
historyPeer7UserpicBg: #5bcbe3; // sea userpic background
|
||||||
|
historyPeer8NameFg: #faa357; // orange group member name
|
||||||
|
historyPeer8NameFgSelected: #ffffff; // orange group member name in a selected message
|
||||||
|
historyPeer8UserpicBg: #febb5b; // orange userpic background
|
||||||
|
historyPeerUserpicFg: windowFgActive; // default userpic initials
|
||||||
|
historyPeer1UserpicBg2: #d45246; // the second red userpic background
|
||||||
|
historyPeer2UserpicBg2: #46ba43; // the second green userpic background
|
||||||
|
historyPeer3UserpicBg2: #e5ca77; // the second yellow userpic background (actually unused)
|
||||||
|
historyPeer4UserpicBg2: #408acf; // the second blue userpic background
|
||||||
|
historyPeer5UserpicBg2: #6c61df; // the second purple userpic background
|
||||||
|
historyPeer6UserpicBg2: #d95574; // the second pink userpic background
|
||||||
|
historyPeer7UserpicBg2: #359ad4; // the second sea userpic background
|
||||||
|
historyPeer8UserpicBg2: #f68136; // the second orange userpic background
|
||||||
|
historyPeerSavedMessagesBg2: historyPeer4UserpicBg2; // the second saved messages userpic background
|
||||||
|
historyScrollBarBg: #7f84897a; // scroll bar current rectangle, the bar itself in the chat view (adjusted)
|
||||||
|
historyScrollBarBgOver: #64686cbc; // scroll bar current rectangle with mouse over it in the chat view (adjusted)
|
||||||
|
historyScrollBg: #565a5e4c; // scroll bar background (adjusted)
|
||||||
|
historyScrollBgOver: #5a5d616b; // scroll bar background with mouse over the scroll bar (adjusted)
|
||||||
|
msgInBg: #182533; // inbox message background
|
||||||
|
msgInBgSelected: #2e70a5; // inbox selected message background (and background of selected text in those messages)
|
||||||
|
msgOutBg: #2b5278; // outbox message background
|
||||||
|
msgOutBgSelected: #2e70a5; // outbox selected message background (and background of selected text in those messages)
|
||||||
|
msgSelectOverlay: #3585d44c; // overlay which is filling the media parts of selected messages (like in selected photo message)
|
||||||
|
msgStickerOverlay: #3585d47f; // overlay which is filling the selected sticker message
|
||||||
|
msgInServiceFg: #71bafa; // inbox message information text (like information about a forwarded message original sender)
|
||||||
|
msgInServiceFgSelected: #ffffff; // inbox selected message information text (like information about a forwarded message original sender)
|
||||||
|
msgOutServiceFg: #90caff; // outbox message information text (like information about a forwarded message original sender)
|
||||||
|
msgOutServiceFgSelected: #ffffff; // outbox message information text (like information about a forwarded message original sender)
|
||||||
|
msgInShadow: #748ea200; // inbox message shadow (below the bubble)
|
||||||
|
msgInShadowSelected: #538ebb00; // inbox selected message shadow (below the bubble)
|
||||||
|
msgOutShadow: #00000000; // outbox message shadow (below the bubble)
|
||||||
|
msgOutShadowSelected: #366ea600; // outbox selected message shadow (below the bubble)
|
||||||
|
msgInDateFg: #6d7f8f; // inbox message time text
|
||||||
|
msgInDateFgSelected: #ffffff; // inbox selected message time text
|
||||||
|
msgOutDateFg: #7da8d3; // outbox message time text
|
||||||
|
msgOutDateFgSelected: #ffffff; // outbox selected message time text
|
||||||
|
msgServiceFg: windowFgActive; // service message text (like date dividers or service message about the group title being changed)
|
||||||
|
msgServiceBg: #213040d5; // service message background (like in a service message about group title being changed) (adjusted)
|
||||||
|
msgServiceBgSelected: #2e7ab4; // service message selected text background (like in a service message about group title being changed) (adjusted)
|
||||||
|
msgInReplyBarColor: #429bdb; // inbox message reply outline
|
||||||
|
msgInReplyBarSelColor: #ffffff; // inbox selected message reply outline
|
||||||
|
msgOutReplyBarColor: #65b9f4; // outbox message reply outline
|
||||||
|
msgOutReplyBarSelColor: #ffffff; // outbox selected message reply outline
|
||||||
|
msgImgReplyBarColor: msgServiceFg; // sticker message reply outline
|
||||||
|
msgInMonoFg: #5a8cb7; // inbox message monospace text (like a message sent with `test` text)
|
||||||
|
msgOutMonoFg: #aed1f3; // outbox message monospace text
|
||||||
|
msgInMonoFgSelected: #a3cdf7; // inbox message monospace text in a selected text or message
|
||||||
|
msgOutMonoFgSelected: #a3cdf7; // outbox message monospace text in a selected text or message
|
||||||
|
msgDateImgFg: #fffffff2; // media message time text (like time text in a sent photo)
|
||||||
|
msgDateImgBg: #00000054; // media message time bubble background (like time bubble in a sent photo) or file with thumbnail download icon circle background
|
||||||
|
msgDateImgBgOver: #00000074; // media message download icon circle background with mouse over (like file with thumbnail download icon)
|
||||||
|
msgDateImgBgSelected: #204f7887; // selected media message time bubble background
|
||||||
|
msgFileThumbLinkInFg: lightButtonFg; // inbox media file message with thumbnail download / open with button text
|
||||||
|
msgFileThumbLinkInFgSelected: #ffffff; // inbox selected media file message with thumbnail download / open with button text
|
||||||
|
msgFileThumbLinkOutFg: #6c9ecf; // outbox media file message with thumbnail download / open with button text
|
||||||
|
msgFileThumbLinkOutFgSelected: #ffffff; // outbox selected media file message with thumbnail download / open with button text
|
||||||
|
msgFileInBg: #3f96d0; // inbox audio file download circle background
|
||||||
|
msgFileInBgOver: #489ed7; // inbox audio file download circle background with mouse over
|
||||||
|
msgFileInBgSelected: #6ab4f4; // inbox selected audio file download circle background
|
||||||
|
msgFileOutBg: #4c9ce2; // outbox audio file download circle background
|
||||||
|
msgFileOutBgOver: #54a4e9; // outbox audio file download circle background with mouse over
|
||||||
|
msgFileOutBgSelected: #58abf3; // outbox selected audio file download circle background
|
||||||
|
msgFile1Bg: #3e7eba; // blue shared links / files without image square thumbnail
|
||||||
|
msgFile1BgDark: #24679e; // blue shared files without image download circle background
|
||||||
|
msgFile1BgOver: #1d5e93; // blue shared files without image download circle background with mouse over
|
||||||
|
msgFile1BgSelected: #ffffff; // blue shared files without image download circle background if file is selected
|
||||||
|
msgFile2Bg: #3ea34a; // green shared links / shared files without image square thumbnail
|
||||||
|
msgFile2BgDark: #298835; // green shared files without image download circle background
|
||||||
|
msgFile2BgOver: #1b7725; // green shared files without image download circle background with mouse over
|
||||||
|
msgFile2BgSelected: #1b7725; // green shared files without image download circle background if file is selected
|
||||||
|
msgFile3Bg: #d6454c; // red shared links / shared files without image square thumbnail
|
||||||
|
msgFile3BgDark: #bf333a; // red shared files without image download circle background
|
||||||
|
msgFile3BgOver: #b2282f; // red shared files without image download circle background with mouse over
|
||||||
|
msgFile3BgSelected: #b2282f; // red shared files without image download circle background if file is selected
|
||||||
|
msgFile4Bg: #d99546; // yellow shared links / shared files without image square thumbnail
|
||||||
|
msgFile4BgDark: #c17d39; // yellow shared files without image download circle background
|
||||||
|
msgFile4BgOver: #ac6b29; // yellow shared files without image download circle background with mouse over
|
||||||
|
msgFile4BgSelected: #ac6b29; // yellow shared files without image download circle background if file is selected
|
||||||
|
historyFileInIconFg: #ffffff; // inbox file without thumbnail (like audio file) download arrow icon
|
||||||
|
historyFileInIconFgSelected: #ffffff; // inbox selected file without thumbnail (like audio file) download arrow icon
|
||||||
|
historyFileInRadialFg: #ffffff; // inbox file without thumbnail (like audio file) radial download animation line
|
||||||
|
historyFileInRadialFgSelected: historyFileInIconFgSelected; // inbox selected file without thumbnail (like audio file) radial download animation line
|
||||||
|
historyFileOutIconFg: #ffffff; // outbox file without thumbnail (like audio file) download arrow icon
|
||||||
|
historyFileOutIconFgSelected: #ffffff; // outbox selected file without thumbnail (like audio file) download arrow icon
|
||||||
|
historyFileOutRadialFg: #ffffff; // outbox file without thumbnail (like audio file) radial download animation line
|
||||||
|
historyFileOutRadialFgSelected: #ffffff; // outbox selected file without thumbnail (like audio file) radial download animation line
|
||||||
|
historyFileThumbIconFg: #efefef; // file with thumbnail (or photo / video) download arrow icon
|
||||||
|
historyFileThumbIconFgSelected: #ffffff; // selected file with thumbnail (or photo / video) download arrow icon
|
||||||
|
historyFileThumbRadialFg: historyFileThumbIconFg; // file with thumbnail (or photo / video) radial download animation line
|
||||||
|
historyFileThumbRadialFgSelected: #ffffff; // selected file with thumbnail (or photo / video) radial download animation line
|
||||||
|
historyVideoMessageProgressFg: historyFileThumbIconFg; // radial playback progress in round video messages
|
||||||
|
msgWaveformInActive: #549cd7; // inbox voice message active waveform lines (like played part of currently playing voice message)
|
||||||
|
msgWaveformInActiveSelected: #ffffff; // inbox selected voice message active waveform lines (like played part of currently playing voice message)
|
||||||
|
msgWaveformInInactive: #3a4d61; // inbox voice message inactive waveform lines (like upcoming part of currently playing voice message)
|
||||||
|
msgWaveformInInactiveSelected: #6fa5d4; // inbox selected voice message inactive waveform lines (like upcoming part of currently playing voice message)
|
||||||
|
msgWaveformOutActive: #62b2fd; // outbox voice message active waveform lines (like played part of currently playing voice message)
|
||||||
|
msgWaveformOutActiveSelected: #ffffff; // outbox selected voice message active waveform lines (like played part of currently playing voice message)
|
||||||
|
msgWaveformOutInactive: #4b7fb3; // outbox voice message inactive waveform lines (like upcoming part of currently playing voice message)
|
||||||
|
msgWaveformOutInactiveSelected: #6fa5d4; // outbox selected voice message inactive waveform lines (like upcoming part of currently playing voice message)
|
||||||
|
msgBotKbOverBgAdd: #80b1db0f; // this is painted over a bot inline keyboard button (which has msgServiceBg background) when mouse is over that button
|
||||||
|
msgBotKbIconFg: msgServiceFg; // bot inline keyboard button icon in the top-right corner (like in @vote bot when a poll is ready to be shared)
|
||||||
|
msgBotKbRippleBg: #92c0e50b; // bot inline keyboard button ripple effect
|
||||||
|
mediaInFg: msgInDateFg; // inbox media message status text (like in file that is being downloaded)
|
||||||
|
mediaInFgSelected: msgInDateFgSelected; // inbox selected media message status text (like in file that is being downloaded)
|
||||||
|
mediaOutFg: msgOutDateFg; // outbox media message status text (like in file that is being downloaded)
|
||||||
|
mediaOutFgSelected: msgOutDateFgSelected; // outbox selected media message status text (like in file that is being downloaded)
|
||||||
|
youtubePlayIconBg: #e83131c8; // youtube play icon background (when a link to a youtube video with a webpage preview is sent)
|
||||||
|
youtubePlayIconFg: windowFgActive; // youtube play icon arrow (when a link to a youtube video with a webpage preview is sent)
|
||||||
|
videoPlayIconBg: #0000007f; // other video play icon background (like when a link to a vimeo video with a webpage preview is sent)
|
||||||
|
videoPlayIconFg: #ffffff; // other video play icon arrow (like when a link to a vimeo video with a webpage preview is sent)
|
||||||
|
toastBg: #000000b2; // toast notification background (like when you click on your t.me link when editing your username)
|
||||||
|
toastFg: windowFgActive; // toast notification text (like when you click on your t.me link when editing your username)
|
||||||
|
reportSpamBg: #363c42; // report spam panel background (like a non contact user writes your for the first time)
|
||||||
|
reportSpamFg: windowFg; // report spam panel text (when you send a report from that panel)
|
||||||
|
historyToDownBg: #1d2b3a; // arrow button background (to scroll to the end of the viewed chat)
|
||||||
|
historyToDownBgOver: #243446; // arrow button background with mouse over
|
||||||
|
historyToDownBgRipple: #2b3c4f; // arrow button ripple effect
|
||||||
|
historyToDownFg: #adb4ba; // arrow button icon
|
||||||
|
historyToDownFgOver: menuIconFgOver; // arrow button icon with mouse over
|
||||||
|
historyToDownShadow: #00000040; // arrow button shadow
|
||||||
|
historyComposeAreaBg: #17212b; // history compose area background (message write area / reply information / forwarding information)
|
||||||
|
historyComposeAreaFg: historyTextInFg; // history compose area text
|
||||||
|
historyComposeAreaFgService: msgInDateFg; // history compose area text when replying to a media message
|
||||||
|
historyComposeIconFg: menuIconFg; // history compose area icon (like emoji, attach, bot command..)
|
||||||
|
historyComposeIconFgOver: menuIconFgOver; // history compose area icon with mouse over
|
||||||
|
historySendIconFg: windowBgActive; // send message icon
|
||||||
|
historySendIconFgOver: windowBgActive; // send message icon with mouse over
|
||||||
|
historyPinnedBg: #1b2734; // pinned message area background
|
||||||
|
historyReplyBg: historyComposeAreaBg; // reply / forward / edit message area background
|
||||||
|
historyReplyIconFg: windowBgActive; // reply / forward / edit message left icon
|
||||||
|
historyReplyCancelFg: cancelIconFg; // reply / forward / edit message cancel button
|
||||||
|
historyReplyCancelFgOver: cancelIconFgOver; // reply / forward / edit message cancel button with mouse over
|
||||||
|
historyComposeButtonBg: historyComposeAreaBg; // unblock / join channel / mute channel button background
|
||||||
|
historyComposeButtonBgOver: #1c2835; // unblock / join channel / mute channel button background with mouse over
|
||||||
|
historyComposeButtonBgRipple: #222f3e; // unblock / join channel / mute channel button ripple effect
|
||||||
|
overviewCheckBg: #00000040; // shared files / links checkbox background for not selected rows when some rows are selected
|
||||||
|
overviewCheckFg: #ffffff; // shared files / links checkbox icon for not selected rows when some rows are selected
|
||||||
|
overviewCheckFgActive: #ffffff; // shared files / links checkbox icon for selected rows
|
||||||
|
overviewPhotoSelectOverlay: #3fa2e333; // shared photos / videos / links fill for selected rows
|
||||||
|
profileStatusFgOver: #677a8b; // group members list in group profile user last seen text with mouse over
|
||||||
|
profileVerifiedCheckBg: windowBgActive; // profile verified check icon background
|
||||||
|
profileVerifiedCheckFg: #ffffff; // profile verified check icon tick
|
||||||
|
profileAdminStartFg: #62a9e6; // group members list admin star icon
|
||||||
|
notificationsBoxMonitorFg: windowFg; // custom notifications settings box monitor color
|
||||||
|
notificationsBoxScreenBg: dialogsBgActive; // #6389a8; // custom notifications settings box monitor screen background
|
||||||
|
notificationSampleUserpicFg: windowBgActive; // custom notifications settings box small sample userpic placeholder
|
||||||
|
notificationSampleCloseFg: #d7d7d7; // custom notifications settings box small sample close button placeholder
|
||||||
|
notificationSampleTextFg: #d7d7d7; // custom notifications settings box small sample text placeholder
|
||||||
|
notificationSampleNameFg: #939393; // custom notifications settings box small sample name placeholder
|
||||||
|
changePhoneSimcardFrom: notificationSampleTextFg; // change phone number box left simcard icon
|
||||||
|
changePhoneSimcardTo: notificationSampleNameFg; // change phone number box right simcard and plane icons
|
||||||
|
mainMenuBg: windowBg; // main menu background
|
||||||
|
mainMenuCoverBg: #276899; // main menu top cover background
|
||||||
|
mainMenuCoverFg: windowFgActive; // main menu top cover text
|
||||||
|
mainMenuCloudFg: activeButtonFg; //
|
||||||
|
mainMenuCloudBg: #185680; //
|
||||||
|
mediaPlayerBg: windowBg; // audio file player background
|
||||||
|
mediaPlayerActiveFg: windowBgActive; // audio file player playback progress already played part
|
||||||
|
mediaPlayerInactiveFg: sliderBgInactive; // audio file player playback progress upcoming (not played yet) part with mouse over
|
||||||
|
mediaPlayerDisabledFg: #9dd1ef; // audio file player loading progress (when you're playing an audio file and switch to the previous one which is not loaded yet)
|
||||||
|
mediaviewFileBg: windowBg; // file rectangle background (when you view a png file in Media Viewer and go to a previous, not loaded yet, file)
|
||||||
|
mediaviewFileNameFg: windowFg; // file name in file rectangle
|
||||||
|
mediaviewFileSizeFg: windowSubTextFg; // file size text in file rectangle
|
||||||
|
mediaviewFileRedCornerFg: #d55959; // red file thumbnail placeholder corner in file rectangle (for a file without thumbnail, like .pdf)
|
||||||
|
mediaviewFileYellowCornerFg: #e8a659; // yellow file thumbnail placeholder corner in file rectangle (for a file without thumbnail, like .zip)
|
||||||
|
mediaviewFileGreenCornerFg: #49a957; // green file thumbnail placeholder corner in file rectangle (for a file without thumbnail, like .exe)
|
||||||
|
mediaviewFileBlueCornerFg: #599dcf; // blue file thumbnail placeholder corner in file rectangle (for a file without thumbnail, like .dmg)
|
||||||
|
mediaviewFileExtFg: activeButtonFg; // file extension text in file thumbnail placeholder in file rectangle
|
||||||
|
mediaviewMenuBg: #383838; // context menu in Media Viewer background
|
||||||
|
mediaviewMenuBgOver: #505050; // context menu item background with mouse over
|
||||||
|
mediaviewMenuBgRipple: #676767; // context menu item ripple effect
|
||||||
|
mediaviewMenuFg: windowFgActive; // context menu item text
|
||||||
|
mediaviewBg: #222222eb; // Media Viewer background
|
||||||
|
mediaviewVideoBg: imageBg; // Media Viewer background when viewing a video in full screen
|
||||||
|
mediaviewControlBg: #0000003c; // controls background (like next photo / previous photo)
|
||||||
|
mediaviewControlFg: windowFgActive; // controls icon (like next photo / previous photo)
|
||||||
|
mediaviewCaptionBg: #11111180; // caption text background (when viewing photo with caption)
|
||||||
|
mediaviewCaptionFg: mediaviewControlFg; // caption text
|
||||||
|
mediaviewTextLinkFg: #70baf5; // caption text link
|
||||||
|
mediaviewSaveMsgBg: toastBg; // save to file toast message background in Media Viewer
|
||||||
|
mediaviewSaveMsgFg: toastFg; // save to file toast message text
|
||||||
|
mediaviewPlaybackActive: #c7c7c7; // video playback progress already played part
|
||||||
|
mediaviewPlaybackInactive: #252525; // video playback progress upcoming (not played yet) part
|
||||||
|
mediaviewPlaybackActiveOver: #ffffff; // video playback progress already played part with mouse over
|
||||||
|
mediaviewPlaybackInactiveOver: #474747; // video playback progress upcoming (not played yet) part with mouse over
|
||||||
|
mediaviewPlaybackProgressFg: #ffffffc7; // video playback progress text
|
||||||
|
mediaviewPlaybackIconFg: mediaviewPlaybackActive; // video playback controls icon
|
||||||
|
mediaviewPlaybackIconFgOver: mediaviewPlaybackActiveOver; // video playback controls icon with mouse over
|
||||||
|
mediaviewTransparentBg: #ffffff; // transparent filling part (when viewing a transparent .png file in Media Viewer)
|
||||||
|
mediaviewTransparentFg: #cccccc; // another transparent filling part
|
||||||
|
notificationBg: windowBg; // custom notification window background
|
||||||
|
callBg: #14191ff5; // phone call popup background
|
||||||
|
callNameFg: #ffffff; // phone call popup name text
|
||||||
|
callFingerprintBg: #00000066; // phone call popup emoji fingerprint background
|
||||||
|
callStatusFg: #aaabac; // phone call popup status text
|
||||||
|
callIconFg: #ffffff; // phone call popup answer, hangup and mute mic icon
|
||||||
|
callAnswerBg: #488fc9; // phone call popup answer button background
|
||||||
|
callAnswerRipple: #4286c2; // phone call popup answer button ripple effect
|
||||||
|
callAnswerBgOuter: #3f95eb26; // phone call popup answer button outer ripple effect
|
||||||
|
callHangupBg: #cc4646; // phone call popup hangup button background
|
||||||
|
callHangupRipple: #ca4141; // phone call popup hangup button ripple effect
|
||||||
|
callCancelBg: #ffffff; // phone call popup line busy cancel button background
|
||||||
|
callCancelFg: #536271; // phone call popup line busy cancel button icon
|
||||||
|
callCancelRipple: #435363; // phone call popup line busy cancel button ripple effect
|
||||||
|
callMuteRipple: #ffffff12; // phone call popup mute mic ripple effect
|
||||||
|
callBarBg: #366693; // active phone call bar background
|
||||||
|
callBarMuteRipple: #4b7dab; // active phone call bar mute and hangup button ripple effect
|
||||||
|
callBarBgMuted: #35495d; // phone call bar with muted mic background
|
||||||
|
callBarUnmuteRipple: #435b73; // phone call bar with muted mic mute and hangup button ripple effect
|
||||||
|
callBarFg: dialogsNameFgActive; // phone call bar text and icons
|
||||||
|
importantTooltipBg: toastBg; //
|
||||||
|
importantTooltipFg: toastFg; //
|
||||||
|
importantTooltipFgLink: #65b6fc; //
|
||||||
|
filterInputActiveBg: #242f3d; // default rounded input field active background (like in chats list search field when field is focused)
|
||||||
|
botKbBg: #242f3d; // bot keyboard button background
|
||||||
|
botKbDownBg: #2d3a49; // bot keyboard button ripple effect
|
||||||
|
emojiIconFg: #6c7883; // emoji category icon
|
||||||
|
emojiIconFgActive: #51a0e5; // active emoji category icon
|
||||||
|
overviewCheckBorder: #e4eaef; // shared media round checkbox border
|
||||||
|
sideBarBg: #0e1621; // filters side bar background
|
||||||
|
sideBarBgActive: #25303e; // filters side bar active background
|
||||||
|
sideBarBgRipple: #1e2733; // filters side bar ripple effect
|
||||||
|
sideBarTextFg: #768c9e; // filters side bar text
|
||||||
|
sideBarTextFgActive: #64b9fa; // filters side bar active item text
|
||||||
|
sideBarIconFg: #768c9e; // filters side bar icon
|
||||||
|
sideBarIconFgActive: #5eb5f7; // filters side bar active item icon
|
||||||
|
sideBarBadgeBg: #5eb5f7; // filters side bar badge background
|
||||||
|
sideBarBadgeBgMuted: #768c9e; // filters side bar unimportant badge background
|
||||||
|
statisticsChartInactive: #313d4cc8; // inactive area in footer of statistic charts
|
||||||
|
statisticsChartActive: #526679d8; // sides in footer of statistic charts
|
||||||
@@ -0,0 +1,710 @@
|
|||||||
|
{
|
||||||
|
"$schema": "vscode://schemas/color-theme",
|
||||||
|
"name": "2026 Dark",
|
||||||
|
"include": "./dark_modern.json",
|
||||||
|
"type": "dark",
|
||||||
|
"colors": {
|
||||||
|
"foreground": "#bfbfbf",
|
||||||
|
"disabledForeground": "#555555",
|
||||||
|
"errorForeground": "#f48771",
|
||||||
|
"descriptionForeground": "#8C8C8C",
|
||||||
|
"icon.foreground": "#8C8C8C",
|
||||||
|
"focusBorder": "#3994BCB3",
|
||||||
|
"textBlockQuote.background": "#242526",
|
||||||
|
"textBlockQuote.border": "#2A2B2C",
|
||||||
|
"textCodeBlock.background": "#242526",
|
||||||
|
"textLink.foreground": "#48A0C7",
|
||||||
|
"textLink.activeForeground": "#53A5CA",
|
||||||
|
"textPreformat.background": "#262626",
|
||||||
|
"textPreformat.foreground": "#8C8C8C",
|
||||||
|
"textSeparator.foreground": "#2a2a2a",
|
||||||
|
"button.background": "#297AA0",
|
||||||
|
"button.foreground": "#FFFFFF",
|
||||||
|
"button.hoverBackground": "#2B7DA3",
|
||||||
|
"button.border": "#297AA0",
|
||||||
|
"button.secondaryHoverBackground": "#FFFFFF10",
|
||||||
|
"button.secondaryBorder": "#333536",
|
||||||
|
"checkbox.background": "#242526",
|
||||||
|
"checkbox.border": "#707070",
|
||||||
|
"checkbox.foreground": "#8C8C8C",
|
||||||
|
"dropdown.background": "#191A1B",
|
||||||
|
"dropdown.border": "#333536",
|
||||||
|
"dropdown.foreground": "#bfbfbf",
|
||||||
|
"dropdown.listBackground": "#191A1B",
|
||||||
|
"input.background": "#191A1B",
|
||||||
|
"input.border": "#333536",
|
||||||
|
"input.foreground": "#bfbfbf",
|
||||||
|
"input.placeholderForeground": "#555555",
|
||||||
|
"inputOption.activeBackground": "#313233",
|
||||||
|
"inputOption.activeForeground": "#bfbfbf",
|
||||||
|
"inputOption.activeBorder": "#2A2B2C",
|
||||||
|
"inputValidation.infoBackground": "#1E3A47",
|
||||||
|
"inputValidation.infoBorder": "#3994BC",
|
||||||
|
"inputValidation.infoForeground": "#bfbfbf",
|
||||||
|
"inputValidation.warningBackground": "#352A05",
|
||||||
|
"inputValidation.warningBorder": "#B89500",
|
||||||
|
"inputValidation.warningForeground": "#bfbfbf",
|
||||||
|
"inputValidation.errorBackground": "#3A1D1D",
|
||||||
|
"inputValidation.errorBorder": "#BE1100",
|
||||||
|
"inputValidation.errorForeground": "#bfbfbf",
|
||||||
|
"scrollbar.shadow": "#191B1D4D",
|
||||||
|
"scrollbarSlider.background": "#A8A9AA85",
|
||||||
|
"scrollbarSlider.hoverBackground": "#A8A9AA90",
|
||||||
|
"scrollbarSlider.activeBackground": "#A8A9AA9C",
|
||||||
|
"badge.background": "#307E9F",
|
||||||
|
"badge.foreground": "#FFFFFF",
|
||||||
|
"progressBar.background": "#878889",
|
||||||
|
"list.activeSelectionBackground": "#FFFFFF22",
|
||||||
|
"list.activeSelectionForeground": "#ededed",
|
||||||
|
"list.inactiveSelectionBackground": "#2C2D2E",
|
||||||
|
"list.inactiveSelectionForeground": "#ededed",
|
||||||
|
"list.hoverBackground": "#FFFFFF14",
|
||||||
|
"list.hoverForeground": "#bfbfbf",
|
||||||
|
"list.dropBackground": "#3994BC1A",
|
||||||
|
"toolbar.activeBackground": "#FFFFFF33",
|
||||||
|
"list.focusBackground": "#FFFFFF22",
|
||||||
|
"list.focusForeground": "#bfbfbf",
|
||||||
|
"list.focusOutline": "#3994BCB3",
|
||||||
|
"list.highlightForeground": "#48A0C7",
|
||||||
|
"list.invalidItemForeground": "#444444",
|
||||||
|
"list.errorForeground": "#f48771",
|
||||||
|
"list.warningForeground": "#e5ba7d",
|
||||||
|
"activityBar.background": "#191A1B",
|
||||||
|
"activityBar.foreground": "#bfbfbf",
|
||||||
|
"activityBar.inactiveForeground": "#8C8C8C",
|
||||||
|
"activityBar.activeBackground": "#313233",
|
||||||
|
"activityBar.border": "#2A2B2C",
|
||||||
|
"activityBar.activeBorder": "#bfbfbf",
|
||||||
|
"activityBar.activeFocusBorder": "#3994BCB3",
|
||||||
|
"activityBarBadge.background": "#307E9F",
|
||||||
|
"activityBarBadge.foreground": "#FFFFFF",
|
||||||
|
"activityBarTop.activeBorder": "#bfbfbf",
|
||||||
|
"sideBar.background": "#191A1B",
|
||||||
|
"sideBar.foreground": "#bfbfbf",
|
||||||
|
"sideBar.border": "#2A2B2C",
|
||||||
|
"sideBarTitle.foreground": "#bfbfbf",
|
||||||
|
"sideBarSectionHeader.background": "#191A1B",
|
||||||
|
"sideBarSectionHeader.foreground": "#bfbfbf",
|
||||||
|
"sideBarSectionHeader.border": "#2A2B2C",
|
||||||
|
"titleBar.activeBackground": "#191A1B",
|
||||||
|
"titleBar.activeForeground": "#8C8C8C",
|
||||||
|
"titleBar.inactiveBackground": "#121314",
|
||||||
|
"titleBar.inactiveForeground": "#8C8C8C",
|
||||||
|
"titleBar.border": "#2A2B2C",
|
||||||
|
"menubar.selectionBackground": "#242526",
|
||||||
|
"menubar.selectionForeground": "#bfbfbf",
|
||||||
|
"menu.background": "#202122",
|
||||||
|
"menu.foreground": "#bfbfbf",
|
||||||
|
"menu.selectionBackground": "#3994BC26",
|
||||||
|
"menu.selectionForeground": "#bfbfbf",
|
||||||
|
"menu.selectionBorder": "#3994BC",
|
||||||
|
"menu.separatorBackground": "#2A2B2C",
|
||||||
|
"menu.border": "#2A2B2C",
|
||||||
|
"commandCenter.foreground": "#bfbfbf",
|
||||||
|
"commandCenter.activeForeground": "#bfbfbf",
|
||||||
|
"commandCenter.background": "#191A1B",
|
||||||
|
"commandCenter.activeBackground": "#FFFFFF0F",
|
||||||
|
"commandCenter.border": "#2E3031",
|
||||||
|
"editor.background": "#121314",
|
||||||
|
"editor.foreground": "#BBBEBF",
|
||||||
|
"editorStickyScroll.background": "#121314",
|
||||||
|
"editorStickyScrollHover.background": "#202122",
|
||||||
|
"editorStickyScroll.border": "#2A2B2C",
|
||||||
|
"editorLineNumber.foreground": "#858889",
|
||||||
|
"editorLineNumber.activeForeground": "#BBBEBF",
|
||||||
|
"editorCursor.foreground": "#BBBEBF",
|
||||||
|
"editor.selectionBackground": "#276782dd",
|
||||||
|
"editor.inactiveSelectionBackground": "#27678260",
|
||||||
|
"editor.selectionHighlightBackground": "#27678260",
|
||||||
|
"editor.wordHighlightBackground": "#27678250",
|
||||||
|
"editor.wordHighlightStrongBackground": "#27678280",
|
||||||
|
"editor.findMatchBackground": "#27678290",
|
||||||
|
"editor.findMatchHighlightBackground": "#27678280",
|
||||||
|
"editor.findRangeHighlightBackground": "#FFFFFF13",
|
||||||
|
"editor.hoverHighlightBackground": "#FFFFFF13",
|
||||||
|
"editor.lineHighlightBackground": "#242526",
|
||||||
|
"editor.rangeHighlightBackground": "#FFFFFF13",
|
||||||
|
"editorLink.activeForeground": "#3a94bc",
|
||||||
|
"editorWhitespace.foreground": "#8C8C8C4D",
|
||||||
|
"editorIndentGuide.background1": "#8384854D",
|
||||||
|
"editorIndentGuide.activeBackground1": "#838485",
|
||||||
|
"editorRuler.foreground": "#848484",
|
||||||
|
"editorCodeLens.foreground": "#8C8C8C",
|
||||||
|
"editorBracketMatch.background": "#3994BC55",
|
||||||
|
"editorBracketMatch.border": "#2A2B2C",
|
||||||
|
"editorWidget.background": "#202122",
|
||||||
|
"editorWidget.border": "#2A2B2C",
|
||||||
|
"editorWidget.foreground": "#bfbfbf",
|
||||||
|
"editorSuggestWidget.background": "#202122",
|
||||||
|
"editorSuggestWidget.border": "#2A2B2C",
|
||||||
|
"editorSuggestWidget.foreground": "#bfbfbf",
|
||||||
|
"editorSuggestWidget.highlightForeground": "#bfbfbf",
|
||||||
|
"editorSuggestWidget.selectedBackground": "#FFFFFF26",
|
||||||
|
"editorSuggestWidget.focusOutline": "#3994BCB3",
|
||||||
|
"editorHoverWidget.background": "#202122",
|
||||||
|
"editorHoverWidget.border": "#2A2B2C",
|
||||||
|
"widget.border": "#2A2B2C",
|
||||||
|
"peekView.border": "#2A2B2C",
|
||||||
|
"peekViewEditor.background": "#191A1B",
|
||||||
|
"peekViewEditor.matchHighlightBackground": "#3994BC33",
|
||||||
|
"peekViewResult.background": "#191A1B",
|
||||||
|
"peekViewResult.fileForeground": "#bfbfbf",
|
||||||
|
"peekViewResult.lineForeground": "#8C8C8C",
|
||||||
|
"peekViewResult.matchHighlightBackground": "#3994BC33",
|
||||||
|
"peekViewResult.selectionBackground": "#3994BC26",
|
||||||
|
"peekViewResult.selectionForeground": "#bfbfbf",
|
||||||
|
"peekViewTitle.background": "#242526",
|
||||||
|
"peekViewTitleDescription.foreground": "#8C8C8C",
|
||||||
|
"peekViewTitleLabel.foreground": "#bfbfbf",
|
||||||
|
"editorGutter.background": "#121314",
|
||||||
|
"editorGutter.addedBackground": "#72C892",
|
||||||
|
"editorGutter.deletedBackground": "#F28772",
|
||||||
|
"diffEditor.insertedLineBackground": "#347d3926",
|
||||||
|
"diffEditor.insertedTextBackground": "#57ab5a4d",
|
||||||
|
"diffEditor.removedLineBackground": "#c93c3726",
|
||||||
|
"diffEditor.removedTextBackground": "#f470674d",
|
||||||
|
"editorOverviewRuler.border": "#2A2B2C",
|
||||||
|
"editorOverviewRuler.findMatchForeground": "#3a94bc99",
|
||||||
|
"editorOverviewRuler.modifiedForeground": "#6ab890",
|
||||||
|
"editorOverviewRuler.addedForeground": "#73c991",
|
||||||
|
"editorOverviewRuler.deletedForeground": "#f48771",
|
||||||
|
"editorOverviewRuler.errorForeground": "#f48771",
|
||||||
|
"editorOverviewRuler.warningForeground": "#e5ba7d",
|
||||||
|
"panel.background": "#191A1B",
|
||||||
|
"panel.border": "#2A2B2C",
|
||||||
|
"panelSection.border": "#2A2B2C",
|
||||||
|
"panelSectionHeader.border": "#2A2B2C",
|
||||||
|
"panelTitle.activeBorder": "#3994BC",
|
||||||
|
"panelTitle.activeForeground": "#bfbfbf",
|
||||||
|
"panelTitle.inactiveForeground": "#8C8C8C",
|
||||||
|
"statusBar.background": "#191A1B",
|
||||||
|
"statusBar.inactiveBackground": "#121314",
|
||||||
|
"statusBar.foreground": "#8C8C8C",
|
||||||
|
"statusBar.border": "#2A2B2C",
|
||||||
|
"statusBar.focusBorder": "#3994BCB3",
|
||||||
|
"statusBar.debuggingBackground": "#3994BC",
|
||||||
|
"statusBar.debuggingForeground": "#FFFFFF",
|
||||||
|
"statusBar.noFolderBackground": "#191A1B",
|
||||||
|
"statusBar.noFolderForeground": "#8C8C8C",
|
||||||
|
"statusBarItem.activeBackground": "#4B4C4D",
|
||||||
|
"statusBarItem.hoverBackground": "#323233",
|
||||||
|
"statusBarItem.focusBorder": "#3994BCB3",
|
||||||
|
"statusBarItem.prominentBackground": "#3994BC",
|
||||||
|
"statusBarItem.prominentForeground": "#FFFFFF",
|
||||||
|
"statusBarItem.prominentHoverBackground": "#3994BC",
|
||||||
|
"tab.activeBackground": "#121314",
|
||||||
|
"tab.activeForeground": "#bfbfbf",
|
||||||
|
"tab.inactiveBackground": "#191A1B",
|
||||||
|
"tab.inactiveForeground": "#8C8C8C",
|
||||||
|
"tab.border": "#2A2B2C",
|
||||||
|
"tab.lastPinnedBorder": "#2A2B2C",
|
||||||
|
"tab.activeBorderTop": "#3994BC",
|
||||||
|
"tab.hoverBackground": "#121314",
|
||||||
|
"tab.hoverForeground": "#bfbfbf",
|
||||||
|
"tab.unfocusedActiveBackground": "#121314",
|
||||||
|
"tab.unfocusedActiveForeground": "#8C8C8C",
|
||||||
|
"tab.unfocusedInactiveBackground": "#191A1B",
|
||||||
|
"tab.unfocusedInactiveForeground": "#444444",
|
||||||
|
"editorGroupHeader.tabsBackground": "#191A1B",
|
||||||
|
"tab.activeBorder": "#121314",
|
||||||
|
"editorGroupHeader.tabsBorder": "#2A2B2C",
|
||||||
|
"breadcrumb.foreground": "#8C8C8C",
|
||||||
|
"breadcrumb.background": "#121314",
|
||||||
|
"breadcrumb.focusForeground": "#bfbfbf",
|
||||||
|
"breadcrumb.activeSelectionForeground": "#bfbfbf",
|
||||||
|
"breadcrumbPicker.background": "#202122",
|
||||||
|
"notificationCenter.border": "#2A2B2C",
|
||||||
|
"notificationCenterHeader.foreground": "#bfbfbf",
|
||||||
|
"notificationCenterHeader.background": "#242526",
|
||||||
|
"notificationToast.border": "#2A2B2C",
|
||||||
|
"notifications.foreground": "#bfbfbf",
|
||||||
|
"notifications.background": "#202122",
|
||||||
|
"notifications.border": "#2A2B2C",
|
||||||
|
"notificationLink.foreground": "#3a94bc",
|
||||||
|
"notificationsWarningIcon.foreground": "#CCA700",
|
||||||
|
"notificationsErrorIcon.foreground": "#f48771",
|
||||||
|
"notificationsInfoIcon.foreground": "#3a94bc",
|
||||||
|
"activityWarningBadge.foreground": "#202020",
|
||||||
|
"activityWarningBadge.background": "#CCA700",
|
||||||
|
"activityErrorBadge.foreground": "#FFFFFF",
|
||||||
|
"activityErrorBadge.background": "#f48771",
|
||||||
|
"extensionButton.prominentBackground": "#297AA0",
|
||||||
|
"extensionButton.prominentForeground": "#FFFFFF",
|
||||||
|
"extensionButton.prominentHoverBackground": "#2B7DA3",
|
||||||
|
"pickerGroup.border": "#2A2B2C",
|
||||||
|
"pickerGroup.foreground": "#bfbfbf",
|
||||||
|
"quickInput.background": "#202122",
|
||||||
|
"quickInput.foreground": "#bfbfbf",
|
||||||
|
"quickInputList.focusBackground": "#297AA0",
|
||||||
|
"quickInputList.focusForeground": "#FFFFFF",
|
||||||
|
"quickInputList.focusIconForeground": "#FFFFFF",
|
||||||
|
"quickInputList.focusHighlightForeground": "#FFFFFF",
|
||||||
|
"terminal.selectionBackground": "#3994BC33",
|
||||||
|
"terminal.background": "#191A1B",
|
||||||
|
"terminal.border": "#2A2B2C",
|
||||||
|
"terminal.tab.activeBorder": "#3994BC00",
|
||||||
|
"terminalCursor.foreground": "#bfbfbf",
|
||||||
|
"terminalCursor.background": "#191A1B",
|
||||||
|
"gitDecoration.addedResourceForeground": "#73c991",
|
||||||
|
"gitDecoration.modifiedResourceForeground": "#e5ba7d",
|
||||||
|
"gitDecoration.deletedResourceForeground": "#f48771",
|
||||||
|
"gitDecoration.untrackedResourceForeground": "#73c991",
|
||||||
|
"gitDecoration.ignoredResourceForeground": "#8C8C8C",
|
||||||
|
"gitDecoration.conflictingResourceForeground": "#f48771",
|
||||||
|
"gitDecoration.stageModifiedResourceForeground": "#e5ba7d",
|
||||||
|
"gitDecoration.stageDeletedResourceForeground": "#f48771",
|
||||||
|
"quickInputTitle.background": "#202122",
|
||||||
|
"commandCenter.activeBorder": "#333536",
|
||||||
|
"chat.requestBubbleBackground": "#ffffff13",
|
||||||
|
"chat.requestBubbleHoverBackground": "#ffffff22",
|
||||||
|
"chat.inputWorkingBorderColor1": "#297AA0",
|
||||||
|
"editorCommentsWidget.rangeBackground": "#488FAE26",
|
||||||
|
"editorCommentsWidget.rangeActiveBackground": "#488FAE46",
|
||||||
|
"charts.foreground": "#CCCCCC",
|
||||||
|
"charts.lines": "#C8CACC80",
|
||||||
|
"charts.blue": "#57A3F8",
|
||||||
|
"charts.red": "#EF8773",
|
||||||
|
"charts.yellow": "#E0B97F",
|
||||||
|
"charts.orange": "#CD861A",
|
||||||
|
"charts.green": "#86CF86",
|
||||||
|
"charts.purple": "#AD80D7",
|
||||||
|
"inlineChat.border": "#00000000",
|
||||||
|
"minimapSlider.background": "#A8A9AA85",
|
||||||
|
"minimapSlider.hoverBackground": "#A8A9AA90",
|
||||||
|
"minimapSlider.activeBackground": "#A8A9AA9C",
|
||||||
|
"agents.background": "#121314",
|
||||||
|
"agentsPanel.background": "#191A1B",
|
||||||
|
"agentsPanel.foreground": "#bfbfbf",
|
||||||
|
"agentsPanel.border": "#2A2B2C",
|
||||||
|
"surface.background": "#191A1B",
|
||||||
|
"surface.foreground": "#bfbfbf",
|
||||||
|
"surface.border": "#2A2B2C",
|
||||||
|
"agentsGradient.tintColor": "#297AA0",
|
||||||
|
"agentsChatInput.background": "#202122",
|
||||||
|
"agentsChatInput.foreground": "#bfbfbf",
|
||||||
|
"agentsChatInput.border": "#333536",
|
||||||
|
"agentsChatInput.focusBorder": "#3994BCB3",
|
||||||
|
"agentsChatInput.placeholderForeground": "#555555",
|
||||||
|
"agentsNewSessionButton.background": "#00000000",
|
||||||
|
"agentsNewSessionButton.foreground": "#bfbfbf",
|
||||||
|
"agentsNewSessionButton.border": "#333536",
|
||||||
|
"agentsNewSessionButton.hoverBackground": "#FFFFFF18",
|
||||||
|
"agentsBadge.background": "#307E9F",
|
||||||
|
"agentsBadge.foreground": "#FFFFFF",
|
||||||
|
"agentsUnreadBadge.background": "#307E9F",
|
||||||
|
"agentsUnreadBadge.foreground": "#FFFFFF",
|
||||||
|
"agentsBottomPanel.border": "#00000000"
|
||||||
|
},
|
||||||
|
"tokenColors": [
|
||||||
|
{
|
||||||
|
"scope": [
|
||||||
|
"comment",
|
||||||
|
"punctuation.definition.comment",
|
||||||
|
"string.comment"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#8b949e"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": [
|
||||||
|
"constant.other.placeholder",
|
||||||
|
"constant.character"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#ff7b72"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": [
|
||||||
|
"constant",
|
||||||
|
"entity.name.constant",
|
||||||
|
"variable.other.constant",
|
||||||
|
"variable.other.enummember",
|
||||||
|
"variable.language",
|
||||||
|
"entity"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#79c0ff"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": [
|
||||||
|
"entity.name",
|
||||||
|
"meta.export.default",
|
||||||
|
"meta.definition.variable"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#ffa657"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": [
|
||||||
|
"variable.parameter.function",
|
||||||
|
"meta.jsx.children",
|
||||||
|
"meta.block",
|
||||||
|
"meta.tag.attributes",
|
||||||
|
"entity.name.constant",
|
||||||
|
"meta.object.member",
|
||||||
|
"meta.embedded.expression"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#c9d1d9"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "entity.name.function",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#d2a8ff"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": [
|
||||||
|
"entity.name.tag",
|
||||||
|
"support.class.component"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#7ee787"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "keyword",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#ff7b72"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": [
|
||||||
|
"storage",
|
||||||
|
"storage.type"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#ff7b72"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": [
|
||||||
|
"storage.modifier.package",
|
||||||
|
"storage.modifier.import",
|
||||||
|
"storage.type.java"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#c9d1d9"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": [
|
||||||
|
"string",
|
||||||
|
"string punctuation.section.embedded source"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#a5d6ff"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "support",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#79c0ff"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "meta.property-name",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#79c0ff"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "variable",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#ffa657"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "variable.other",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#c9d1d9"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "invalid.broken",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#ffa198",
|
||||||
|
"fontStyle": "italic"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "invalid.deprecated",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#ffa198",
|
||||||
|
"fontStyle": "italic"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "invalid.illegal",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#ffa198",
|
||||||
|
"fontStyle": "italic"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "invalid.unimplemented",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#ffa198",
|
||||||
|
"fontStyle": "italic"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "carriage-return",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#f0f6fc",
|
||||||
|
"fontStyle": "italic underline"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "message.error",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#ffa198"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "string variable",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#79c0ff"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": [
|
||||||
|
"source.regexp",
|
||||||
|
"string.regexp"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#a5d6ff"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": [
|
||||||
|
"string.regexp.character-class",
|
||||||
|
"string.regexp constant.character.escape",
|
||||||
|
"string.regexp source.ruby.embedded",
|
||||||
|
"string.regexp string.regexp.arbitrary-repitition"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#a5d6ff"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "string.regexp constant.character.escape",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#7ee787",
|
||||||
|
"fontStyle": "bold"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "support.constant",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#79c0ff"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "support.variable",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#79c0ff"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "support.type.property-name.json",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#7ee787"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "meta.module-reference",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#79c0ff"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "punctuation.definition.list.begin.markdown",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#ffa657"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": [
|
||||||
|
"markup.heading",
|
||||||
|
"markup.heading entity.name"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#79c0ff",
|
||||||
|
"fontStyle": "bold"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "markup.quote",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#7ee787"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "markup.italic",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#c9d1d9",
|
||||||
|
"fontStyle": "italic"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "markup.bold",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#c9d1d9",
|
||||||
|
"fontStyle": "bold"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": [
|
||||||
|
"markup.underline"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"fontStyle": "underline"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": [
|
||||||
|
"markup.strikethrough"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"fontStyle": "strikethrough"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "markup.inline.raw",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#79c0ff"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": [
|
||||||
|
"markup.deleted",
|
||||||
|
"meta.diff.header.from-file",
|
||||||
|
"punctuation.definition.deleted"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#ffa198"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": [
|
||||||
|
"punctuation.section.embedded"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#ff7b72"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": [
|
||||||
|
"markup.inserted",
|
||||||
|
"meta.diff.header.to-file",
|
||||||
|
"punctuation.definition.inserted"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#7ee787"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": [
|
||||||
|
"markup.changed",
|
||||||
|
"punctuation.definition.changed"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#ffa657"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": [
|
||||||
|
"markup.ignored",
|
||||||
|
"markup.untracked"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#0d1117"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "meta.diff.range",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#d2a8ff",
|
||||||
|
"fontStyle": "bold"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "meta.diff.header",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#79c0ff"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "meta.separator",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#79c0ff",
|
||||||
|
"fontStyle": "bold"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "meta.output",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#79c0ff"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": [
|
||||||
|
"brackethighlighter.tag",
|
||||||
|
"brackethighlighter.curly",
|
||||||
|
"brackethighlighter.round",
|
||||||
|
"brackethighlighter.square",
|
||||||
|
"brackethighlighter.angle",
|
||||||
|
"brackethighlighter.quote"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#8b949e"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "brackethighlighter.unmatched",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#ffa198"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": [
|
||||||
|
"constant.other.reference.link",
|
||||||
|
"string.other.link"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#a5d6ff"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "token.info-token",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#6796E6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "token.warn-token",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#CD9731"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "token.error-token",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#F44747"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "token.debug-token",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#B267E6"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"semanticHighlighting": true
|
||||||
|
}
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
{
|
||||||
|
"$schema": "vscode://schemas/color-theme",
|
||||||
|
"name": "Dark Modern",
|
||||||
|
"include": "./dark_plus.json",
|
||||||
|
"colors": {
|
||||||
|
"activityBar.activeBorder": "#0078D4",
|
||||||
|
"activityBar.background": "#181818",
|
||||||
|
"activityBar.border": "#2B2B2B",
|
||||||
|
"activityBar.foreground": "#D7D7D7",
|
||||||
|
"activityBar.inactiveForeground": "#868686",
|
||||||
|
"activityBarBadge.background": "#0078D4",
|
||||||
|
"activityBarBadge.foreground": "#FFFFFF",
|
||||||
|
"badge.background": "#616161",
|
||||||
|
"badge.foreground": "#F8F8F8",
|
||||||
|
"button.background": "#0078D4",
|
||||||
|
"button.border": "#ffffff1a",
|
||||||
|
"button.foreground": "#FFFFFF",
|
||||||
|
"button.hoverBackground": "#026EC1",
|
||||||
|
"button.secondaryBackground": "#00000000",
|
||||||
|
"button.secondaryForeground": "#CCCCCC",
|
||||||
|
"button.secondaryHoverBackground": "#2B2B2B",
|
||||||
|
"chat.slashCommandBackground": "#26477866",
|
||||||
|
"chat.slashCommandForeground": "#85B6FF",
|
||||||
|
"chat.editedFileForeground": "#E2C08D",
|
||||||
|
"checkbox.background": "#313131",
|
||||||
|
"checkbox.border": "#3C3C3C",
|
||||||
|
"debugToolBar.background": "#181818",
|
||||||
|
"descriptionForeground": "#9D9D9D",
|
||||||
|
"dropdown.background": "#313131",
|
||||||
|
"dropdown.border": "#3C3C3C",
|
||||||
|
"dropdown.foreground": "#CCCCCC",
|
||||||
|
"dropdown.listBackground": "#1F1F1F",
|
||||||
|
"editor.background": "#1F1F1F",
|
||||||
|
"editor.findMatchBackground": "#9E6A03",
|
||||||
|
"editor.foreground": "#CCCCCC",
|
||||||
|
"editorGroup.border": "#FFFFFF17",
|
||||||
|
"editorGroupHeader.tabsBackground": "#181818",
|
||||||
|
"editorGroupHeader.tabsBorder": "#2B2B2B",
|
||||||
|
"editorGutter.addedBackground": "#2EA043",
|
||||||
|
"editorGutter.deletedBackground": "#F85149",
|
||||||
|
"editorGutter.modifiedBackground": "#0078D4",
|
||||||
|
"editorLineNumber.activeForeground": "#CCCCCC",
|
||||||
|
"editorLineNumber.foreground": "#6E7681",
|
||||||
|
"editorOverviewRuler.border": "#010409",
|
||||||
|
"editorWidget.background": "#202020",
|
||||||
|
"errorForeground": "#F85149",
|
||||||
|
"focusBorder": "#0078D4",
|
||||||
|
"foreground": "#CCCCCC",
|
||||||
|
"icon.foreground": "#CCCCCC",
|
||||||
|
"input.background": "#313131",
|
||||||
|
"input.border": "#3C3C3C",
|
||||||
|
"input.foreground": "#CCCCCC",
|
||||||
|
"input.placeholderForeground": "#989898",
|
||||||
|
"inputOption.activeBackground": "#2489DB82",
|
||||||
|
"inputOption.activeBorder": "#2488DB",
|
||||||
|
"keybindingLabel.foreground": "#CCCCCC",
|
||||||
|
"menu.background": "#1F1F1F",
|
||||||
|
"menu.selectionBackground": "#0078d4",
|
||||||
|
"notificationCenterHeader.background": "#1F1F1F",
|
||||||
|
"notificationCenterHeader.foreground": "#CCCCCC",
|
||||||
|
"notifications.background": "#1F1F1F",
|
||||||
|
"notifications.border": "#2B2B2B",
|
||||||
|
"notifications.foreground": "#CCCCCC",
|
||||||
|
"panel.background": "#181818",
|
||||||
|
"panel.border": "#2B2B2B",
|
||||||
|
"panelInput.border": "#2B2B2B",
|
||||||
|
"panelTitle.activeBorder": "#0078D4",
|
||||||
|
"panelTitle.activeForeground": "#CCCCCC",
|
||||||
|
"panelTitle.inactiveForeground": "#9D9D9D",
|
||||||
|
"peekViewEditor.background": "#1F1F1F",
|
||||||
|
"peekViewEditor.matchHighlightBackground": "#BB800966",
|
||||||
|
"peekViewResult.background": "#1F1F1F",
|
||||||
|
"peekViewResult.matchHighlightBackground": "#BB800966",
|
||||||
|
"pickerGroup.border": "#3C3C3C",
|
||||||
|
"progressBar.background": "#0078D4",
|
||||||
|
"quickInput.background": "#222222",
|
||||||
|
"quickInput.foreground": "#CCCCCC",
|
||||||
|
"settings.dropdownBackground": "#313131",
|
||||||
|
"settings.dropdownBorder": "#3C3C3C",
|
||||||
|
"settings.headerForeground": "#FFFFFF",
|
||||||
|
"settings.modifiedItemIndicator": "#BB800966",
|
||||||
|
"sideBar.background": "#181818",
|
||||||
|
"sideBar.border": "#2B2B2B",
|
||||||
|
"sideBar.foreground": "#CCCCCC",
|
||||||
|
"sideBarSectionHeader.background": "#181818",
|
||||||
|
"sideBarSectionHeader.border": "#2B2B2B",
|
||||||
|
"sideBarSectionHeader.foreground": "#CCCCCC",
|
||||||
|
"sideBarTitle.foreground": "#CCCCCC",
|
||||||
|
"statusBar.background": "#181818",
|
||||||
|
"statusBar.inactiveBackground": "#1F1F1F",
|
||||||
|
"statusBar.border": "#2B2B2B",
|
||||||
|
"statusBarItem.hoverBackground": "#F1F1F133",
|
||||||
|
"statusBarItem.hoverForeground": "#FFFFFF",
|
||||||
|
"statusBar.debuggingBackground": "#0078D4",
|
||||||
|
"statusBar.debuggingForeground": "#FFFFFF",
|
||||||
|
"statusBar.focusBorder": "#0078D4",
|
||||||
|
"statusBar.foreground": "#CCCCCC",
|
||||||
|
"statusBar.noFolderBackground": "#1F1F1F",
|
||||||
|
"statusBarItem.focusBorder": "#0078D4",
|
||||||
|
"statusBarItem.prominentBackground": "#6E768166",
|
||||||
|
"statusBarItem.remoteBackground": "#0078D4",
|
||||||
|
"statusBarItem.remoteForeground": "#FFFFFF",
|
||||||
|
"tab.activeBackground": "#1F1F1F",
|
||||||
|
"tab.activeBorder": "#1F1F1F",
|
||||||
|
"tab.activeBorderTop": "#0078D4",
|
||||||
|
"tab.activeForeground": "#FFFFFF",
|
||||||
|
"tab.selectedBorderTop": "#6caddf",
|
||||||
|
"tab.border": "#2B2B2B",
|
||||||
|
"tab.hoverBackground": "#1F1F1F",
|
||||||
|
"tab.inactiveBackground": "#181818",
|
||||||
|
"tab.inactiveForeground": "#9D9D9D",
|
||||||
|
"tab.unfocusedActiveBorder": "#1F1F1F",
|
||||||
|
"tab.unfocusedActiveBorderTop": "#2B2B2B",
|
||||||
|
"tab.unfocusedHoverBackground": "#1F1F1F",
|
||||||
|
"terminal.foreground": "#CCCCCC",
|
||||||
|
"terminal.tab.activeBorder": "#0078D4",
|
||||||
|
"textBlockQuote.background": "#2B2B2B",
|
||||||
|
"textBlockQuote.border": "#616161",
|
||||||
|
"textCodeBlock.background": "#2B2B2B",
|
||||||
|
"textLink.activeForeground": "#4daafc",
|
||||||
|
"textLink.foreground": "#4daafc",
|
||||||
|
"textPreformat.foreground": "#D0D0D0",
|
||||||
|
"textPreformat.background": "#3C3C3C",
|
||||||
|
"textSeparator.foreground": "#21262D",
|
||||||
|
"titleBar.activeBackground": "#181818",
|
||||||
|
"titleBar.activeForeground": "#CCCCCC",
|
||||||
|
"titleBar.border": "#2B2B2B",
|
||||||
|
"titleBar.inactiveBackground": "#1F1F1F",
|
||||||
|
"titleBar.inactiveForeground": "#9D9D9D",
|
||||||
|
"welcomePage.tileBackground": "#2B2B2B",
|
||||||
|
"welcomePage.progress.foreground": "#0078D4",
|
||||||
|
"widget.border": "#313131",
|
||||||
|
"modernActivityBarItem.activeBackground": "#FFFFFF22",
|
||||||
|
"modernActivityBarItem.hoverBackground": "#FFFFFF11",
|
||||||
|
"modernActivityBar.border": "#252526"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,205 @@
|
|||||||
|
{
|
||||||
|
"$schema": "vscode://schemas/color-theme",
|
||||||
|
"name": "Dark+",
|
||||||
|
"include": "./dark_vs.json",
|
||||||
|
"tokenColors": [
|
||||||
|
{
|
||||||
|
"name": "Function declarations",
|
||||||
|
"scope": [
|
||||||
|
"entity.name.function",
|
||||||
|
"support.function",
|
||||||
|
"support.constant.handlebars",
|
||||||
|
"source.powershell variable.other.member",
|
||||||
|
"entity.name.operator.custom-literal"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#DCDCAA"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Types declaration and references",
|
||||||
|
"scope": [
|
||||||
|
"support.class",
|
||||||
|
"support.type",
|
||||||
|
"entity.name.type",
|
||||||
|
"entity.name.namespace",
|
||||||
|
"entity.other.attribute",
|
||||||
|
"entity.name.scope-resolution",
|
||||||
|
"entity.name.class",
|
||||||
|
"storage.type.numeric.go",
|
||||||
|
"storage.type.byte.go",
|
||||||
|
"storage.type.boolean.go",
|
||||||
|
"storage.type.string.go",
|
||||||
|
"storage.type.uintptr.go",
|
||||||
|
"storage.type.error.go",
|
||||||
|
"storage.type.rune.go",
|
||||||
|
"storage.type.cs",
|
||||||
|
"storage.type.generic.cs",
|
||||||
|
"storage.type.modifier.cs",
|
||||||
|
"storage.type.variable.cs",
|
||||||
|
"storage.type.annotation.java",
|
||||||
|
"storage.type.generic.java",
|
||||||
|
"storage.type.java",
|
||||||
|
"storage.type.object.array.java",
|
||||||
|
"storage.type.primitive.array.java",
|
||||||
|
"storage.type.primitive.java",
|
||||||
|
"storage.type.token.java",
|
||||||
|
"storage.type.groovy",
|
||||||
|
"storage.type.annotation.groovy",
|
||||||
|
"storage.type.parameters.groovy",
|
||||||
|
"storage.type.generic.groovy",
|
||||||
|
"storage.type.object.array.groovy",
|
||||||
|
"storage.type.primitive.array.groovy",
|
||||||
|
"storage.type.primitive.groovy"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#4EC9B0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Types declaration and references, TS grammar specific",
|
||||||
|
"scope": [
|
||||||
|
"meta.type.cast.expr",
|
||||||
|
"meta.type.new.expr",
|
||||||
|
"support.constant.math",
|
||||||
|
"support.constant.dom",
|
||||||
|
"support.constant.json",
|
||||||
|
"entity.other.inherited-class",
|
||||||
|
"punctuation.separator.namespace.ruby"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#4EC9B0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Control flow / Special keywords",
|
||||||
|
"scope": [
|
||||||
|
"keyword.control",
|
||||||
|
"source.cpp keyword.operator.new",
|
||||||
|
"keyword.operator.delete",
|
||||||
|
"keyword.other.using",
|
||||||
|
"keyword.other.directive.using",
|
||||||
|
"keyword.other.operator",
|
||||||
|
"entity.name.operator"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#C586C0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Variable and parameter name",
|
||||||
|
"scope": [
|
||||||
|
"variable",
|
||||||
|
"meta.definition.variable.name",
|
||||||
|
"support.variable",
|
||||||
|
"entity.name.variable",
|
||||||
|
"constant.other.placeholder"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#9CDCFE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Constants and enums",
|
||||||
|
"scope": [
|
||||||
|
"variable.other.constant",
|
||||||
|
"variable.other.enummember"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#4FC1FF"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Object keys, TS grammar specific",
|
||||||
|
"scope": [
|
||||||
|
"meta.object-literal.key"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#9CDCFE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "CSS property value",
|
||||||
|
"scope": [
|
||||||
|
"support.constant.property-value",
|
||||||
|
"support.constant.font-name",
|
||||||
|
"support.constant.media-type",
|
||||||
|
"support.constant.media",
|
||||||
|
"constant.other.color.rgb-value",
|
||||||
|
"constant.other.rgb-value",
|
||||||
|
"support.constant.color"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#CE9178"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Regular expression groups",
|
||||||
|
"scope": [
|
||||||
|
"punctuation.definition.group.regexp",
|
||||||
|
"punctuation.definition.group.assertion.regexp",
|
||||||
|
"punctuation.definition.character-class.regexp",
|
||||||
|
"punctuation.character.set.begin.regexp",
|
||||||
|
"punctuation.character.set.end.regexp",
|
||||||
|
"keyword.operator.negation.regexp",
|
||||||
|
"support.other.parenthesis.regexp"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#CE9178"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": [
|
||||||
|
"constant.character.character-class.regexp",
|
||||||
|
"constant.other.character-class.set.regexp",
|
||||||
|
"constant.other.character-class.regexp",
|
||||||
|
"constant.character.set.regexp"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#d16969"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": [
|
||||||
|
"keyword.operator.or.regexp",
|
||||||
|
"keyword.control.anchor.regexp"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#DCDCAA"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "keyword.operator.quantifier.regexp",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#d7ba7d"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": [
|
||||||
|
"constant.character",
|
||||||
|
"constant.other.option"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#569cd6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "constant.character.escape",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#d7ba7d"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "entity.name.label",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#C8C8C8"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"semanticTokenColors": {
|
||||||
|
"newOperator": "#C586C0",
|
||||||
|
"stringLiteral": "#ce9178",
|
||||||
|
"customLiteral": "#DCDCAA",
|
||||||
|
"numberLiteral": "#b5cea8"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,423 @@
|
|||||||
|
{
|
||||||
|
"$schema": "vscode://schemas/color-theme",
|
||||||
|
"name": "Dark (Visual Studio)",
|
||||||
|
"colors": {
|
||||||
|
"checkbox.border": "#6B6B6B",
|
||||||
|
"editor.background": "#1E1E1E",
|
||||||
|
"editor.foreground": "#D4D4D4",
|
||||||
|
"editor.inactiveSelectionBackground": "#3A3D41",
|
||||||
|
"editorIndentGuide.background1": "#404040",
|
||||||
|
"editorIndentGuide.activeBackground1": "#707070",
|
||||||
|
"editor.selectionHighlightBackground": "#ADD6FF26",
|
||||||
|
"list.dropBackground": "#383B3D",
|
||||||
|
"activityBarBadge.background": "#007ACC",
|
||||||
|
"sideBarTitle.foreground": "#BBBBBB",
|
||||||
|
"input.placeholderForeground": "#A6A6A6",
|
||||||
|
"menu.background": "#252526",
|
||||||
|
"menu.foreground": "#CCCCCC",
|
||||||
|
"menu.separatorBackground": "#454545",
|
||||||
|
"menu.border": "#454545",
|
||||||
|
"menu.selectionBackground": "#0078d4",
|
||||||
|
"statusBarItem.remoteForeground": "#FFF",
|
||||||
|
"statusBarItem.remoteBackground": "#16825D",
|
||||||
|
"statusBar.inactiveBackground": "#1476B8",
|
||||||
|
"titleBar.inactiveBackground": "#323233",
|
||||||
|
"ports.iconRunningProcessForeground": "#369432",
|
||||||
|
"sideBarSectionHeader.background": "#0000",
|
||||||
|
"sideBarSectionHeader.border": "#ccc3",
|
||||||
|
"tab.selectedBackground": "#37373D",
|
||||||
|
"tab.selectedForeground": "#FFFFFF",
|
||||||
|
"tab.lastPinnedBorder": "#ccc3",
|
||||||
|
"list.activeSelectionIconForeground": "#FFF",
|
||||||
|
"terminal.inactiveSelectionBackground": "#3A3D41",
|
||||||
|
"widget.border": "#303031",
|
||||||
|
"actionBar.toggledBackground": "#383a49",
|
||||||
|
"agentsPanel.border": "#303031",
|
||||||
|
"agentsCard.border": "#00000000",
|
||||||
|
"agentsChatInput.border": "#303031",
|
||||||
|
"agentsChatInput.focusBorder": "#007ACC",
|
||||||
|
"agentsNewSessionButton.border": "#303031",
|
||||||
|
"surface.border": "#252526",
|
||||||
|
"modernActivityBarItem.activeBackground": "#1E1E1E",
|
||||||
|
"modernActivityBarItem.hoverBackground": "#1E1E1E66",
|
||||||
|
"modernActivityBar.border": "#252526"
|
||||||
|
},
|
||||||
|
"tokenColors": [
|
||||||
|
{
|
||||||
|
"scope": [
|
||||||
|
"meta.embedded",
|
||||||
|
"source.groovy.embedded",
|
||||||
|
"string meta.image.inline.markdown",
|
||||||
|
"variable.legacy.builtin.python"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#D4D4D4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "emphasis",
|
||||||
|
"settings": {
|
||||||
|
"fontStyle": "italic"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "strong",
|
||||||
|
"settings": {
|
||||||
|
"fontStyle": "bold"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "header",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#000080"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "comment",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#6A9955"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "constant.language",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#569cd6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": [
|
||||||
|
"constant.numeric",
|
||||||
|
"variable.other.enummember",
|
||||||
|
"keyword.operator.plus.exponent",
|
||||||
|
"keyword.operator.minus.exponent"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#b5cea8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "constant.regexp",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#646695"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "entity.name.tag",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#569cd6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": [
|
||||||
|
"entity.name.tag.css",
|
||||||
|
"entity.name.tag.less"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#d7ba7d"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "entity.other.attribute-name",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#9cdcfe"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": [
|
||||||
|
"entity.other.attribute-name.class.css",
|
||||||
|
"source.css entity.other.attribute-name.class",
|
||||||
|
"entity.other.attribute-name.id.css",
|
||||||
|
"entity.other.attribute-name.parent-selector.css",
|
||||||
|
"entity.other.attribute-name.parent.less",
|
||||||
|
"source.css entity.other.attribute-name.pseudo-class",
|
||||||
|
"entity.other.attribute-name.pseudo-element.css",
|
||||||
|
"source.css.less entity.other.attribute-name.id",
|
||||||
|
"entity.other.attribute-name.scss"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#d7ba7d"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "invalid",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#f44747"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "markup.underline",
|
||||||
|
"settings": {
|
||||||
|
"fontStyle": "underline"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "markup.bold",
|
||||||
|
"settings": {
|
||||||
|
"fontStyle": "bold",
|
||||||
|
"foreground": "#569cd6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "markup.heading",
|
||||||
|
"settings": {
|
||||||
|
"fontStyle": "bold",
|
||||||
|
"foreground": "#569cd6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "markup.italic",
|
||||||
|
"settings": {
|
||||||
|
"fontStyle": "italic",
|
||||||
|
"foreground": "#C586C0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "markup.strikethrough",
|
||||||
|
"settings": {
|
||||||
|
"fontStyle": "strikethrough"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "markup.inserted",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#b5cea8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "markup.deleted",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#ce9178"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "markup.changed",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#569cd6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "punctuation.definition.quote.begin.markdown",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#6A9955"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "punctuation.definition.list.begin.markdown",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#6796e6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "markup.inline.raw",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#ce9178"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "brackets of XML/HTML tags",
|
||||||
|
"scope": "punctuation.definition.tag",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#808080"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": [
|
||||||
|
"meta.preprocessor",
|
||||||
|
"entity.name.function.preprocessor"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#569cd6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "meta.preprocessor.string",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#ce9178"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "meta.preprocessor.numeric",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#b5cea8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "meta.structure.dictionary.key.python",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#9cdcfe"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "meta.diff.header",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#569cd6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "storage",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#569cd6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "storage.type",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#569cd6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": [
|
||||||
|
"storage.modifier",
|
||||||
|
"keyword.operator.noexcept"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#569cd6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": [
|
||||||
|
"string",
|
||||||
|
"meta.embedded.assembly"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#ce9178"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "string.tag",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#ce9178"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "string.value",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#ce9178"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "string.regexp",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#d16969"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "String interpolation",
|
||||||
|
"scope": [
|
||||||
|
"punctuation.definition.template-expression.begin",
|
||||||
|
"punctuation.definition.template-expression.end",
|
||||||
|
"punctuation.section.embedded"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#569cd6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Reset JavaScript string interpolation expression",
|
||||||
|
"scope": [
|
||||||
|
"meta.template.expression"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#d4d4d4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": [
|
||||||
|
"support.type.vendored.property-name",
|
||||||
|
"support.type.property-name",
|
||||||
|
"source.css variable",
|
||||||
|
"source.coffee.embedded"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#9cdcfe"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "keyword",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#569cd6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "keyword.control",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#569cd6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "keyword.operator",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#d4d4d4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": [
|
||||||
|
"keyword.operator.new",
|
||||||
|
"keyword.operator.expression",
|
||||||
|
"keyword.operator.cast",
|
||||||
|
"keyword.operator.sizeof",
|
||||||
|
"keyword.operator.alignof",
|
||||||
|
"keyword.operator.typeid",
|
||||||
|
"keyword.operator.alignas",
|
||||||
|
"keyword.operator.instanceof",
|
||||||
|
"keyword.operator.logical.python",
|
||||||
|
"keyword.operator.wordlike"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#569cd6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "keyword.other.unit",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#b5cea8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": [
|
||||||
|
"punctuation.section.embedded.begin.php",
|
||||||
|
"punctuation.section.embedded.end.php"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#569cd6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "support.function.git-rebase",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#9cdcfe"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scope": "constant.sha.git-rebase",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#b5cea8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "coloring of the Java import and package identifiers",
|
||||||
|
"scope": [
|
||||||
|
"storage.modifier.import.java",
|
||||||
|
"variable.language.wildcard.java",
|
||||||
|
"storage.modifier.package.java"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#d4d4d4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "this.self",
|
||||||
|
"scope": "variable.language",
|
||||||
|
"settings": {
|
||||||
|
"foreground": "#569cd6"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"semanticHighlighting": true,
|
||||||
|
"semanticTokenColors": {
|
||||||
|
"newOperator": "#d4d4d4",
|
||||||
|
"stringLiteral": "#ce9178",
|
||||||
|
"customLiteral": "#D4D4D4",
|
||||||
|
"numberLiteral": "#b5cea8"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"name": "darwin-breeze",
|
||||||
|
"displayName": "Darwin Breeze",
|
||||||
|
"description": "Generated by kde/theme/build.py from DarwinBreezeDark.colors",
|
||||||
|
"publisher": "trivk",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"engines": {
|
||||||
|
"vscode": "^1.70.0"
|
||||||
|
},
|
||||||
|
"categories": [
|
||||||
|
"Themes"
|
||||||
|
],
|
||||||
|
"contributes": {
|
||||||
|
"themes": [
|
||||||
|
{
|
||||||
|
"label": "Darwin Breeze Dark",
|
||||||
|
"uiTheme": "vs-dark",
|
||||||
|
"path": "./themes/DarwinBreezeDark-color-theme.json"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<svg height="32" viewBox="0 0 32 32" width="32" xmlns="http://www.w3.org/2000/svg"><g transform="matrix(0.78 0 0 0.78 3.52 3.52)"><g transform="matrix(.99917103 0 0 .9988667 .023961 .026876)"><path d="m29.946 15.942c.354 9.205-9.874 16.514-18.469 13.197-8.505-2.569-12.285-13.93-7.003-21.077 4.9-7.801 17.469-8.068 22.695-.48a13.97 13.97 0 0 1 2.777 8.36z" fill="none" opacity=".95" stroke="#f5f5f5" stroke-width="2.093"/><path d="m12.758 26.311v-5.725c-.282.433-.679.792-1.19 1.079a3.216 3.216 0 0 1 -1.613.43c-1.27 0-2.366-.555-3.287-1.663-.914-1.109-1.371-2.628-1.371-4.559 0-1.174.185-2.227.555-3.16.376-.932.917-1.636 1.623-2.114a4.074 4.074 0 0 1 2.34-.726c1.323 0 2.365.609 3.125 1.827v-1.563h1.633v16.174zm-5.596-10.36c0 1.504.29 2.635.867 3.39.579.75 1.27 1.124 2.078 1.124.773 0 1.438-.356 1.996-1.068.558-.72.837-1.81.837-3.27 0-1.557-.296-2.727-.887-3.513-.585-.785-1.274-1.178-2.067-1.178-.787 0-1.456.367-2.007 1.101-.544.727-.817 1.865-.817 3.413m11.938 5.88h-1.683v-16.141h1.815v5.758c.766-1.05 1.744-1.574 2.934-1.574.658 0 1.28.147 1.865.44a3.768 3.768 0 0 1 1.452 1.222c.383.521.682 1.153.897 1.894s.323 1.534.323 2.378c0 2.004-.454 3.553-1.361 4.647-.908 1.093-1.997 1.64-3.267 1.64-1.264 0-2.255-.576-2.974-1.728v1.464m-.02-5.935c0 1.402.174 2.415.524 3.04.571 1.02 1.344 1.53 2.319 1.53.793 0 1.479-.375 2.057-1.123.578-.756.867-1.88.867-3.37 0-1.526-.28-2.653-.837-3.38-.551-.726-1.22-1.09-2.007-1.09-.793 0-1.478.378-2.057 1.134-.578.75-.867 1.835-.867 3.26" fill="#fafafa"/></g></g></svg>
|
||||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Patch netbird-ui's tray icons to Breeze proportions.
|
||||||
|
# Runs as root; the pacman hook re-runs it after every netbird-ui install/upgrade.
|
||||||
|
set -euo pipefail
|
||||||
|
here=$(cd "$(dirname "$0")" && pwd)
|
||||||
|
ROOT=${ROOT:-} # for dry-run testing only
|
||||||
|
bin=$ROOT/usr/bin/netbird-ui
|
||||||
|
[[ -f $bin ]] || exit 0
|
||||||
|
|
||||||
|
# Still the file the package installed: keep it as the original for restore.sh
|
||||||
|
sum=$(zcat "$ROOT"/var/lib/pacman/local/netbird-ui*/mtree 2>/dev/null \
|
||||||
|
| grep -F './usr/bin/netbird-ui ' | grep -o 'sha256digest=[0-9a-f]*' | cut -d= -f2 || true)
|
||||||
|
if [[ -n $sum && $(sha256sum <"$bin" | cut -d' ' -f1) == "$sum" ]]; then
|
||||||
|
install -Dm755 "$bin" "$here/orig/netbird-ui"
|
||||||
|
fi
|
||||||
|
python3 -I "$here/patch.py" "$bin"
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Install the netbird-ui tray icon patch and its pacman hook. Usage: sudo ./install.sh
|
||||||
|
set -euo pipefail
|
||||||
|
here=$(cd "$(dirname "$0")" && pwd)
|
||||||
|
ROOT=${ROOT:-} # for dry-run testing only
|
||||||
|
[[ $EUID -eq 0 || -n $ROOT ]] || { echo "Must be run with sudo"; exit 1; }
|
||||||
|
dest=$ROOT/usr/local/share/netbird-breeze-icons
|
||||||
|
|
||||||
|
install -Dm755 "$here/patch.py" "$dest/patch.py"
|
||||||
|
install -m755 "$here/apply.sh" "$dest/apply.sh"
|
||||||
|
install -Dm644 "$here/netbird-breeze-icons.hook" "$ROOT/etc/pacman.d/hooks/netbird-breeze-icons.hook"
|
||||||
|
ROOT=$ROOT "$dest/apply.sh"
|
||||||
|
|
||||||
|
echo "Done. Restart the NetBird UI (without sudo):"
|
||||||
|
echo " pkill -x netbird-ui; setsid -f netbird-ui --daemon-addr unix:///var/run/netbird/main.sock >/dev/null 2>&1"
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
[Trigger]
|
||||||
|
Operation = Install
|
||||||
|
Operation = Upgrade
|
||||||
|
Type = Package
|
||||||
|
Target = netbird-ui
|
||||||
|
Target = netbird-ui-bin
|
||||||
|
|
||||||
|
[Action]
|
||||||
|
Description = Patching NetBird tray icons to match Breeze...
|
||||||
|
When = PostTransaction
|
||||||
|
Exec = /usr/local/share/netbird-breeze-icons/apply.sh
|
||||||
@@ -0,0 +1,183 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Shrink and recolor the tray icons embedded in the netbird-ui binary.
|
||||||
|
|
||||||
|
NetBird sends its tray icon as a pixmap, so an icon theme can't replace it.
|
||||||
|
This rewrites the 48x48 monochrome PNGs inside the binary in place: the
|
||||||
|
glyph is scaled to SCALE so it gets the padding of a Breeze status icon,
|
||||||
|
and the white variants take the panel's text color. Each new PNG must fit
|
||||||
|
in the bytes of the old one; the rest is zero-filled, which Go's PNG
|
||||||
|
decoder never reads because it stops at IEND.
|
||||||
|
|
||||||
|
Usage: patch.py BINARY [--check]
|
||||||
|
"""
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
import struct
|
||||||
|
import sys
|
||||||
|
import tempfile
|
||||||
|
import zlib
|
||||||
|
|
||||||
|
SIZE = 48
|
||||||
|
SCALE = 0.8
|
||||||
|
# DarwinBreezeDark ForegroundNormal, as the other tray icons are drawn
|
||||||
|
LIGHT = (222, 222, 222)
|
||||||
|
# A glyph narrower than this already has padding (already patched)
|
||||||
|
MAX_PADDED_WIDTH = round(SIZE * 0.9)
|
||||||
|
SIG = b"\x89PNG\r\n\x1a\n"
|
||||||
|
|
||||||
|
Pixels = list[list[float]] # rows of premultiplied RGBA floats
|
||||||
|
|
||||||
|
|
||||||
|
def decode(png: bytes) -> tuple[int, int, bytes] | None:
|
||||||
|
"""Return (width, height, RGBA rows) for an 8-bit RGBA PNG, else None."""
|
||||||
|
pos, idat, ihdr = 8, b"", b""
|
||||||
|
while pos < len(png):
|
||||||
|
(length,) = struct.unpack(">I", png[pos:pos + 4])
|
||||||
|
kind, body = png[pos + 4:pos + 8], png[pos + 8:pos + 8 + length]
|
||||||
|
if kind == b"IHDR":
|
||||||
|
ihdr = body
|
||||||
|
elif kind == b"IDAT":
|
||||||
|
idat += body
|
||||||
|
elif kind == b"IEND":
|
||||||
|
break
|
||||||
|
pos += 12 + length
|
||||||
|
w, h, depth, color, _, _, interlace = struct.unpack(">IIBBBBB", ihdr)
|
||||||
|
if (depth, color, interlace) != (8, 6, 0):
|
||||||
|
return None
|
||||||
|
raw, stride, out = zlib.decompress(idat), w * 4, bytearray()
|
||||||
|
prev = bytearray(stride)
|
||||||
|
for y in range(h):
|
||||||
|
ftype = raw[y * (stride + 1)]
|
||||||
|
line = bytearray(raw[y * (stride + 1) + 1:(y + 1) * (stride + 1)])
|
||||||
|
for i in range(stride):
|
||||||
|
a = line[i - 4] if i >= 4 else 0
|
||||||
|
b = prev[i]
|
||||||
|
c = prev[i - 4] if i >= 4 else 0
|
||||||
|
if ftype == 1:
|
||||||
|
line[i] = (line[i] + a) & 0xFF
|
||||||
|
elif ftype == 2:
|
||||||
|
line[i] = (line[i] + b) & 0xFF
|
||||||
|
elif ftype == 3:
|
||||||
|
line[i] = (line[i] + (a + b) // 2) & 0xFF
|
||||||
|
elif ftype == 4:
|
||||||
|
p = a + b - c
|
||||||
|
pa, pb, pc = abs(p - a), abs(p - b), abs(p - c)
|
||||||
|
pred = a if pa <= pb and pa <= pc else b if pb <= pc else c
|
||||||
|
line[i] = (line[i] + pred) & 0xFF
|
||||||
|
out += line
|
||||||
|
prev = line
|
||||||
|
return w, h, bytes(out)
|
||||||
|
|
||||||
|
|
||||||
|
def encode(w: int, h: int, rgba: bytes) -> bytes:
|
||||||
|
def chunk(kind: bytes, body: bytes) -> bytes:
|
||||||
|
crc = zlib.crc32(kind + body)
|
||||||
|
return struct.pack(">I", len(body)) + kind + body + struct.pack(">I", crc)
|
||||||
|
|
||||||
|
raw = b"".join(b"\0" + rgba[y * w * 4:(y + 1) * w * 4] for y in range(h))
|
||||||
|
return (SIG + chunk(b"IHDR", struct.pack(">IIBBBBB", w, h, 8, 6, 0, 0, 0))
|
||||||
|
+ chunk(b"IDAT", zlib.compress(raw, 9)) + chunk(b"IEND", b""))
|
||||||
|
|
||||||
|
|
||||||
|
def glyph_width(rgba: bytes) -> int:
|
||||||
|
xs = [i // 4 % SIZE for i in range(3, len(rgba), 4) if rgba[i] > 16]
|
||||||
|
return max(xs) - min(xs) + 1 if xs else 0
|
||||||
|
|
||||||
|
|
||||||
|
def is_light(rgba: bytes) -> bool | None:
|
||||||
|
"""True for a white glyph, False for black, None if not monochrome."""
|
||||||
|
lum = [rgba[i - 3] for i in range(3, len(rgba), 4) if rgba[i] > 200]
|
||||||
|
if not lum or any(abs(rgba[i - 3] - rgba[i - 2]) > 8 for i in range(3, len(rgba), 4)
|
||||||
|
if rgba[i] > 200):
|
||||||
|
return None
|
||||||
|
if all(v > 230 for v in lum):
|
||||||
|
return True
|
||||||
|
if all(v < 25 for v in lum):
|
||||||
|
return False
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def shrink(rgba: bytes, light: bool) -> bytes:
|
||||||
|
"""Box-filter the image to SCALE, centered on a SIZE canvas."""
|
||||||
|
src: Pixels = []
|
||||||
|
for y in range(SIZE):
|
||||||
|
row: list[float] = []
|
||||||
|
for x in range(SIZE):
|
||||||
|
r, g, b, a = rgba[(y * SIZE + x) * 4:(y * SIZE + x) * 4 + 4]
|
||||||
|
row += [r * a, g * a, b * a, a]
|
||||||
|
src.append(row)
|
||||||
|
inner = SIZE * SCALE
|
||||||
|
off = (SIZE - inner) / 2
|
||||||
|
step = 1 / SCALE
|
||||||
|
out = bytearray(SIZE * SIZE * 4)
|
||||||
|
|
||||||
|
def spans(o: int) -> list[tuple[int, float]]:
|
||||||
|
lo = (o - off) * step
|
||||||
|
hi = lo + step
|
||||||
|
res = []
|
||||||
|
for s in range(max(0, int(lo)), min(SIZE, int(hi) + 1)):
|
||||||
|
cover = min(hi, s + 1) - max(lo, s)
|
||||||
|
if cover > 0:
|
||||||
|
res.append((s, cover))
|
||||||
|
return res
|
||||||
|
|
||||||
|
for oy in range(SIZE):
|
||||||
|
ys = spans(oy)
|
||||||
|
for ox in range(SIZE):
|
||||||
|
acc = [0.0] * 4
|
||||||
|
for sy, wy in ys:
|
||||||
|
for sx, wx in spans(ox):
|
||||||
|
k = wy * wx
|
||||||
|
for c in range(4):
|
||||||
|
acc[c] += src[sy][sx * 4 + c] * k
|
||||||
|
area = step * step
|
||||||
|
a = acc[3] / area
|
||||||
|
if a < 0.5:
|
||||||
|
continue
|
||||||
|
color = LIGHT if light else tuple(round(acc[c] / acc[3]) for c in range(3))
|
||||||
|
out[(oy * SIZE + ox) * 4:(oy * SIZE + ox) * 4 + 4] = bytes(
|
||||||
|
[*color, min(255, round(a))])
|
||||||
|
return bytes(out)
|
||||||
|
|
||||||
|
|
||||||
|
def patch(data: bytearray) -> int:
|
||||||
|
count, pos = 0, 0
|
||||||
|
while (pos := data.find(SIG, pos)) >= 0:
|
||||||
|
end = data.find(b"IEND", pos) + 8
|
||||||
|
old = bytes(data[pos:end])
|
||||||
|
img = decode(old) if old[16:24] == struct.pack(">II", SIZE, SIZE) else None
|
||||||
|
if img is not None:
|
||||||
|
light = is_light(img[2])
|
||||||
|
if light is not None and glyph_width(img[2]) > MAX_PADDED_WIDTH:
|
||||||
|
new = encode(SIZE, SIZE, shrink(img[2], light))
|
||||||
|
if len(new) > len(old):
|
||||||
|
sys.exit(f"Patched icon at {pos} is larger than the original")
|
||||||
|
data[pos:end] = new + bytes(len(old) - len(new))
|
||||||
|
count += 1
|
||||||
|
pos = end
|
||||||
|
return count
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
||||||
|
parser.add_argument("binary", type=Path)
|
||||||
|
parser.add_argument("--check", action="store_true",
|
||||||
|
help="only print how many icons would be patched")
|
||||||
|
args = parser.parse_args()
|
||||||
|
data = bytearray(args.binary.read_bytes())
|
||||||
|
count = patch(data)
|
||||||
|
print(f"{args.binary}: {count} tray icons {'to patch' if args.check else 'patched'}")
|
||||||
|
if args.check or not count:
|
||||||
|
return
|
||||||
|
mode = args.binary.stat().st_mode
|
||||||
|
fd, tmp = tempfile.mkstemp(dir=args.binary.parent, prefix=".netbird-ui.")
|
||||||
|
with os.fdopen(fd, "wb") as f:
|
||||||
|
f.write(data)
|
||||||
|
os.chmod(tmp, mode & 0o7777)
|
||||||
|
os.replace(tmp, args.binary)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Put the original netbird-ui back and remove the hook. Usage: sudo ./restore.sh
|
||||||
|
set -euo pipefail
|
||||||
|
ROOT=${ROOT:-} # for dry-run testing only
|
||||||
|
[[ $EUID -eq 0 || -n $ROOT ]] || { echo "Must be run with sudo"; exit 1; }
|
||||||
|
dest=$ROOT/usr/local/share/netbird-breeze-icons
|
||||||
|
[[ -f $dest/orig/netbird-ui ]] || { echo "No original binary in $dest/orig"; exit 1; }
|
||||||
|
install -m755 "$dest/orig/netbird-ui" "$ROOT/usr/bin/netbird-ui"
|
||||||
|
rm -f "$ROOT/etc/pacman.d/hooks/netbird-breeze-icons.hook"
|
||||||
|
rm -rf "$dest"
|
||||||
|
echo "Restored. Restart the NetBird UI (without sudo):"
|
||||||
|
echo " pkill -x netbird-ui; setsid -f netbird-ui --daemon-addr unix:///var/run/netbird/main.sock >/dev/null 2>&1"
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Copy the Breeze-style icons over Ngó Sen's monochrome tray icons.
|
||||||
|
# Runs as root; the pacman hook re-runs it after every fcitx5-ngosen install/upgrade.
|
||||||
|
set -euo pipefail
|
||||||
|
here=$(cd "$(dirname "$0")" && pwd)
|
||||||
|
ROOT=${ROOT:-} # for dry-run testing only
|
||||||
|
|
||||||
|
# Ngó Sen points at hicolor, but Plasma looks the icon up by name in breeze/breeze-dark
|
||||||
|
dirs=(usr/share/icons/hicolor/scalable/{apps,status}
|
||||||
|
usr/share/icons/breeze{,-dark}/status/{22,24})
|
||||||
|
mtree=$(zcat "$ROOT"/var/lib/pacman/local/fcitx5-ngosen-*/mtree 2>/dev/null || true)
|
||||||
|
|
||||||
|
for d in "${dirs[@]}"; do
|
||||||
|
for f in "$here"/icons/*.svg; do
|
||||||
|
n=$(basename "$f"); t=$ROOT/$d/$n
|
||||||
|
[[ -f $t ]] || continue
|
||||||
|
# Still the file the package installed: keep it as the original for restore.sh
|
||||||
|
sum=$(grep -F "./$d/$n " <<<"$mtree" | grep -o 'sha256digest=[0-9a-f]*' | cut -d= -f2 || true)
|
||||||
|
if [[ -n $sum && $(sha256sum <"$t" | cut -d' ' -f1) == "$sum" ]]; then
|
||||||
|
install -Dm644 "$t" "$here/orig/$d/$n"
|
||||||
|
fi
|
||||||
|
install -m644 "$f" "$t"
|
||||||
|
done
|
||||||
|
done
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22" width="22" height="22">
|
||||||
|
<style id="current-color-scheme" type="text/css">.ColorScheme-Text { color: #232629; }</style>
|
||||||
|
<g class="ColorScheme-Text" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.3">
|
||||||
|
<rect x="3.5" y="3.5" width="15" height="15" rx="2.5" stroke-width="1"/><path d="M8.3 7.5 11 14.5l2.7-7"/>
|
||||||
|
</g></svg>
|
||||||
|
After Width: | Height: | Size: 426 B |
@@ -0,0 +1,5 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22" width="22" height="22">
|
||||||
|
<style id="current-color-scheme" type="text/css">.ColorScheme-Text { color: #fcfcfc; }</style>
|
||||||
|
<g class="ColorScheme-Text" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.3">
|
||||||
|
<rect x="3.5" y="3.5" width="15" height="15" rx="2.5" stroke-width="1"/><path d="M8.3 7.5 11 14.5l2.7-7"/>
|
||||||
|
</g></svg>
|
||||||
|
After Width: | Height: | Size: 426 B |
@@ -0,0 +1,5 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22" width="22" height="22">
|
||||||
|
<style id="current-color-scheme" type="text/css">.ColorScheme-Text { color: #232629; }</style>
|
||||||
|
<g class="ColorScheme-Text" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1">
|
||||||
|
<circle cx="11" cy="11" r="7.5"/><path d="M7.8 12.6q3.2 3.2 6.4 0"/><path d="M8.6 8.6v.6M13.4 8.6v.6" stroke-width="1.6"/>
|
||||||
|
</g></svg>
|
||||||
|
After Width: | Height: | Size: 440 B |
@@ -0,0 +1,5 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22" width="22" height="22">
|
||||||
|
<style id="current-color-scheme" type="text/css">.ColorScheme-Text { color: #fcfcfc; }</style>
|
||||||
|
<g class="ColorScheme-Text" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1">
|
||||||
|
<circle cx="11" cy="11" r="7.5"/><path d="M7.8 12.6q3.2 3.2 6.4 0"/><path d="M8.6 8.6v.6M13.4 8.6v.6" stroke-width="1.6"/>
|
||||||
|
</g></svg>
|
||||||
|
After Width: | Height: | Size: 440 B |
@@ -0,0 +1,5 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22" width="22" height="22">
|
||||||
|
<style id="current-color-scheme" type="text/css">.ColorScheme-Text { color: #232629; }</style>
|
||||||
|
<g class="ColorScheme-Text" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.3">
|
||||||
|
<rect x="3.5" y="3.5" width="15" height="15" rx="2.5" stroke-width="1"/><path d="M13.3 7.5H8.8v7h4.5M8.8 11h3.7"/>
|
||||||
|
</g></svg>
|
||||||
|
After Width: | Height: | Size: 434 B |
@@ -0,0 +1,5 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22" width="22" height="22">
|
||||||
|
<style id="current-color-scheme" type="text/css">.ColorScheme-Text { color: #fcfcfc; }</style>
|
||||||
|
<g class="ColorScheme-Text" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.3">
|
||||||
|
<rect x="3.5" y="3.5" width="15" height="15" rx="2.5" stroke-width="1"/><path d="M13.3 7.5H8.8v7h4.5M8.8 11h3.7"/>
|
||||||
|
</g></svg>
|
||||||
|
After Width: | Height: | Size: 434 B |
@@ -0,0 +1,33 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Install Breeze-style tray icons for Ngó Sen. Usage: sudo ./install.sh
|
||||||
|
set -euo pipefail
|
||||||
|
here=$(cd "$(dirname "$0")" && pwd)
|
||||||
|
ROOT=${ROOT:-} # for dry-run testing only
|
||||||
|
[[ $EUID -eq 0 || -n $ROOT ]] || { echo "Must be run with sudo"; exit 1; }
|
||||||
|
owner=${SUDO_USER:-$(id -un "${PKEXEC_UID:-0}")}
|
||||||
|
dest=$ROOT/usr/local/share/ngosen-breeze-icons
|
||||||
|
|
||||||
|
install -d "$dest/icons"
|
||||||
|
install -m644 "$here"/icons/*.svg "$dest/icons/"
|
||||||
|
install -m755 "$here/apply.sh" "$dest/apply.sh"
|
||||||
|
install -Dm644 "$here/ngosen-breeze-icons.hook" "$ROOT/etc/pacman.d/hooks/ngosen-breeze-icons.hook"
|
||||||
|
# Older versions used NoUpgrade in pacman.conf; the hook replaces it
|
||||||
|
sed -i '/^# ngosen-breeze-icons$/,+1d' "$ROOT/etc/pacman.conf"
|
||||||
|
ROOT=$ROOT "$dest/apply.sh"
|
||||||
|
|
||||||
|
# Ngó Sen: use the monochrome icons (not the lotus ones), white for a dark panel
|
||||||
|
conf=$ROOT$(getent passwd "$owner" | cut -d: -f6)/.config/fcitx5/conf/ngosen.conf
|
||||||
|
as_owner() { if [[ -n $ROOT ]]; then "$@"; else runuser -u "$owner" -- "$@"; fi; }
|
||||||
|
if [[ -f $conf ]]; then
|
||||||
|
for kv in UseLotusIcons=False IconTheme=Dark; do
|
||||||
|
k=${kv%%=*}
|
||||||
|
if grep -q "^$k=" "$conf"; then as_owner sed -i "s/^$k=.*/$kv/" "$conf"
|
||||||
|
elif grep -q "^# $k=" "$conf"; then as_owner sed -i "s/^# $k=.*/$kv/" "$conf"
|
||||||
|
else as_owner sh -c "echo '$kv' >> '$conf'"; fi
|
||||||
|
done
|
||||||
|
else
|
||||||
|
as_owner install -Dm600 /dev/stdin "$conf" <<<$'UseLotusIcons=False\nIconTheme=Dark'
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Done. Restart fcitx5 and plasmashell (without sudo):"
|
||||||
|
echo " $here/restart-fcitx5.sh; systemctl --user restart plasma-plasmashell"
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
[Trigger]
|
||||||
|
Operation = Install
|
||||||
|
Operation = Upgrade
|
||||||
|
Type = Package
|
||||||
|
Target = fcitx5-ngosen
|
||||||
|
|
||||||
|
[Action]
|
||||||
|
Description = Applying Breeze-style tray icons for Ngó Sen...
|
||||||
|
When = PostTransaction
|
||||||
|
Exec = /usr/local/share/ngosen-breeze-icons/apply.sh
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Restart fcitx5 through KWin (KDE Wayland) so it keeps the Wayland input method frontend.
|
||||||
|
L=$(kreadconfig6 --file kwinrc --group Wayland --key InputMethod)
|
||||||
|
[[ -n $L ]] || L=/usr/share/applications/fcitx5-wayland-launcher.desktop
|
||||||
|
pkill -x fcitx5; sleep 1
|
||||||
|
kwriteconfig6 --notify --file kwinrc --group Wayland --key InputMethod --delete; sleep 1
|
||||||
|
kwriteconfig6 --notify --file kwinrc --group Wayland --key InputMethod "$L"
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Put Ngó Sen's original icons back and remove the hook. Usage: sudo ./restore.sh
|
||||||
|
set -euo pipefail
|
||||||
|
ROOT=${ROOT:-} # for dry-run testing only
|
||||||
|
[[ $EUID -eq 0 || -n $ROOT ]] || { echo "Must be run with sudo"; exit 1; }
|
||||||
|
dest=$ROOT/usr/local/share/ngosen-breeze-icons
|
||||||
|
[[ -d $dest/orig/usr ]] || { echo "No original icons in $dest/orig"; exit 1; }
|
||||||
|
(cd "$dest/orig" && find usr -name '*.svg' -print0) | while IFS= read -r -d '' f; do
|
||||||
|
install -m644 "$dest/orig/$f" "$ROOT/$f"
|
||||||
|
done
|
||||||
|
rm -f "$ROOT/etc/pacman.d/hooks/ngosen-breeze-icons.hook"
|
||||||
|
rm -rf "$dest"
|
||||||
|
echo "Restored. To get the lotus icons back, turn them on in Ngó Sen Settings."
|
||||||
|
echo "Restart plasmashell (without sudo): systemctl --user restart plasma-plasmashell"
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
# Tray icons that match Breeze
|
||||||
|
|
||||||
|
```sh
|
||||||
|
stow -d kde -t "$HOME" tray-icons
|
||||||
|
```
|
||||||
|
|
||||||
|
Some icons need one more step after stowing; see below.
|
||||||
|
|
||||||
|
## Ngó Sen (fcitx5-ngosen)
|
||||||
|
|
||||||
|
Replaces Ngó Sen's monochrome tray icons with a V/E inside a rounded frame.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo ~/.local/share/ngosen-breeze-icons/install.sh
|
||||||
|
~/.local/share/ngosen-breeze-icons/restart-fcitx5.sh
|
||||||
|
systemctl --user restart plasma-plasmashell
|
||||||
|
```
|
||||||
|
|
||||||
|
- Ngó Sen points the tray at `/usr/share/icons/hicolor`, but Plasma looks
|
||||||
|
the icon up by name in the `breeze`/`breeze-dark` themes under
|
||||||
|
`/usr/share` and ignores `~/.local/share/icons`, so the system files have
|
||||||
|
to be replaced.
|
||||||
|
- `install.sh` copies the icons and `apply.sh` to
|
||||||
|
`/usr/local/share/ngosen-breeze-icons/`, installs the pacman hook
|
||||||
|
`/etc/pacman.d/hooks/ngosen-breeze-icons.hook` to re-apply them after
|
||||||
|
every package upgrade, and sets `UseLotusIcons=False` and
|
||||||
|
`IconTheme=Dark` in `~/.config/fcitx5/conf/ngosen.conf`.
|
||||||
|
- The original icons are kept in `/usr/local/share/ngosen-breeze-icons/orig/`;
|
||||||
|
`sudo ~/.local/share/ngosen-breeze-icons/restore.sh` puts them back and
|
||||||
|
removes the hook.
|
||||||
|
- On KDE Wayland don't start fcitx5 with `fcitx5 -d`; use
|
||||||
|
`restart-fcitx5.sh` so KWin launches it.
|
||||||
|
|
||||||
|
## NetBird (netbird-ui)
|
||||||
|
|
||||||
|
Scales NetBird's tray icons down to 80% so they get the padding of Breeze
|
||||||
|
status icons, and draws the white ones in the panel's text color
|
||||||
|
(`#dedede`) instead of pure white.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo ~/.local/share/netbird-breeze-icons/install.sh
|
||||||
|
pkill -x netbird-ui; setsid -f netbird-ui --daemon-addr unix:///var/run/netbird/main.sock >/dev/null 2>&1
|
||||||
|
```
|
||||||
|
|
||||||
|
- NetBird sends the tray icon as raw pixels, not an icon name, so an icon
|
||||||
|
theme can't replace it. `patch.py` rewrites the 48x48 PNGs embedded in
|
||||||
|
`/usr/bin/netbird-ui` in place instead; each new PNG fits in the bytes
|
||||||
|
of the old one.
|
||||||
|
- `install.sh` copies `patch.py` and `apply.sh` to
|
||||||
|
`/usr/local/share/netbird-breeze-icons/` and installs the pacman hook
|
||||||
|
`/etc/pacman.d/hooks/netbird-breeze-icons.hook` to re-patch the binary
|
||||||
|
after every `netbird-ui`/`netbird-ui-bin` upgrade.
|
||||||
|
- The original binary is kept in `/usr/local/share/netbird-breeze-icons/orig/`;
|
||||||
|
`sudo ~/.local/share/netbird-breeze-icons/restore.sh` puts it back and
|
||||||
|
removes the hook.
|
||||||
|
|
||||||
|
## qBittorrent
|
||||||
|
|
||||||
|
`qbittorrent-tray-mono.svg` is qBittorrent's monochrome tray icon scaled
|
||||||
|
down to 78%, so it has the same padding as Breeze status icons instead of
|
||||||
|
filling the whole tray slot.
|
||||||
|
|
||||||
|
qBittorrent 5.x only looks the tray icon up in the icon theme when "Use
|
||||||
|
icons from system theme" is on, so also set (qBittorrent closed, or via
|
||||||
|
Tools > Options > Behavior):
|
||||||
|
|
||||||
|
```ini
|
||||||
|
# ~/.config/qBittorrent/qBittorrent.conf
|
||||||
|
[Appearance]
|
||||||
|
TrayIconStyle=Monochrome
|
||||||
|
|
||||||
|
[Preferences]
|
||||||
|
Advanced\useSystemIconTheme=true
|
||||||
|
```
|
||||||
|
|
||||||
|
`qBittorrent.conf` itself isn't stowed: qBittorrent rewrites it on exit.
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
# vim:fileencoding=utf-8:foldmethod=marker
|
|
||||||
|
|
||||||
font_family JetBrainsMono Nerd Font Regular
|
|
||||||
bold_font JetBrainsMono Nerd Font Bold
|
|
||||||
italic_font JetBrainsMono Nerd Font Italic
|
|
||||||
bold_italic_font JetBrainsMono Nerd Font Bold Italic
|
|
||||||
|
|
||||||
font_size 13.0
|
|
||||||
|
|
||||||
background_opacity 0.85
|
|
||||||
|
|
||||||
allow_hyperlinks yes
|
|
||||||
|
|
||||||
shell_integration enabled
|
|
||||||
|
|
||||||
macos_option_as_alt yes
|
|
||||||
|
|
||||||
# include ./mocha.conf
|
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
# macOS packages
|
||||||
|
|
||||||
|
From the repository root, install all macOS packages:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
(cd mac && stow -t "$HOME" */)
|
||||||
|
```
|
||||||
|
|
||||||
|
Install the package:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
stow -d mac -t "$HOME" ghostty
|
||||||
|
```
|
||||||
|
|
||||||
|
- `ghostty`: JetBrainsMono Nerd Font and Ghostty's bundled SpaceGray Eighties theme.
|
||||||
@@ -1,104 +0,0 @@
|
|||||||
# Don't ask for confirmations
|
|
||||||
#assume_yes = true
|
|
||||||
|
|
||||||
# Disable specific steps - same options as the command line flag
|
|
||||||
disable = ["system", "emacs", "gem", "node", "pnpm", "pip3", "micro", "containers"]
|
|
||||||
|
|
||||||
display_preamble = false
|
|
||||||
|
|
||||||
# Ignore failures for these steps
|
|
||||||
#ignore_failures = ["powershell"]
|
|
||||||
|
|
||||||
# Run specific steps - same options as the command line flag
|
|
||||||
#only = ["system", "emacs"]
|
|
||||||
|
|
||||||
# Do not ask to retry failed steps (default: false)
|
|
||||||
#no_retry = true
|
|
||||||
|
|
||||||
# Run inside tmux
|
|
||||||
#run_in_tmux = true
|
|
||||||
|
|
||||||
# List of remote machines with Topgrade installed on them
|
|
||||||
#remote_topgrades = ["toothless", "pi", "parnas"]
|
|
||||||
|
|
||||||
# Arguments to pass SSH when upgrading remote systems
|
|
||||||
#ssh_arguments = "-o ConnectTimeout=2"
|
|
||||||
|
|
||||||
# Path to Topgrade executable on remote machines
|
|
||||||
#remote_topgrade_path = ".cargo/bin/topgrade"
|
|
||||||
|
|
||||||
# Arguments to pass tmux when pulling Repositories
|
|
||||||
#tmux_arguments = "-S /var/tmux.sock"
|
|
||||||
|
|
||||||
# Do not set the terminal title
|
|
||||||
#set_title = false
|
|
||||||
|
|
||||||
# Display the time in step titles
|
|
||||||
# display_time = true
|
|
||||||
|
|
||||||
# Cleanup temporary or old files
|
|
||||||
#cleanup = true
|
|
||||||
|
|
||||||
[git]
|
|
||||||
#max_concurrency = 5
|
|
||||||
# Additional git repositories to pull
|
|
||||||
#repos = [
|
|
||||||
# "~/src/*/",
|
|
||||||
# "~/.config/something"
|
|
||||||
#]
|
|
||||||
|
|
||||||
# Don't pull the predefined git repos
|
|
||||||
#pull_predefined = false
|
|
||||||
|
|
||||||
# Arguments to pass Git when pulling Repositories
|
|
||||||
#arguments = "--rebase --autostash"
|
|
||||||
|
|
||||||
[composer]
|
|
||||||
#self_update = true
|
|
||||||
|
|
||||||
# Commands to run before anything
|
|
||||||
[pre_commands]
|
|
||||||
#"Emacs Snapshot" = "rm -rf ~/.emacs.d/elpa.bak && cp -rl ~/.emacs.d/elpa ~/.emacs.d/elpa.bak"
|
|
||||||
|
|
||||||
# Custom commands
|
|
||||||
[commands]
|
|
||||||
#"Python Environment" = "~/dev/.env/bin/pip install -i https://pypi.python.org/simple -U --upgrade-strategy eager jupyter"
|
|
||||||
|
|
||||||
[brew]
|
|
||||||
#greedy_cask = true
|
|
||||||
|
|
||||||
[linux]
|
|
||||||
# Arch Package Manager to use. Allowed values: autodetect, trizen, paru, yay, pikaur, pacman.
|
|
||||||
#arch_package_manager = "pacman"
|
|
||||||
# Arguments to pass yay (or paru) when updating packages
|
|
||||||
#yay_arguments = "--nodevel"
|
|
||||||
#show_arch_news = true
|
|
||||||
#trizen_arguments = "--devel"
|
|
||||||
#pikaur_arguments = ""
|
|
||||||
#enable_tlmgr = true
|
|
||||||
#emerge_sync_flags = "-q"
|
|
||||||
#emerge_update_flags = "-uDNa --with-bdeps=y world"
|
|
||||||
#redhat_distro_sync = false
|
|
||||||
#rpm_ostree = false
|
|
||||||
|
|
||||||
[windows]
|
|
||||||
# Manually select Windows updates
|
|
||||||
#accept_all_updates = false
|
|
||||||
#open_remotes_in_new_terminal = true
|
|
||||||
|
|
||||||
# Causes Topgrade to rename itself during the run to allow package managers
|
|
||||||
# to upgrade it. Use this only if you installed Topgrade by using a package
|
|
||||||
# manager such as Scoop to Cargo
|
|
||||||
#self_rename = true
|
|
||||||
|
|
||||||
[npm]
|
|
||||||
# Use sudo if the NPM directory isn't owned by the current user
|
|
||||||
#use_sudo = true
|
|
||||||
|
|
||||||
[firmware]
|
|
||||||
# Offer to update firmware; if false just check for and display available updates
|
|
||||||
#upgrade = true
|
|
||||||
|
|
||||||
[flatpak]
|
|
||||||
# Use sudo for updating the system-wide installation
|
|
||||||
#use_sudo = true
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
# install zinit
|
|
||||||
source $ZDOTDIR/zinit
|
|
||||||
|
|
||||||
# load remote plugins
|
|
||||||
zinit wait lucid light-mode id-as depth"1" for \
|
|
||||||
wintermi/zsh-brew \
|
|
||||||
hlissner/zsh-autopair \
|
|
||||||
Aloxaf/fzf-tab \
|
|
||||||
atinit"zicompinit; zicdreplay -q" \
|
|
||||||
zdharma-continuum/fast-syntax-highlighting \
|
|
||||||
atload"_zsh_autosuggest_start" \
|
|
||||||
zsh-users/zsh-autosuggestions
|
|
||||||
|
|
||||||
# load prompt theme
|
|
||||||
zinit ice as"command" from"gh-r" id-as \
|
|
||||||
atclone"./starship init zsh > init.zsh; ./starship completions zsh > _starship" \
|
|
||||||
atpull"%atclone" src"init.zsh"
|
|
||||||
zinit light starship/starship
|
|
||||||
|
|
||||||
# load binaries
|
|
||||||
zinit as"command" wait lucid light-mode from"gh-r" id-as for \
|
|
||||||
extract"!" lsd-rs/lsd \
|
|
||||||
extract"!" zyedidia/micro \
|
|
||||||
extract"!" cp"autocomplete/bat.zsh -> _bat" @sharkdp/bat \
|
|
||||||
extract"!" pick"usr/bin/fastfetch" \
|
|
||||||
fastfetch-cli/fastfetch \
|
|
||||||
atclone"./zoxide init zsh > init.zsh" atpull"%atclone" src"init.zsh" \
|
|
||||||
ajeetdsouza/zoxide \
|
|
||||||
atclone"./fzf --zsh > init.zsh" atpull="%atclone" src"init.zsh" \
|
|
||||||
junegunn/fzf \
|
|
||||||
atclone"./fnm env --use-on-cd --shell zsh > init.zsh; ./fnm completions --shell zsh > _fnm" atpull"%atclone" src"init.zsh" Schniz/fnm
|
|
||||||
|
|
||||||
# load local scripts
|
|
||||||
zinit is-snippet id-as for \
|
|
||||||
$ZDOTDIR/snippets/exports \
|
|
||||||
$ZDOTDIR/snippets/aliases \
|
|
||||||
$ZDOTDIR/snippets/options \
|
|
||||||
$ZDOTDIR/snippets/bin
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
#!/usr/bin/env zsh
|
|
||||||
|
|
||||||
# Add GNU tools to PATH without 'g' prefix
|
|
||||||
local gnu_tools=(
|
|
||||||
"coreutils"
|
|
||||||
"findutils"
|
|
||||||
"gnu-tar"
|
|
||||||
"gnu-sed"
|
|
||||||
"gawk"
|
|
||||||
"gnu-indent"
|
|
||||||
"grep"
|
|
||||||
)
|
|
||||||
|
|
||||||
for tool in $gnu_tools; do
|
|
||||||
local gnubin="/opt/homebrew/opt/$tool/libexec/gnubin"
|
|
||||||
if [ -d "$gnubin" ]; then
|
|
||||||
case ":$PATH:" in
|
|
||||||
*":$gnubin:"*) ;;
|
|
||||||
*) export PATH="$gnubin:$PATH" ;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Add other bins separately since they have a different path structure
|
|
||||||
local bin_paths=(
|
|
||||||
"$HOME/.local/bin"
|
|
||||||
"/opt/homebrew/opt/gnu-getopt/bin"
|
|
||||||
)
|
|
||||||
for bin_path in $bin_paths; do
|
|
||||||
if [ -d "$bin_path" ]; then
|
|
||||||
case ":$PATH:" in
|
|
||||||
*":$bin_path:"*) ;;
|
|
||||||
*) export PATH="$bin_path:$PATH" ;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
#!/usr/bin/env zsh
|
|
||||||
|
|
||||||
ZINIT_HOME="${XDG_DATA_HOME:-${HOME}/.local/share}/zinit/zinit.git"
|
|
||||||
[ ! -d $ZINIT_HOME ] && mkdir -p "$(dirname $ZINIT_HOME)"
|
|
||||||
[ ! -d $ZINIT_HOME/.git ] && git clone https://github.com/zdharma-continuum/zinit.git "$ZINIT_HOME"
|
|
||||||
|
|
||||||
# not to use aliases: zi or zini
|
|
||||||
declare -A ZINIT
|
|
||||||
ZINIT[NO_ALIASES]=1
|
|
||||||
ZINIT[LIST_COMMAND]='lsd --tree'
|
|
||||||
|
|
||||||
source "${ZINIT_HOME}/zinit.zsh"
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
export XDG_CONFIG_HOME="${HOME}/.config"
|
|
||||||
export ZDOTDIR="${XDG_CONFIG_HOME}/zsh"
|
|
||||||
export SHELL_SESSIONS_DISABLE=1
|
|
||||||