mirror of
https://github.com/helix-editor/helix.git
synced 2024-11-22 09:26:19 +04:00
Compare commits
53 Commits
039a21f756
...
c7b47c827b
Author | SHA1 | Date | |
---|---|---|---|
|
c7b47c827b | ||
|
b8313da5a8 | ||
|
32ff0fce4a | ||
|
9e171e7d1d | ||
|
b92e8abfb3 | ||
|
8807dbfc40 | ||
|
15b478d433 | ||
|
467fad51b1 | ||
|
b855cd0cda | ||
|
6101b3a7a3 | ||
|
887bbbc375 | ||
|
7ee66c0658 | ||
|
843c058f0b | ||
|
ed7e5bd8dc | ||
|
b501a300e9 | ||
|
310bc04f23 | ||
|
2f6a113fbe | ||
|
8c6ca3c0fc | ||
|
b97c745631 | ||
|
d8e2aab201 | ||
|
188f701f50 | ||
|
83f1b98e80 | ||
|
4dc46f9472 | ||
|
4d0b7e57b1 | ||
|
548fd57489 | ||
|
8ed8d52e9d | ||
|
eeb5b7bbdd | ||
|
d95b21ddd3 | ||
|
56bb366f7e | ||
|
06d5b88dee | ||
|
e2d79c1891 | ||
|
5b3e0b64f0 | ||
|
07262f5170 | ||
|
6ec510d58f | ||
|
4d3612125b | ||
|
f9ac1f1ff1 | ||
|
2dbecd3c80 | ||
|
aa10b1fd11 | ||
|
07968880e6 | ||
|
4e2faa0be9 | ||
|
0fca0d057e | ||
|
68ee87695b | ||
|
b6e555a2ed | ||
|
48e15f77f7 | ||
|
59b020ec91 | ||
|
239262e094 | ||
|
23600e3ecb | ||
|
287e412780 | ||
|
bc18dc2c0c | ||
|
3fd7ca334e | ||
|
6373027c9e | ||
|
f06f481ad9 | ||
|
ec7b62e551 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,3 +3,4 @@ target
|
|||||||
helix-term/rustfmt.toml
|
helix-term/rustfmt.toml
|
||||||
result
|
result
|
||||||
runtime/grammars
|
runtime/grammars
|
||||||
|
.DS_Store
|
||||||
|
31
Cargo.lock
generated
31
Cargo.lock
generated
@ -136,9 +136,9 @@ checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.1.37"
|
version = "1.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "40545c26d092346d8a8dab71ee48e7685a7a9cba76e634790c215b41a4a7b4cf"
|
checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"shlex",
|
"shlex",
|
||||||
]
|
]
|
||||||
@ -211,6 +211,15 @@ dependencies = [
|
|||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-channel"
|
||||||
|
version = "0.5.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-deque"
|
name = "crossbeam-deque"
|
||||||
version = "0.8.5"
|
version = "0.8.5"
|
||||||
@ -710,12 +719,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "8e0eb9efdf96c35c0bed7596d1bef2d4ce6360a1d09738001f9d3e402aa7ba3e"
|
checksum = "8e0eb9efdf96c35c0bed7596d1bef2d4ce6360a1d09738001f9d3e402aa7ba3e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crc32fast",
|
"crc32fast",
|
||||||
|
"crossbeam-channel",
|
||||||
"flate2",
|
"flate2",
|
||||||
"gix-hash",
|
"gix-hash",
|
||||||
"gix-trace",
|
"gix-trace",
|
||||||
"gix-utils",
|
"gix-utils",
|
||||||
"libc",
|
"libc",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
"parking_lot",
|
||||||
"prodash",
|
"prodash",
|
||||||
"sha1_smol",
|
"sha1_smol",
|
||||||
"thiserror 1.0.69",
|
"thiserror 1.0.69",
|
||||||
@ -1755,9 +1766,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.162"
|
version = "0.2.164"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398"
|
checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libloading"
|
name = "libloading"
|
||||||
@ -1911,9 +1922,9 @@ checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "open"
|
name = "open"
|
||||||
version = "5.3.0"
|
version = "5.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "61a877bf6abd716642a53ef1b89fb498923a4afca5c754f9050b4d081c05c4b3"
|
checksum = "3ecd52f0b8d15c40ce4820aa251ed5de032e5d91fab27f7db2f40d42a8bdf69c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"is-wsl",
|
"is-wsl",
|
||||||
"libc",
|
"libc",
|
||||||
@ -2128,9 +2139,9 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustix"
|
name = "rustix"
|
||||||
version = "0.38.40"
|
version = "0.38.41"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0"
|
checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"errno",
|
"errno",
|
||||||
@ -2182,9 +2193,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.132"
|
version = "1.0.133"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03"
|
checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"memchr",
|
"memchr",
|
||||||
|
@ -117,7 +117,7 @@ #### Note to packagers
|
|||||||
script could follow are:
|
script could follow are:
|
||||||
|
|
||||||
1. `export HELIX_DEFAULT_RUNTIME=/usr/lib/helix/runtime`
|
1. `export HELIX_DEFAULT_RUNTIME=/usr/lib/helix/runtime`
|
||||||
1. `cargo build --profile opt --locked --path helix-term`
|
1. `cargo build --profile opt --locked`
|
||||||
1. `cp -r runtime $BUILD_DIR/usr/lib/helix/`
|
1. `cp -r runtime $BUILD_DIR/usr/lib/helix/`
|
||||||
1. `cp target/opt/hx $BUILD_DIR/usr/bin/hx`
|
1. `cp target/opt/hx $BUILD_DIR/usr/bin/hx`
|
||||||
|
|
||||||
|
@ -27,8 +27,8 @@ # Configuration
|
|||||||
|
|
||||||
You can use a custom configuration file by specifying it with the `-c` or
|
You can use a custom configuration file by specifying it with the `-c` or
|
||||||
`--config` command line argument, for example `hx -c path/to/custom-config.toml`.
|
`--config` command line argument, for example `hx -c path/to/custom-config.toml`.
|
||||||
Additionally, you can reload the configuration file by sending the USR1
|
You can reload the config file by issuing the `:config-reload` command. Alternatively, on Unix operating systems, you can reload it by sending the USR1
|
||||||
signal to the Helix process on Unix operating systems, such as by using the command `pkill -USR1 hx`.
|
signal to the Helix process, such as by using the command `pkill -USR1 hx`.
|
||||||
|
|
||||||
Finally, you can have a `config.toml` local to a project by putting it under a `.helix` directory in your repository.
|
Finally, you can have a `config.toml` local to a project by putting it under a `.helix` directory in your repository.
|
||||||
Its settings will be merged with the configuration directory `config.toml` and the built-in configuration.
|
Its settings will be merged with the configuration directory `config.toml` and the built-in configuration.
|
||||||
|
@ -24,6 +24,7 @@ ### `[editor]` Section
|
|||||||
|--|--|---------|
|
|--|--|---------|
|
||||||
| `scrolloff` | Number of lines of padding around the edge of the screen when scrolling | `5` |
|
| `scrolloff` | Number of lines of padding around the edge of the screen when scrolling | `5` |
|
||||||
| `mouse` | Enable mouse mode | `true` |
|
| `mouse` | Enable mouse mode | `true` |
|
||||||
|
| `default-yank-register` | Default register used for yank/paste | `"` |
|
||||||
| `middle-click-paste` | Middle click paste support | `true` |
|
| `middle-click-paste` | Middle click paste support | `true` |
|
||||||
| `scroll-lines` | Number of lines to scroll per scroll wheel step | `3` |
|
| `scroll-lines` | Number of lines to scroll per scroll wheel step | `3` |
|
||||||
| `shell` | Shell to use when running external commands | Unix: `["sh", "-c"]`<br/>Windows: `["cmd", "/C"]` |
|
| `shell` | Shell to use when running external commands | Unix: `["sh", "-c"]`<br/>Windows: `["cmd", "/C"]` |
|
||||||
@ -52,6 +53,30 @@ ### `[editor]` Section
|
|||||||
| `indent-heuristic` | How the indentation for a newly inserted line is computed: `simple` just copies the indentation level from the previous line, `tree-sitter` computes the indentation based on the syntax tree and `hybrid` combines both approaches. If the chosen heuristic is not available, a different one will be used as a fallback (the fallback order being `hybrid` -> `tree-sitter` -> `simple`). | `hybrid`
|
| `indent-heuristic` | How the indentation for a newly inserted line is computed: `simple` just copies the indentation level from the previous line, `tree-sitter` computes the indentation based on the syntax tree and `hybrid` combines both approaches. If the chosen heuristic is not available, a different one will be used as a fallback (the fallback order being `hybrid` -> `tree-sitter` -> `simple`). | `hybrid`
|
||||||
| `jump-label-alphabet` | The characters that are used to generate two character jump labels. Characters at the start of the alphabet are used first. | `"abcdefghijklmnopqrstuvwxyz"`
|
| `jump-label-alphabet` | The characters that are used to generate two character jump labels. Characters at the start of the alphabet are used first. | `"abcdefghijklmnopqrstuvwxyz"`
|
||||||
| `end-of-line-diagnostics` | Minimum severity of diagnostics to render at the end of the line. Set to `disable` to disable entirely. Refer to the setting about `inline-diagnostics` for more details | "disable"
|
| `end-of-line-diagnostics` | Minimum severity of diagnostics to render at the end of the line. Set to `disable` to disable entirely. Refer to the setting about `inline-diagnostics` for more details | "disable"
|
||||||
|
| `clipboard-provider` | Which API to use for clipboard interaction. One of `pasteboard` (MacOS), `wayland`, `x-clip`, `x-sel`, `win-32-yank`, `termux`, `tmux`, `windows`, `termcode`, `none`, or a custom command set. | Platform and environment specific. |
|
||||||
|
|
||||||
|
### `[editor.clipboard-provider]` Section
|
||||||
|
|
||||||
|
Helix can be configured wither to use a builtin clipboard configuration or to use
|
||||||
|
a provided command.
|
||||||
|
|
||||||
|
For instance, setting it to use OSC 52 termcodes, the configuration would be:
|
||||||
|
```toml
|
||||||
|
[editor]
|
||||||
|
clipboard-provider = "termcode"
|
||||||
|
```
|
||||||
|
|
||||||
|
Alternatively, Helix can be configured to use arbitary commands for clipboard integration:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[editor.clipboard-provider.custom]
|
||||||
|
yank = { command = "cat", args = ["test.txt"] }
|
||||||
|
paste = { command = "tee", args = ["test.txt"] }
|
||||||
|
primary-yank = { command = "cat", args = ["test-primary.txt"] } # optional
|
||||||
|
primary-paste = { command = "tee", args = ["test-primary.txt"] } # optional
|
||||||
|
```
|
||||||
|
|
||||||
|
For custom commands the contents of the yank/paste is communicated over stdin/stdout.
|
||||||
|
|
||||||
### `[editor.statusline]` Section
|
### `[editor.statusline]` Section
|
||||||
|
|
||||||
@ -428,7 +453,8 @@ ### `[editor.inline-diagnostics]` Section
|
|||||||
|
|
||||||
The new diagnostic rendering is not yet enabled by default. As soon as end of line or inline diagnostics are enabled the old diagnostics rendering is automatically disabled. The recommended default setting are:
|
The new diagnostic rendering is not yet enabled by default. As soon as end of line or inline diagnostics are enabled the old diagnostics rendering is automatically disabled. The recommended default setting are:
|
||||||
|
|
||||||
```
|
```toml
|
||||||
|
[editor]
|
||||||
end-of-line-diagnostics = "hint"
|
end-of-line-diagnostics = "hint"
|
||||||
[editor.inline-diagnostics]
|
[editor.inline-diagnostics]
|
||||||
cursor-line = "warning" # show warnings and errors on the cursorline inline
|
cursor-line = "warning" # show warnings and errors on the cursorline inline
|
||||||
|
@ -91,7 +91,7 @@
|
|||||||
| hosts | ✓ | | | |
|
| hosts | ✓ | | | |
|
||||||
| html | ✓ | | | `vscode-html-language-server`, `superhtml` |
|
| html | ✓ | | | `vscode-html-language-server`, `superhtml` |
|
||||||
| hurl | ✓ | ✓ | ✓ | |
|
| hurl | ✓ | ✓ | ✓ | |
|
||||||
| hyprlang | ✓ | | ✓ | |
|
| hyprlang | ✓ | | ✓ | `hyprls` |
|
||||||
| idris | | | | `idris2-lsp` |
|
| idris | | | | `idris2-lsp` |
|
||||||
| iex | ✓ | | | |
|
| iex | ✓ | | | |
|
||||||
| ini | ✓ | | | |
|
| ini | ✓ | | | |
|
||||||
@ -136,6 +136,7 @@
|
|||||||
| move | ✓ | | | |
|
| move | ✓ | | | |
|
||||||
| msbuild | ✓ | | ✓ | |
|
| msbuild | ✓ | | ✓ | |
|
||||||
| nasm | ✓ | ✓ | | |
|
| nasm | ✓ | ✓ | | |
|
||||||
|
| nestedtext | ✓ | ✓ | ✓ | |
|
||||||
| nickel | ✓ | | ✓ | `nls` |
|
| nickel | ✓ | | ✓ | `nls` |
|
||||||
| nim | ✓ | ✓ | ✓ | `nimlangserver` |
|
| nim | ✓ | ✓ | ✓ | `nimlangserver` |
|
||||||
| nix | ✓ | ✓ | | `nil`, `nixd` |
|
| nix | ✓ | ✓ | | `nil`, `nixd` |
|
||||||
@ -168,6 +169,7 @@
|
|||||||
| purescript | ✓ | ✓ | | `purescript-language-server` |
|
| purescript | ✓ | ✓ | | `purescript-language-server` |
|
||||||
| python | ✓ | ✓ | ✓ | `ruff`, `jedi-language-server`, `pylsp` |
|
| python | ✓ | ✓ | ✓ | `ruff`, `jedi-language-server`, `pylsp` |
|
||||||
| qml | ✓ | | ✓ | `qmlls` |
|
| qml | ✓ | | ✓ | `qmlls` |
|
||||||
|
| quint | ✓ | | | `quint-language-server` |
|
||||||
| r | ✓ | | | `R` |
|
| r | ✓ | | | `R` |
|
||||||
| racket | ✓ | | ✓ | `racket` |
|
| racket | ✓ | | ✓ | `racket` |
|
||||||
| regex | ✓ | | | |
|
| regex | ✓ | | | |
|
||||||
@ -189,6 +191,7 @@
|
|||||||
| sml | ✓ | | | |
|
| sml | ✓ | | | |
|
||||||
| snakemake | ✓ | | ✓ | `pylsp` |
|
| snakemake | ✓ | | ✓ | `pylsp` |
|
||||||
| solidity | ✓ | ✓ | | `solc` |
|
| solidity | ✓ | ✓ | | `solc` |
|
||||||
|
| spade | ✓ | | ✓ | `spade-language-server` |
|
||||||
| spicedb | ✓ | | | |
|
| spicedb | ✓ | | | |
|
||||||
| sql | ✓ | ✓ | | |
|
| sql | ✓ | ✓ | | |
|
||||||
| sshclientconfig | ✓ | | | |
|
| sshclientconfig | ✓ | | | |
|
||||||
@ -204,6 +207,7 @@
|
|||||||
| task | ✓ | | | |
|
| task | ✓ | | | |
|
||||||
| tcl | ✓ | | ✓ | |
|
| tcl | ✓ | | ✓ | |
|
||||||
| templ | ✓ | | | `templ` |
|
| templ | ✓ | | | `templ` |
|
||||||
|
| textproto | ✓ | ✓ | ✓ | |
|
||||||
| tfvars | ✓ | | ✓ | `terraform-ls` |
|
| tfvars | ✓ | | ✓ | `terraform-ls` |
|
||||||
| thrift | ✓ | | | |
|
| thrift | ✓ | | | |
|
||||||
| todotxt | ✓ | | | |
|
| todotxt | ✓ | | | |
|
||||||
@ -215,7 +219,7 @@
|
|||||||
| typespec | ✓ | ✓ | ✓ | `tsp-server` |
|
| typespec | ✓ | ✓ | ✓ | `tsp-server` |
|
||||||
| typst | ✓ | | | `tinymist`, `typst-lsp` |
|
| typst | ✓ | | | `tinymist`, `typst-lsp` |
|
||||||
| ungrammar | ✓ | | | |
|
| ungrammar | ✓ | | | |
|
||||||
| unison | ✓ | | ✓ | |
|
| unison | ✓ | ✓ | ✓ | |
|
||||||
| uxntal | ✓ | | | |
|
| uxntal | ✓ | | | |
|
||||||
| v | ✓ | ✓ | ✓ | `v-analyzer` |
|
| v | ✓ | ✓ | ✓ | `v-analyzer` |
|
||||||
| vala | ✓ | ✓ | | `vala-language-server` |
|
| vala | ✓ | ✓ | | `vala-language-server` |
|
||||||
|
@ -146,6 +146,7 @@ ### Selection manipulation
|
|||||||
| `Alt-p`, `Alt-left` | Select previous sibling node in syntax tree (**TS**) | `select_prev_sibling` |
|
| `Alt-p`, `Alt-left` | Select previous sibling node in syntax tree (**TS**) | `select_prev_sibling` |
|
||||||
| `Alt-n`, `Alt-right` | Select next sibling node in syntax tree (**TS**) | `select_next_sibling` |
|
| `Alt-n`, `Alt-right` | Select next sibling node in syntax tree (**TS**) | `select_next_sibling` |
|
||||||
| `Alt-a` | Select all sibling nodes in syntax tree (**TS**) | `select_all_siblings` |
|
| `Alt-a` | Select all sibling nodes in syntax tree (**TS**) | `select_all_siblings` |
|
||||||
|
| `Alt-I`, `Alt-Shift-down`| Select all children nodes in syntax tree (**TS**) | `select_all_children` |
|
||||||
| `Alt-e` | Move to end of parent node in syntax tree (**TS**) | `move_parent_node_end` |
|
| `Alt-e` | Move to end of parent node in syntax tree (**TS**) | `move_parent_node_end` |
|
||||||
| `Alt-b` | Move to start of parent node in syntax tree (**TS**) | `move_parent_node_start` |
|
| `Alt-b` | Move to start of parent node in syntax tree (**TS**) | `move_parent_node_start` |
|
||||||
|
|
||||||
@ -281,7 +282,7 @@ #### Space mode
|
|||||||
|
|
||||||
| Key | Description | Command |
|
| Key | Description | Command |
|
||||||
| ----- | ----------- | ------- |
|
| ----- | ----------- | ------- |
|
||||||
| `f` | Open file picker | `file_picker` |
|
| `f` | Open file picker at LSP workspace root | `file_picker` |
|
||||||
| `F` | Open file picker at current working directory | `file_picker_in_current_directory` |
|
| `F` | Open file picker at current working directory | `file_picker_in_current_directory` |
|
||||||
| `b` | Open buffer picker | `buffer_picker` |
|
| `b` | Open buffer picker | `buffer_picker` |
|
||||||
| `j` | Open jumplist picker | `jumplist_picker` |
|
| `j` | Open jumplist picker | `jumplist_picker` |
|
||||||
|
@ -102,6 +102,14 @@ ### AppImage
|
|||||||
./helix-*.AppImage # run helix
|
./helix-*.AppImage # run helix
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You can optionally [add the `.desktop` file](./building-from-source.md#configure-the-desktop-shortcut). Helix must be installed in `PATH` with the name `hx`. For example:
|
||||||
|
```sh
|
||||||
|
mkdir -p "$HOME/.local/bin"
|
||||||
|
mv helix-*.AppImage "$HOME/.local/bin/hx"
|
||||||
|
```
|
||||||
|
|
||||||
|
and make sure `~/.local/bin` is in your `PATH`.
|
||||||
|
|
||||||
## macOS
|
## macOS
|
||||||
|
|
||||||
### Homebrew Core
|
### Homebrew Core
|
||||||
|
@ -4,10 +4,31 @@ ## Key remapping
|
|||||||
file. (More powerful solutions such as rebinding via commands will be
|
file. (More powerful solutions such as rebinding via commands will be
|
||||||
available in the future).
|
available in the future).
|
||||||
|
|
||||||
|
There are three kinds of commands that can be used in keymaps:
|
||||||
|
|
||||||
|
* Static commands: commands like `move_char_right` which are usually bound to
|
||||||
|
keys and used for movement and editing. A list of static commands is
|
||||||
|
available in the [Keymap](./keymap.html) documentation and in the source code
|
||||||
|
in [`helix-term/src/commands.rs`](https://github.com/helix-editor/helix/blob/master/helix-term/src/commands.rs)
|
||||||
|
at the invocation of `static_commands!` macro.
|
||||||
|
* Typable commands: commands that can be executed from command mode (`:`), for
|
||||||
|
example `:write!`. See the [Commands](./commands.html) documentation for a
|
||||||
|
list of available typeable commands or the `TypableCommandList` declaration in
|
||||||
|
the source code at [`helix-term/src/commands/typed.rs`](https://github.com/helix-editor/helix/blob/master/helix-term/src/commands/typed.rs).
|
||||||
|
* Macros: sequences of keys that are executed in order. These keybindings
|
||||||
|
start with `@` and then list any number of keys to be executed. For example
|
||||||
|
`@miw` can be used to select the surrounding word. For now, macro keybindings
|
||||||
|
are not allowed in keybinding sequences due to limitations in the way that
|
||||||
|
command sequences are executed. Modifier keys (e.g. Alt+o) can be used
|
||||||
|
like `"<A-o>"`, e.g. `"@miw<A-o>"`
|
||||||
|
|
||||||
To remap keys, create a `config.toml` file in your `helix` configuration
|
To remap keys, create a `config.toml` file in your `helix` configuration
|
||||||
directory (default `~/.config/helix` on Linux systems) with a structure like
|
directory (default `~/.config/helix` on Linux systems) with a structure like
|
||||||
this:
|
this:
|
||||||
|
|
||||||
|
> 💡 To set a modifier + key as a keymap, type `A-X = ...` or `C-X = ...` for Alt + X or Ctrl + X. Combine with Shift using a dash, e.g. `C-S-esc`.
|
||||||
|
> Within macros, wrap them in `<>`, e.g. `<A-X>` and `<C-X>` to distinguish from the `A` or `C` keys.
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
# At most one section each of 'keys.normal', 'keys.insert' and 'keys.select'
|
# At most one section each of 'keys.normal', 'keys.insert' and 'keys.select'
|
||||||
[keys.normal]
|
[keys.normal]
|
||||||
@ -18,6 +39,7 @@ # At most one section each of 'keys.normal', 'keys.insert' and 'keys.select'
|
|||||||
"C-S-esc" = "extend_line" # Maps Ctrl-Shift-Escape to extend_line
|
"C-S-esc" = "extend_line" # Maps Ctrl-Shift-Escape to extend_line
|
||||||
g = { a = "code_action" } # Maps `ga` to show possible code actions
|
g = { a = "code_action" } # Maps `ga` to show possible code actions
|
||||||
"ret" = ["open_below", "normal_mode"] # Maps the enter key to open_below then re-enter normal mode
|
"ret" = ["open_below", "normal_mode"] # Maps the enter key to open_below then re-enter normal mode
|
||||||
|
"A-x" = "@x<A-d>" # Maps Alt-x to a macro selecting the whole line and deleting it without yanking it
|
||||||
|
|
||||||
[keys.insert]
|
[keys.insert]
|
||||||
"A-x" = "normal_mode" # Maps Alt-X to enter normal mode
|
"A-x" = "normal_mode" # Maps Alt-X to enter normal mode
|
||||||
@ -74,21 +96,3 @@ ## Special keys and modifiers
|
|||||||
| Escape | `"esc"` |
|
| Escape | `"esc"` |
|
||||||
|
|
||||||
Keys can be disabled by binding them to the `no_op` command.
|
Keys can be disabled by binding them to the `no_op` command.
|
||||||
|
|
||||||
## Commands
|
|
||||||
|
|
||||||
There are three kinds of commands that can be used in keymaps:
|
|
||||||
|
|
||||||
* Static commands: commands like `move_char_right` which are usually bound to
|
|
||||||
keys and used for movement and editing. A list of static commands is
|
|
||||||
available in the [Keymap](./keymap.html) documentation and in the source code
|
|
||||||
in [`helix-term/src/commands.rs`](https://github.com/helix-editor/helix/blob/master/helix-term/src/commands.rs)
|
|
||||||
at the invocation of `static_commands!` macro and the `TypableCommandList`.
|
|
||||||
* Typable commands: commands that can be executed from command mode (`:`), for
|
|
||||||
example `:write!`. See the [Commands](./commands.html) documentation for a
|
|
||||||
list of available typeable commands.
|
|
||||||
* Macros: sequences of keys that are executed in order. These keybindings
|
|
||||||
start with `@` and then list any number of keys to be executed. For example
|
|
||||||
`@miw` can be used to select the surrounding word. For now, macro keybindings
|
|
||||||
are not allowed in keybinding sequences due to limitations in the way that
|
|
||||||
command sequences are executed.
|
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
/// Given a slice of text, return the text re-wrapped to fit it
|
/// Given a slice of text, return the text re-wrapped to fit it
|
||||||
/// within the given width.
|
/// within the given width.
|
||||||
pub fn reflow_hard_wrap(text: &str, text_width: usize) -> SmartString<LazyCompact> {
|
pub fn reflow_hard_wrap(text: &str, text_width: usize) -> SmartString<LazyCompact> {
|
||||||
let options = Options::new(text_width).word_splitter(NoHyphenation);
|
let options = Options::new(text_width)
|
||||||
|
.word_splitter(NoHyphenation)
|
||||||
|
.word_separator(textwrap::WordSeparator::AsciiSpace);
|
||||||
textwrap::refill(text, options).into()
|
textwrap::refill(text, options).into()
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ license = "MIT"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
bitflags = "2.6.0"
|
bitflags = "2.6.0"
|
||||||
serde = { version = "1.0.215", features = ["derive"] }
|
serde = { version = "1.0.215", features = ["derive"] }
|
||||||
serde_json = "1.0.132"
|
serde_json = "1.0.133"
|
||||||
serde_repr = "0.1"
|
serde_repr = "0.1"
|
||||||
url = {version = "2.5.3", features = ["serde"]}
|
url = {version = "2.5.3", features = ["serde"]}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ content_inspector = "0.2.4"
|
|||||||
thiserror.workspace = true
|
thiserror.workspace = true
|
||||||
|
|
||||||
# opening URLs
|
# opening URLs
|
||||||
open = "5.3.0"
|
open = "5.3.1"
|
||||||
url = "2.5.3"
|
url = "2.5.3"
|
||||||
|
|
||||||
# config
|
# config
|
||||||
@ -74,7 +74,7 @@ grep-searcher = "0.1.14"
|
|||||||
|
|
||||||
[target.'cfg(not(windows))'.dependencies] # https://github.com/vorner/signal-hook/issues/100
|
[target.'cfg(not(windows))'.dependencies] # https://github.com/vorner/signal-hook/issues/100
|
||||||
signal-hook-tokio = { version = "0.3", features = ["futures-v0_3"] }
|
signal-hook-tokio = { version = "0.3", features = ["futures-v0_3"] }
|
||||||
libc = "0.2.162"
|
libc = "0.2.164"
|
||||||
|
|
||||||
[target.'cfg(target_os = "macos")'.dependencies]
|
[target.'cfg(target_os = "macos")'.dependencies]
|
||||||
crossterm = { version = "0.28", features = ["event-stream", "use-dev-tty", "libc"] }
|
crossterm = { version = "0.28", features = ["event-stream", "use-dev-tty", "libc"] }
|
||||||
|
@ -71,6 +71,7 @@
|
|||||||
future::Future,
|
future::Future,
|
||||||
io::Read,
|
io::Read,
|
||||||
num::NonZeroUsize,
|
num::NonZeroUsize,
|
||||||
|
sync::Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
@ -2735,7 +2736,9 @@ fn delete_selection_impl(cx: &mut Context, op: Operation, yank: YankAction) {
|
|||||||
// yank the selection
|
// yank the selection
|
||||||
let text = doc.text().slice(..);
|
let text = doc.text().slice(..);
|
||||||
let values: Vec<String> = selection.fragments(text).map(Cow::into_owned).collect();
|
let values: Vec<String> = selection.fragments(text).map(Cow::into_owned).collect();
|
||||||
let reg_name = cx.register.unwrap_or('"');
|
let reg_name = cx
|
||||||
|
.register
|
||||||
|
.unwrap_or_else(|| cx.editor.config.load().default_yank_register);
|
||||||
if let Err(err) = cx.editor.registers.write(reg_name, values) {
|
if let Err(err) = cx.editor.registers.write(reg_name, values) {
|
||||||
cx.editor.set_error(err.to_string());
|
cx.editor.set_error(err.to_string());
|
||||||
return;
|
return;
|
||||||
@ -3109,7 +3112,7 @@ struct JumpMeta {
|
|||||||
|
|
||||||
fn changed_file_picker(cx: &mut Context) {
|
fn changed_file_picker(cx: &mut Context) {
|
||||||
pub struct FileChangeData {
|
pub struct FileChangeData {
|
||||||
cwd: PathBuf,
|
cwd: Arc<Path>,
|
||||||
style_untracked: Style,
|
style_untracked: Style,
|
||||||
style_modified: Style,
|
style_modified: Style,
|
||||||
style_conflict: Style,
|
style_conflict: Style,
|
||||||
@ -3117,7 +3120,7 @@ pub struct FileChangeData {
|
|||||||
style_renamed: Style,
|
style_renamed: Style,
|
||||||
}
|
}
|
||||||
|
|
||||||
let cwd = helix_stdx::env::current_working_dir();
|
let cwd: Arc<Path> = Arc::from(helix_stdx::env::current_working_dir().as_path());
|
||||||
if !cwd.exists() {
|
if !cwd.exists() {
|
||||||
cx.editor
|
cx.editor
|
||||||
.set_error("Current working directory does not exist");
|
.set_error("Current working directory does not exist");
|
||||||
@ -3188,17 +3191,24 @@ pub struct FileChangeData {
|
|||||||
.with_preview(|_editor, meta| Some((meta.path().into(), None)));
|
.with_preview(|_editor, meta| Some((meta.path().into(), None)));
|
||||||
let injector = picker.injector();
|
let injector = picker.injector();
|
||||||
|
|
||||||
cx.editor
|
// Helix can be launched without arguments, in which case no diff provider will be loaded since
|
||||||
.diff_providers
|
// there is no file to provide infos for.
|
||||||
.clone()
|
//
|
||||||
.for_each_changed_file(cwd, move |change| match change {
|
// This ensures we have one to work with for cwd (and as a bonus it means any file opened
|
||||||
|
// from this picker will have its diff provider already in cache).
|
||||||
|
cx.editor.diff_providers.add(&cwd);
|
||||||
|
cx.editor.diff_providers.clone().for_each_changed_file(
|
||||||
|
cwd.clone(),
|
||||||
|
move |change| match change {
|
||||||
Ok(change) => injector.push(change).is_ok(),
|
Ok(change) => injector.push(change).is_ok(),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
status::report_blocking(err);
|
status::report_blocking(err);
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
});
|
},
|
||||||
|
);
|
||||||
cx.push_layer(Box::new(overlaid(picker)));
|
cx.push_layer(Box::new(overlaid(picker)));
|
||||||
|
cx.editor.diff_providers.remove(&cwd);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn command_palette(cx: &mut Context) {
|
pub fn command_palette(cx: &mut Context) {
|
||||||
@ -4221,7 +4231,11 @@ fn commit_undo_checkpoint(cx: &mut Context) {
|
|||||||
// Yank / Paste
|
// Yank / Paste
|
||||||
|
|
||||||
fn yank(cx: &mut Context) {
|
fn yank(cx: &mut Context) {
|
||||||
yank_impl(cx.editor, cx.register.unwrap_or('"'));
|
yank_impl(
|
||||||
|
cx.editor,
|
||||||
|
cx.register
|
||||||
|
.unwrap_or(cx.editor.config().default_yank_register),
|
||||||
|
);
|
||||||
exit_select_mode(cx);
|
exit_select_mode(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4282,7 +4296,12 @@ fn yank_joined_impl(editor: &mut Editor, separator: &str, register: char) {
|
|||||||
|
|
||||||
fn yank_joined(cx: &mut Context) {
|
fn yank_joined(cx: &mut Context) {
|
||||||
let separator = doc!(cx.editor).line_ending.as_str();
|
let separator = doc!(cx.editor).line_ending.as_str();
|
||||||
yank_joined_impl(cx.editor, separator, cx.register.unwrap_or('"'));
|
yank_joined_impl(
|
||||||
|
cx.editor,
|
||||||
|
separator,
|
||||||
|
cx.register
|
||||||
|
.unwrap_or(cx.editor.config().default_yank_register),
|
||||||
|
);
|
||||||
exit_select_mode(cx);
|
exit_select_mode(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4339,6 +4358,10 @@ fn paste_impl(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if mode == Mode::Insert {
|
||||||
|
doc.append_changes_to_history(view);
|
||||||
|
}
|
||||||
|
|
||||||
let repeat = std::iter::repeat(
|
let repeat = std::iter::repeat(
|
||||||
// `values` is asserted to have at least one entry above.
|
// `values` is asserted to have at least one entry above.
|
||||||
values
|
values
|
||||||
@ -4438,7 +4461,12 @@ fn paste_primary_clipboard_before(cx: &mut Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn replace_with_yanked(cx: &mut Context) {
|
fn replace_with_yanked(cx: &mut Context) {
|
||||||
replace_with_yanked_impl(cx.editor, cx.register.unwrap_or('"'), cx.count());
|
replace_with_yanked_impl(
|
||||||
|
cx.editor,
|
||||||
|
cx.register
|
||||||
|
.unwrap_or(cx.editor.config().default_yank_register),
|
||||||
|
cx.count(),
|
||||||
|
);
|
||||||
exit_select_mode(cx);
|
exit_select_mode(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4501,7 +4529,8 @@ fn paste(editor: &mut Editor, register: char, pos: Paste, count: usize) {
|
|||||||
fn paste_after(cx: &mut Context) {
|
fn paste_after(cx: &mut Context) {
|
||||||
paste(
|
paste(
|
||||||
cx.editor,
|
cx.editor,
|
||||||
cx.register.unwrap_or('"'),
|
cx.register
|
||||||
|
.unwrap_or(cx.editor.config().default_yank_register),
|
||||||
Paste::After,
|
Paste::After,
|
||||||
cx.count(),
|
cx.count(),
|
||||||
);
|
);
|
||||||
@ -4511,7 +4540,8 @@ fn paste_after(cx: &mut Context) {
|
|||||||
fn paste_before(cx: &mut Context) {
|
fn paste_before(cx: &mut Context) {
|
||||||
paste(
|
paste(
|
||||||
cx.editor,
|
cx.editor,
|
||||||
cx.register.unwrap_or('"'),
|
cx.register
|
||||||
|
.unwrap_or(cx.editor.config().default_yank_register),
|
||||||
Paste::Before,
|
Paste::Before,
|
||||||
cx.count(),
|
cx.count(),
|
||||||
);
|
);
|
||||||
@ -5365,7 +5395,8 @@ fn insert_register(cx: &mut Context) {
|
|||||||
cx.register = Some(ch);
|
cx.register = Some(ch);
|
||||||
paste(
|
paste(
|
||||||
cx.editor,
|
cx.editor,
|
||||||
cx.register.unwrap_or('"'),
|
cx.register
|
||||||
|
.unwrap_or(cx.editor.config().default_yank_register),
|
||||||
Paste::Cursor,
|
Paste::Cursor,
|
||||||
cx.count(),
|
cx.count(),
|
||||||
);
|
);
|
||||||
|
@ -1074,7 +1074,7 @@ fn show_clipboard_provider(
|
|||||||
}
|
}
|
||||||
|
|
||||||
cx.editor
|
cx.editor
|
||||||
.set_status(cx.editor.registers.clipboard_provider_name().to_string());
|
.set_status(cx.editor.registers.clipboard_provider_name());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1279,7 +1279,7 @@ fn reload(
|
|||||||
|
|
||||||
let scrolloff = cx.editor.config().scrolloff;
|
let scrolloff = cx.editor.config().scrolloff;
|
||||||
let (view, doc) = current!(cx.editor);
|
let (view, doc) = current!(cx.editor);
|
||||||
doc.reload(view, &cx.editor.diff_providers).map(|_| {
|
doc.reload(view, &mut cx.editor.diff_providers).map(|_| {
|
||||||
view.ensure_cursor_in_view(doc, scrolloff);
|
view.ensure_cursor_in_view(doc, scrolloff);
|
||||||
})?;
|
})?;
|
||||||
if let Some(path) = doc.path() {
|
if let Some(path) = doc.path() {
|
||||||
@ -1318,6 +1318,8 @@ fn reload_all(
|
|||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
cx.editor.diff_providers.reset();
|
||||||
|
|
||||||
for (doc_id, view_ids) in docs_view_ids {
|
for (doc_id, view_ids) in docs_view_ids {
|
||||||
let doc = doc_mut!(cx.editor, &doc_id);
|
let doc = doc_mut!(cx.editor, &doc_id);
|
||||||
|
|
||||||
@ -1327,7 +1329,7 @@ fn reload_all(
|
|||||||
// Ensure that the view is synced with the document's history.
|
// Ensure that the view is synced with the document's history.
|
||||||
view.sync_changes(doc);
|
view.sync_changes(doc);
|
||||||
|
|
||||||
if let Err(error) = doc.reload(view, &cx.editor.diff_providers) {
|
if let Err(error) = doc.reload(view, &mut cx.editor.diff_providers) {
|
||||||
cx.editor.set_error(format!("{}", error));
|
cx.editor.set_error(format!("{}", error));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
|
use crate::config::{Config, ConfigLoadError};
|
||||||
use crossterm::{
|
use crossterm::{
|
||||||
style::{Color, Print, Stylize},
|
style::{Color, Print, Stylize},
|
||||||
tty::IsTty,
|
tty::IsTty,
|
||||||
};
|
};
|
||||||
use helix_core::config::{default_lang_config, user_lang_config};
|
use helix_core::config::{default_lang_config, user_lang_config};
|
||||||
use helix_loader::grammar::load_runtime_file;
|
use helix_loader::grammar::load_runtime_file;
|
||||||
use helix_view::clipboard::get_clipboard_provider;
|
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
@ -53,7 +53,6 @@ pub fn general() -> std::io::Result<()> {
|
|||||||
let lang_file = helix_loader::lang_config_file();
|
let lang_file = helix_loader::lang_config_file();
|
||||||
let log_file = helix_loader::log_file();
|
let log_file = helix_loader::log_file();
|
||||||
let rt_dirs = helix_loader::runtime_dirs();
|
let rt_dirs = helix_loader::runtime_dirs();
|
||||||
let clipboard_provider = get_clipboard_provider();
|
|
||||||
|
|
||||||
if config_file.exists() {
|
if config_file.exists() {
|
||||||
writeln!(stdout, "Config file: {}", config_file.display())?;
|
writeln!(stdout, "Config file: {}", config_file.display())?;
|
||||||
@ -92,7 +91,6 @@ pub fn general() -> std::io::Result<()> {
|
|||||||
writeln!(stdout, "{}", msg.yellow())?;
|
writeln!(stdout, "{}", msg.yellow())?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
writeln!(stdout, "Clipboard provider: {}", clipboard_provider.name())?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -101,8 +99,19 @@ pub fn clipboard() -> std::io::Result<()> {
|
|||||||
let stdout = std::io::stdout();
|
let stdout = std::io::stdout();
|
||||||
let mut stdout = stdout.lock();
|
let mut stdout = stdout.lock();
|
||||||
|
|
||||||
let board = get_clipboard_provider();
|
let config = match Config::load_default() {
|
||||||
match board.name().as_ref() {
|
Ok(config) => config,
|
||||||
|
Err(ConfigLoadError::Error(err)) if err.kind() == std::io::ErrorKind::NotFound => {
|
||||||
|
Config::default()
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
writeln!(stdout, "{}", "Configuration file malformed".red())?;
|
||||||
|
writeln!(stdout, "{}", err)?;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match config.editor.clipboard_provider.name().as_ref() {
|
||||||
"none" => {
|
"none" => {
|
||||||
writeln!(
|
writeln!(
|
||||||
stdout,
|
stdout,
|
||||||
|
@ -19,7 +19,7 @@ tokio = { version = "1", features = ["rt", "rt-multi-thread", "time", "sync", "p
|
|||||||
parking_lot = "0.12"
|
parking_lot = "0.12"
|
||||||
arc-swap = { version = "1.7.1" }
|
arc-swap = { version = "1.7.1" }
|
||||||
|
|
||||||
gix = { version = "0.67.0", features = ["attributes", "status"], default-features = false, optional = true }
|
gix = { version = "0.67.0", features = ["attributes", "parallel", "status"], default-features = false, optional = true }
|
||||||
imara-diff = "0.1.7"
|
imara-diff = "0.1.7"
|
||||||
anyhow = "1"
|
anyhow = "1"
|
||||||
|
|
||||||
|
@ -22,22 +22,12 @@
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test;
|
mod test;
|
||||||
|
|
||||||
#[inline]
|
pub fn get_diff_base(repo: &ThreadSafeRepository, file: &Path) -> Result<Vec<u8>> {
|
||||||
fn get_repo_dir(file: &Path) -> Result<&Path> {
|
|
||||||
file.parent().context("file has no parent directory")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_diff_base(file: &Path) -> Result<Vec<u8>> {
|
|
||||||
debug_assert!(!file.exists() || file.is_file());
|
debug_assert!(!file.exists() || file.is_file());
|
||||||
debug_assert!(file.is_absolute());
|
debug_assert!(file.is_absolute());
|
||||||
let file = gix::path::realpath(file).context("resolve symlinks")?;
|
let file = gix::path::realpath(file).context("resolve symlink")?;
|
||||||
|
|
||||||
// TODO cache repository lookup
|
let repo = repo.to_thread_local();
|
||||||
|
|
||||||
let repo_dir = get_repo_dir(&file)?;
|
|
||||||
let repo = open_repo(repo_dir)
|
|
||||||
.context("failed to open git repo")?
|
|
||||||
.to_thread_local();
|
|
||||||
let head = repo.head_commit()?;
|
let head = repo.head_commit()?;
|
||||||
let file_oid = find_file_in_commit(&repo, &head, &file)?;
|
let file_oid = find_file_in_commit(&repo, &head, &file)?;
|
||||||
|
|
||||||
@ -59,15 +49,8 @@ pub fn get_diff_base(file: &Path) -> Result<Vec<u8>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_current_head_name(file: &Path) -> Result<Arc<ArcSwap<Box<str>>>> {
|
pub fn get_current_head_name(repo: &ThreadSafeRepository) -> Result<Arc<ArcSwap<Box<str>>>> {
|
||||||
debug_assert!(!file.exists() || file.is_file());
|
let repo = repo.to_thread_local();
|
||||||
debug_assert!(file.is_absolute());
|
|
||||||
let file = gix::path::realpath(file).context("resolve symlinks")?;
|
|
||||||
|
|
||||||
let repo_dir = get_repo_dir(&file)?;
|
|
||||||
let repo = open_repo(repo_dir)
|
|
||||||
.context("failed to open git repo")?
|
|
||||||
.to_thread_local();
|
|
||||||
let head_ref = repo.head_ref()?;
|
let head_ref = repo.head_ref()?;
|
||||||
let head_commit = repo.head_commit()?;
|
let head_commit = repo.head_commit()?;
|
||||||
|
|
||||||
@ -79,11 +62,17 @@ pub fn get_current_head_name(file: &Path) -> Result<Arc<ArcSwap<Box<str>>>> {
|
|||||||
Ok(Arc::new(ArcSwap::from_pointee(name.into_boxed_str())))
|
Ok(Arc::new(ArcSwap::from_pointee(name.into_boxed_str())))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn for_each_changed_file(cwd: &Path, f: impl Fn(Result<FileChange>) -> bool) -> Result<()> {
|
pub fn for_each_changed_file(
|
||||||
status(&open_repo(cwd)?.to_thread_local(), f)
|
repo: &ThreadSafeRepository,
|
||||||
|
f: impl Fn(Result<FileChange>) -> bool,
|
||||||
|
) -> Result<()> {
|
||||||
|
status(&repo.to_thread_local(), f)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_repo(path: &Path) -> Result<ThreadSafeRepository> {
|
pub(super) fn open_repo(path: &Path) -> Result<ThreadSafeRepository> {
|
||||||
|
// Ensure the repo itself is an absolute real path, else we'll not match prefixes with
|
||||||
|
// symlink-resolved files in `get_diff_base()` above.
|
||||||
|
let path = gix::path::realpath(path)?;
|
||||||
// custom open options
|
// custom open options
|
||||||
let mut git_open_opts_map = gix::sec::trust::Mapping::<gix::open::Options>::default();
|
let mut git_open_opts_map = gix::sec::trust::Mapping::<gix::open::Options>::default();
|
||||||
|
|
||||||
|
@ -54,7 +54,8 @@ fn missing_file() {
|
|||||||
let file = temp_git.path().join("file.txt");
|
let file = temp_git.path().join("file.txt");
|
||||||
File::create(&file).unwrap().write_all(b"foo").unwrap();
|
File::create(&file).unwrap().write_all(b"foo").unwrap();
|
||||||
|
|
||||||
assert!(git::get_diff_base(&file).is_err());
|
let repo = git::open_repo(temp_git.path()).unwrap();
|
||||||
|
assert!(git::get_diff_base(&repo, &file).is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -64,7 +65,12 @@ fn unmodified_file() {
|
|||||||
let contents = b"foo".as_slice();
|
let contents = b"foo".as_slice();
|
||||||
File::create(&file).unwrap().write_all(contents).unwrap();
|
File::create(&file).unwrap().write_all(contents).unwrap();
|
||||||
create_commit(temp_git.path(), true);
|
create_commit(temp_git.path(), true);
|
||||||
assert_eq!(git::get_diff_base(&file).unwrap(), Vec::from(contents));
|
|
||||||
|
let repo = git::open_repo(temp_git.path()).unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
git::get_diff_base(&repo, &file).unwrap(),
|
||||||
|
Vec::from(contents)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -76,7 +82,11 @@ fn modified_file() {
|
|||||||
create_commit(temp_git.path(), true);
|
create_commit(temp_git.path(), true);
|
||||||
File::create(&file).unwrap().write_all(b"bar").unwrap();
|
File::create(&file).unwrap().write_all(b"bar").unwrap();
|
||||||
|
|
||||||
assert_eq!(git::get_diff_base(&file).unwrap(), Vec::from(contents));
|
let repo = git::open_repo(temp_git.path()).unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
git::get_diff_base(&repo, &file).unwrap(),
|
||||||
|
Vec::from(contents)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Test that `get_file_head` does not return content for a directory.
|
/// Test that `get_file_head` does not return content for a directory.
|
||||||
@ -95,7 +105,9 @@ fn directory() {
|
|||||||
|
|
||||||
std::fs::remove_dir_all(&dir).unwrap();
|
std::fs::remove_dir_all(&dir).unwrap();
|
||||||
File::create(&dir).unwrap().write_all(b"bar").unwrap();
|
File::create(&dir).unwrap().write_all(b"bar").unwrap();
|
||||||
assert!(git::get_diff_base(&dir).is_err());
|
|
||||||
|
let repo = git::open_repo(temp_git.path()).unwrap();
|
||||||
|
assert!(git::get_diff_base(&repo, &dir).is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Test that `get_diff_base` resolves symlinks so that the same diff base is
|
/// Test that `get_diff_base` resolves symlinks so that the same diff base is
|
||||||
@ -122,8 +134,9 @@ fn symlink() {
|
|||||||
symlink("file.txt", &file_link).unwrap();
|
symlink("file.txt", &file_link).unwrap();
|
||||||
create_commit(temp_git.path(), true);
|
create_commit(temp_git.path(), true);
|
||||||
|
|
||||||
assert_eq!(git::get_diff_base(&file_link).unwrap(), contents);
|
let repo = git::open_repo(temp_git.path()).unwrap();
|
||||||
assert_eq!(git::get_diff_base(&file).unwrap(), contents);
|
assert_eq!(git::get_diff_base(&repo, &file_link).unwrap(), contents);
|
||||||
|
assert_eq!(git::get_diff_base(&repo, &file).unwrap(), contents);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Test that `get_diff_base` returns content when the file is a symlink to
|
/// Test that `get_diff_base` returns content when the file is a symlink to
|
||||||
@ -147,6 +160,7 @@ fn symlink_to_git_repo() {
|
|||||||
let file_link = temp_dir.path().join("file_link.txt");
|
let file_link = temp_dir.path().join("file_link.txt");
|
||||||
symlink(&file, &file_link).unwrap();
|
symlink(&file, &file_link).unwrap();
|
||||||
|
|
||||||
assert_eq!(git::get_diff_base(&file_link).unwrap(), contents);
|
let repo = git::open_repo(temp_git.path()).unwrap();
|
||||||
assert_eq!(git::get_diff_base(&file).unwrap(), contents);
|
assert_eq!(git::get_diff_base(&repo, &file_link).unwrap(), contents);
|
||||||
|
assert_eq!(git::get_diff_base(&repo, &file).unwrap(), contents);
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
use anyhow::{anyhow, bail, Result};
|
use anyhow::Result;
|
||||||
use arc_swap::ArcSwap;
|
use arc_swap::ArcSwap;
|
||||||
use std::{
|
use std::{collections::HashMap, path::Path, sync::Arc};
|
||||||
path::{Path, PathBuf},
|
|
||||||
sync::Arc,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[cfg(feature = "git")]
|
#[cfg(feature = "git")]
|
||||||
mod git;
|
mod git;
|
||||||
@ -16,67 +13,182 @@
|
|||||||
|
|
||||||
pub use status::FileChange;
|
pub use status::FileChange;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Default, Clone)]
|
||||||
pub struct DiffProviderRegistry {
|
pub struct DiffProviderRegistry {
|
||||||
providers: Vec<DiffProvider>,
|
/// Repository root path mapped to their provider.
|
||||||
|
///
|
||||||
|
/// When a root path cannot be found after having called `add_file`, it means there is no
|
||||||
|
/// provider to speak of.
|
||||||
|
providers: HashMap<Arc<Path>, DiffProvider>,
|
||||||
|
/// Count the number of files added for a specific provider path.
|
||||||
|
/// Providers themselves don't care about that, this is handled entirely in `Self::add_file`,
|
||||||
|
/// without knowledge from the `Self::add_file_<provider>` methods.
|
||||||
|
///
|
||||||
|
/// Note: it *could* happen that a provider for a path is changed without the number of
|
||||||
|
/// associated files changing, e.g deleting a .git/ and initializing a .jj/ repo.
|
||||||
|
counters: HashMap<Arc<Path>, u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Diff-related methods
|
||||||
impl DiffProviderRegistry {
|
impl DiffProviderRegistry {
|
||||||
pub fn get_diff_base(&self, file: &Path) -> Option<Vec<u8>> {
|
pub fn get_diff_base(&self, file: &Path) -> Option<Vec<u8>> {
|
||||||
self.providers
|
match self.provider_for(file)?.get_diff_base(file) {
|
||||||
.iter()
|
Ok(diff_base) => Some(diff_base),
|
||||||
.find_map(|provider| match provider.get_diff_base(file) {
|
|
||||||
Ok(res) => Some(res),
|
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
log::debug!("{err:#?}");
|
log::debug!("{err:#?}");
|
||||||
log::debug!("failed to open diff base for {}", file.display());
|
log::debug!("failed to open diff base for {}", file.display());
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_current_head_name(&self, file: &Path) -> Option<Arc<ArcSwap<Box<str>>>> {
|
pub fn get_current_head_name(&self, file: &Path) -> Option<Arc<ArcSwap<Box<str>>>> {
|
||||||
self.providers
|
match self.provider_for(file)?.get_current_head_name() {
|
||||||
.iter()
|
Ok(head_name) => Some(head_name),
|
||||||
.find_map(|provider| match provider.get_current_head_name(file) {
|
|
||||||
Ok(res) => Some(res),
|
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
log::debug!("{err:#?}");
|
log::debug!("{err:#?}");
|
||||||
log::debug!("failed to obtain current head name for {}", file.display());
|
log::debug!("failed to obtain current head name for {}", file.display());
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fire-and-forget changed file iteration. Runs everything in a background task. Keeps
|
/// Fire-and-forget changed file iteration. Runs everything in a background task. Keeps
|
||||||
/// iteration until `on_change` returns `false`.
|
/// iteration until `on_change` returns `false`.
|
||||||
pub fn for_each_changed_file(
|
pub fn for_each_changed_file(
|
||||||
self,
|
self,
|
||||||
cwd: PathBuf,
|
cwd: Arc<Path>,
|
||||||
f: impl Fn(Result<FileChange>) -> bool + Send + 'static,
|
f: impl Fn(Result<FileChange>) -> bool + Send + 'static,
|
||||||
) {
|
) {
|
||||||
tokio::task::spawn_blocking(move || {
|
tokio::task::spawn_blocking(move || {
|
||||||
if self
|
let Some(diff_provider) = self.provider_for(&cwd) else {
|
||||||
.providers
|
return;
|
||||||
.iter()
|
};
|
||||||
.find_map(|provider| provider.for_each_changed_file(&cwd, &f).ok())
|
if let Err(err) = diff_provider.for_each_changed_file(&f) {
|
||||||
.is_none()
|
f(Err(err));
|
||||||
{
|
|
||||||
f(Err(anyhow!("no diff provider returns success")));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for DiffProviderRegistry {
|
/// Creation and update methods
|
||||||
fn default() -> Self {
|
#[cfg_attr(not(feature = "git"), allow(unused))]
|
||||||
// currently only git is supported
|
impl DiffProviderRegistry {
|
||||||
// TODO make this configurable when more providers are added
|
/// Register a provider (if any is found) for the given path.
|
||||||
let providers = vec![
|
pub fn add(&mut self, path: &Path) {
|
||||||
|
let Some((repo_path, provider)) = get_possible_provider(path) else {
|
||||||
|
// Do nothing here: there is no path to use and so the actual methods to get infos
|
||||||
|
// like `get_diff_base` just won't do anything since they won't find a source to
|
||||||
|
// work with.
|
||||||
|
log::debug!("Found no potential diff provider for {}", path.display());
|
||||||
|
// Note: if a `.<vcs>/` dir is deleted, we may end up in a situation where we lose track
|
||||||
|
// of a now unused provider. This is acceptable because it doesn't happen that often in
|
||||||
|
// practice and people can just reload to force an update.
|
||||||
|
//
|
||||||
|
// If it becomes an issue in the future, we could fix it by recomputing the providers
|
||||||
|
// for each stored paths here.
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = match provider {
|
||||||
#[cfg(feature = "git")]
|
#[cfg(feature = "git")]
|
||||||
DiffProvider::Git,
|
PossibleDiffProvider::Git => self.add_file_git(repo_path),
|
||||||
];
|
};
|
||||||
DiffProviderRegistry { providers }
|
|
||||||
|
match result {
|
||||||
|
Ok((key, prov)) => {
|
||||||
|
// Increase the count for this path.
|
||||||
|
let count = self.counters.entry(key).or_default();
|
||||||
|
let created = *count == 0;
|
||||||
|
*count += 1;
|
||||||
|
|
||||||
|
// Only log at info level when adding a new provider
|
||||||
|
if created {
|
||||||
|
log::info!(
|
||||||
|
"Added {prov:?} (repo: {}) from {}",
|
||||||
|
repo_path.display(),
|
||||||
|
path.display()
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
log::debug!(
|
||||||
|
"Reused {prov:?} (repo: {}) for {}",
|
||||||
|
repo_path.display(),
|
||||||
|
path.display()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(err) => log::debug!(
|
||||||
|
"Failed to open repo at {} for {}: {:?}",
|
||||||
|
repo_path.display(),
|
||||||
|
path.display(),
|
||||||
|
err
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reload the provider for the given path.
|
||||||
|
pub fn reload(&mut self, path: &Path) {
|
||||||
|
self.remove(path);
|
||||||
|
self.add(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Remove the given path from the provider cache. If it was the last one using it, this will
|
||||||
|
/// free up the provider.
|
||||||
|
pub fn remove(&mut self, path: &Path) {
|
||||||
|
let Some((repo_path, _)) = get_possible_provider(path) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let Some(count) = self.counters.get_mut(repo_path) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
*count -= 1;
|
||||||
|
if *count == 0 {
|
||||||
|
// Cleanup the provider when the last user disappears
|
||||||
|
self.counters.remove(repo_path);
|
||||||
|
self.providers.remove(repo_path);
|
||||||
|
|
||||||
|
// While reallocating is costly, in most sessions of Helix there will be one main
|
||||||
|
// workspace and sometimes a jump to some temporary one (for example from a jump-to-def
|
||||||
|
// in an LSP) that will be closed after some time. We want to avoid keeping unused
|
||||||
|
// RAM for this.
|
||||||
|
self.providers.shrink_to_fit();
|
||||||
|
self.counters.shrink_to_fit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Clears the saved providers completely.
|
||||||
|
pub fn reset(&mut self) {
|
||||||
|
self.providers = Default::default();
|
||||||
|
self.counters = Default::default();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Private methods
|
||||||
|
impl DiffProviderRegistry {
|
||||||
|
fn provider_for(&self, path: &Path) -> Option<&DiffProvider> {
|
||||||
|
let path = get_possible_provider(path)?.0;
|
||||||
|
self.providers.get(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add the git repo to the known providers *if* it isn't already known.
|
||||||
|
#[cfg(feature = "git")]
|
||||||
|
fn add_file_git(&mut self, repo_path: &Path) -> Result<(Arc<Path>, PossibleDiffProvider)> {
|
||||||
|
// Don't build a git repo object if there is already one for that path.
|
||||||
|
if let Some((key, DiffProvider::Git(_))) = self.providers.get_key_value(repo_path) {
|
||||||
|
return Ok((Arc::clone(key), PossibleDiffProvider::Git));
|
||||||
|
}
|
||||||
|
|
||||||
|
match git::open_repo(repo_path) {
|
||||||
|
Ok(repo) => {
|
||||||
|
let key = Arc::from(repo_path);
|
||||||
|
self.providers
|
||||||
|
.insert(Arc::clone(&key), DiffProvider::Git(repo));
|
||||||
|
Ok((key, PossibleDiffProvider::Git))
|
||||||
|
}
|
||||||
|
Err(err) => Err(err),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,39 +196,67 @@ fn default() -> Self {
|
|||||||
/// cloning [DiffProviderRegistry] as `Clone` cannot be used in trait objects.
|
/// cloning [DiffProviderRegistry] as `Clone` cannot be used in trait objects.
|
||||||
///
|
///
|
||||||
/// `Copy` is simply to ensure the `clone()` call is the simplest it can be.
|
/// `Copy` is simply to ensure the `clone()` call is the simplest it can be.
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Clone)]
|
||||||
pub enum DiffProvider {
|
pub enum DiffProvider {
|
||||||
#[cfg(feature = "git")]
|
#[cfg(feature = "git")]
|
||||||
Git,
|
Git(gix::ThreadSafeRepository),
|
||||||
None,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(not(feature = "git"), allow(unused))]
|
||||||
impl DiffProvider {
|
impl DiffProvider {
|
||||||
fn get_diff_base(&self, file: &Path) -> Result<Vec<u8>> {
|
fn get_diff_base(&self, file: &Path) -> Result<Vec<u8>> {
|
||||||
match self {
|
// We need the */ref else we're matching on a reference and Rust considers all references
|
||||||
|
// inhabited. In our case
|
||||||
|
match *self {
|
||||||
#[cfg(feature = "git")]
|
#[cfg(feature = "git")]
|
||||||
Self::Git => git::get_diff_base(file),
|
Self::Git(ref repo) => git::get_diff_base(repo, file),
|
||||||
Self::None => bail!("No diff support compiled in"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_current_head_name(&self, file: &Path) -> Result<Arc<ArcSwap<Box<str>>>> {
|
fn get_current_head_name(&self) -> Result<Arc<ArcSwap<Box<str>>>> {
|
||||||
match self {
|
match *self {
|
||||||
#[cfg(feature = "git")]
|
#[cfg(feature = "git")]
|
||||||
Self::Git => git::get_current_head_name(file),
|
Self::Git(ref repo) => git::get_current_head_name(repo),
|
||||||
Self::None => bail!("No diff support compiled in"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn for_each_changed_file(
|
fn for_each_changed_file(&self, f: impl Fn(Result<FileChange>) -> bool) -> Result<()> {
|
||||||
&self,
|
match *self {
|
||||||
cwd: &Path,
|
|
||||||
f: impl Fn(Result<FileChange>) -> bool,
|
|
||||||
) -> Result<()> {
|
|
||||||
match self {
|
|
||||||
#[cfg(feature = "git")]
|
#[cfg(feature = "git")]
|
||||||
Self::Git => git::for_each_changed_file(cwd, f),
|
Self::Git(ref repo) => git::for_each_changed_file(repo, f),
|
||||||
Self::None => bail!("No diff support compiled in"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub enum PossibleDiffProvider {
|
||||||
|
/// Possibly a git repo rooted at the stored path (i.e. `<path>/.git` exists)
|
||||||
|
#[cfg(feature = "git")]
|
||||||
|
Git,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Does *possible* diff provider auto detection. Returns the 'root' of the workspace
|
||||||
|
///
|
||||||
|
/// We say possible because this function doesn't open the actual repository to check if that's
|
||||||
|
/// actually the case.
|
||||||
|
fn get_possible_provider(path: &Path) -> Option<(&Path, PossibleDiffProvider)> {
|
||||||
|
if cfg!(feature = "git") {
|
||||||
|
#[cfg_attr(not(feature = "git"), allow(unused))]
|
||||||
|
fn check_path(path: &Path) -> Option<(&Path, PossibleDiffProvider)> {
|
||||||
|
#[cfg(feature = "git")]
|
||||||
|
if path.join(".git").try_exists().ok()? {
|
||||||
|
return Some((path, PossibleDiffProvider::Git));
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
for parent in path.ancestors() {
|
||||||
|
if let Some(path_and_provider) = check_path(parent) {
|
||||||
|
return Some(path_and_provider);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
@ -1,164 +1,408 @@
|
|||||||
// Implementation reference: https://github.com/neovim/neovim/blob/f2906a4669a2eef6d7bf86a29648793d63c98949/runtime/autoload/provider/clipboard.vim#L68-L152
|
// Implementation reference: https://github.com/neovim/neovim/blob/f2906a4669a2eef6d7bf86a29648793d63c98949/runtime/autoload/provider/clipboard.vim#L68-L152
|
||||||
|
|
||||||
use anyhow::Result;
|
use serde::{Deserialize, Serialize};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy)]
|
||||||
pub enum ClipboardType {
|
pub enum ClipboardType {
|
||||||
Clipboard,
|
Clipboard,
|
||||||
Selection,
|
Selection,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ClipboardProvider: std::fmt::Debug {
|
#[derive(Debug, Error)]
|
||||||
fn name(&self) -> Cow<str>;
|
pub enum ClipboardError {
|
||||||
fn get_contents(&self, clipboard_type: ClipboardType) -> Result<String>;
|
#[error(transparent)]
|
||||||
fn set_contents(&mut self, contents: String, clipboard_type: ClipboardType) -> Result<()>;
|
IoError(#[from] std::io::Error),
|
||||||
|
#[error("could not convert terminal output to UTF-8: {0}")]
|
||||||
|
FromUtf8Error(#[from] std::string::FromUtf8Error),
|
||||||
|
#[cfg(windows)]
|
||||||
|
#[error("Windows API error: {0}")]
|
||||||
|
WinAPI(#[from] clipboard_win::ErrorCode),
|
||||||
|
#[error("clipboard provider command failed")]
|
||||||
|
CommandFailed,
|
||||||
|
#[error("failed to write to clipboard provider's stdin")]
|
||||||
|
StdinWriteFailed,
|
||||||
|
#[error("clipboard provider did not return any contents")]
|
||||||
|
MissingStdout,
|
||||||
|
#[error("This clipboard provider does not support reading")]
|
||||||
|
ReadingNotSupported,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(windows))]
|
type Result<T> = std::result::Result<T, ClipboardError>;
|
||||||
macro_rules! command_provider {
|
|
||||||
(paste => $get_prg:literal $( , $get_arg:literal )* ; copy => $set_prg:literal $( , $set_arg:literal )* ; ) => {{
|
|
||||||
log::debug!(
|
|
||||||
"Using {} to interact with the system clipboard",
|
|
||||||
if $set_prg != $get_prg { format!("{}+{}", $set_prg, $get_prg)} else { $set_prg.to_string() }
|
|
||||||
);
|
|
||||||
Box::new(provider::command::Provider {
|
|
||||||
get_cmd: provider::command::Config {
|
|
||||||
prg: $get_prg,
|
|
||||||
args: &[ $( $get_arg ),* ],
|
|
||||||
},
|
|
||||||
set_cmd: provider::command::Config {
|
|
||||||
prg: $set_prg,
|
|
||||||
args: &[ $( $set_arg ),* ],
|
|
||||||
},
|
|
||||||
get_primary_cmd: None,
|
|
||||||
set_primary_cmd: None,
|
|
||||||
})
|
|
||||||
}};
|
|
||||||
|
|
||||||
(paste => $get_prg:literal $( , $get_arg:literal )* ;
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
copy => $set_prg:literal $( , $set_arg:literal )* ;
|
pub use external::ClipboardProvider;
|
||||||
primary_paste => $pr_get_prg:literal $( , $pr_get_arg:literal )* ;
|
#[cfg(target_arch = "wasm32")]
|
||||||
primary_copy => $pr_set_prg:literal $( , $pr_set_arg:literal )* ;
|
pub use noop::ClipboardProvider;
|
||||||
) => {{
|
|
||||||
log::debug!(
|
// Clipboard not supported for wasm
|
||||||
"Using {} to interact with the system and selection (primary) clipboard",
|
#[cfg(target_arch = "wasm32")]
|
||||||
if $set_prg != $get_prg { format!("{}+{}", $set_prg, $get_prg)} else { $set_prg.to_string() }
|
mod noop {
|
||||||
);
|
use super::*;
|
||||||
Box::new(provider::command::Provider {
|
|
||||||
get_cmd: provider::command::Config {
|
#[derive(Debug, Clone)]
|
||||||
prg: $get_prg,
|
pub enum ClipboardProvider {}
|
||||||
args: &[ $( $get_arg ),* ],
|
|
||||||
},
|
impl ClipboardProvider {
|
||||||
set_cmd: provider::command::Config {
|
pub fn detect() -> Self {
|
||||||
prg: $set_prg,
|
Self
|
||||||
args: &[ $( $set_arg ),* ],
|
}
|
||||||
},
|
|
||||||
get_primary_cmd: Some(provider::command::Config {
|
pub fn name(&self) -> Cow<str> {
|
||||||
prg: $pr_get_prg,
|
"none".into()
|
||||||
args: &[ $( $pr_get_arg ),* ],
|
}
|
||||||
}),
|
|
||||||
set_primary_cmd: Some(provider::command::Config {
|
pub fn get_contents(&self, _clipboard_type: ClipboardType) -> Result<String> {
|
||||||
prg: $pr_set_prg,
|
Err(ClipboardError::ReadingNotSupported)
|
||||||
args: &[ $( $pr_set_arg ),* ],
|
}
|
||||||
}),
|
|
||||||
})
|
pub fn set_contents(&self, _content: &str, _clipboard_type: ClipboardType) -> Result<()> {
|
||||||
}};
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
pub fn get_clipboard_provider() -> Box<dyn ClipboardProvider> {
|
mod external {
|
||||||
Box::<provider::WindowsProvider>::default()
|
use super::*;
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||||
pub fn get_clipboard_provider() -> Box<dyn ClipboardProvider> {
|
pub struct Command {
|
||||||
|
command: Cow<'static, str>,
|
||||||
|
#[serde(default)]
|
||||||
|
args: Cow<'static, [Cow<'static, str>]>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||||
|
#[serde(rename_all = "kebab-case")]
|
||||||
|
pub struct CommandProvider {
|
||||||
|
yank: Command,
|
||||||
|
paste: Command,
|
||||||
|
yank_primary: Option<Command>,
|
||||||
|
paste_primary: Option<Command>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||||
|
#[serde(rename_all = "kebab-case")]
|
||||||
|
#[allow(clippy::large_enum_variant)]
|
||||||
|
pub enum ClipboardProvider {
|
||||||
|
Pasteboard,
|
||||||
|
Wayland,
|
||||||
|
XClip,
|
||||||
|
XSel,
|
||||||
|
Win32Yank,
|
||||||
|
Tmux,
|
||||||
|
#[cfg(windows)]
|
||||||
|
Windows,
|
||||||
|
Termux,
|
||||||
|
#[cfg(feature = "term")]
|
||||||
|
Termcode,
|
||||||
|
Custom(CommandProvider),
|
||||||
|
None,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ClipboardProvider {
|
||||||
|
#[cfg(windows)]
|
||||||
|
fn default() -> Self {
|
||||||
|
use helix_stdx::env::binary_exists;
|
||||||
|
|
||||||
|
if binary_exists("win32yank.exe") {
|
||||||
|
Self::Win32Yank
|
||||||
|
} else {
|
||||||
|
Self::Windows
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
fn default() -> Self {
|
||||||
use helix_stdx::env::{binary_exists, env_var_is_set};
|
use helix_stdx::env::{binary_exists, env_var_is_set};
|
||||||
|
|
||||||
if env_var_is_set("TMUX") && binary_exists("tmux") {
|
if env_var_is_set("TMUX") && binary_exists("tmux") {
|
||||||
command_provider! {
|
Self::Tmux
|
||||||
paste => "tmux", "save-buffer", "-";
|
|
||||||
copy => "tmux", "load-buffer", "-w", "-";
|
|
||||||
}
|
|
||||||
} else if binary_exists("pbcopy") && binary_exists("pbpaste") {
|
} else if binary_exists("pbcopy") && binary_exists("pbpaste") {
|
||||||
command_provider! {
|
Self::Pasteboard
|
||||||
paste => "pbpaste";
|
} else if cfg!(feature = "term") {
|
||||||
copy => "pbcopy";
|
Self::Termcode
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
Box::new(provider::FallbackProvider::new())
|
Self::None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(not(any(windows, target_os = "macos")))]
|
||||||
pub fn get_clipboard_provider() -> Box<dyn ClipboardProvider> {
|
fn default() -> Self {
|
||||||
// TODO:
|
|
||||||
Box::new(provider::FallbackProvider::new())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(any(windows, target_arch = "wasm32", target_os = "macos")))]
|
|
||||||
pub fn get_clipboard_provider() -> Box<dyn ClipboardProvider> {
|
|
||||||
use helix_stdx::env::{binary_exists, env_var_is_set};
|
use helix_stdx::env::{binary_exists, env_var_is_set};
|
||||||
use provider::command::is_exit_success;
|
|
||||||
// TODO: support for user-defined provider, probably when we have plugin support by setting a
|
|
||||||
// variable?
|
|
||||||
|
|
||||||
if env_var_is_set("WAYLAND_DISPLAY") && binary_exists("wl-copy") && binary_exists("wl-paste") {
|
fn is_exit_success(program: &str, args: &[&str]) -> bool {
|
||||||
command_provider! {
|
std::process::Command::new(program)
|
||||||
paste => "wl-paste", "--no-newline";
|
.args(args)
|
||||||
copy => "wl-copy", "--type", "text/plain";
|
.output()
|
||||||
primary_paste => "wl-paste", "-p", "--no-newline";
|
.ok()
|
||||||
primary_copy => "wl-copy", "-p", "--type", "text/plain";
|
.and_then(|out| out.status.success().then_some(()))
|
||||||
|
.is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if env_var_is_set("WAYLAND_DISPLAY")
|
||||||
|
&& binary_exists("wl-copy")
|
||||||
|
&& binary_exists("wl-paste")
|
||||||
|
{
|
||||||
|
Self::Wayland
|
||||||
} else if env_var_is_set("DISPLAY") && binary_exists("xclip") {
|
} else if env_var_is_set("DISPLAY") && binary_exists("xclip") {
|
||||||
command_provider! {
|
Self::XClip
|
||||||
paste => "xclip", "-o", "-selection", "clipboard";
|
|
||||||
copy => "xclip", "-i", "-selection", "clipboard";
|
|
||||||
primary_paste => "xclip", "-o";
|
|
||||||
primary_copy => "xclip", "-i";
|
|
||||||
}
|
|
||||||
} else if env_var_is_set("DISPLAY")
|
} else if env_var_is_set("DISPLAY")
|
||||||
&& binary_exists("xsel")
|
&& binary_exists("xsel")
|
||||||
|
// FIXME: check performance of is_exit_success
|
||||||
&& is_exit_success("xsel", &["-o", "-b"])
|
&& is_exit_success("xsel", &["-o", "-b"])
|
||||||
{
|
{
|
||||||
// FIXME: check performance of is_exit_success
|
Self::XSel
|
||||||
command_provider! {
|
} else if binary_exists("termux-clipboard-set") && binary_exists("termux-clipboard-get")
|
||||||
paste => "xsel", "-o", "-b";
|
{
|
||||||
copy => "xsel", "-i", "-b";
|
Self::Termux
|
||||||
primary_paste => "xsel", "-o";
|
|
||||||
primary_copy => "xsel", "-i";
|
|
||||||
}
|
|
||||||
} else if binary_exists("win32yank.exe") {
|
|
||||||
command_provider! {
|
|
||||||
paste => "win32yank.exe", "-o", "--lf";
|
|
||||||
copy => "win32yank.exe", "-i", "--crlf";
|
|
||||||
}
|
|
||||||
} else if binary_exists("termux-clipboard-set") && binary_exists("termux-clipboard-get") {
|
|
||||||
command_provider! {
|
|
||||||
paste => "termux-clipboard-get";
|
|
||||||
copy => "termux-clipboard-set";
|
|
||||||
}
|
|
||||||
} else if env_var_is_set("TMUX") && binary_exists("tmux") {
|
} else if env_var_is_set("TMUX") && binary_exists("tmux") {
|
||||||
command_provider! {
|
Self::Tmux
|
||||||
paste => "tmux", "save-buffer", "-";
|
} else if binary_exists("win32yank.exe") {
|
||||||
copy => "tmux", "load-buffer", "-w", "-";
|
Self::Win32Yank
|
||||||
}
|
} else if cfg!(feature = "term") {
|
||||||
|
Self::Termcode
|
||||||
} else {
|
} else {
|
||||||
Box::new(provider::FallbackProvider::new())
|
Self::None
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(target_os = "windows"))]
|
impl ClipboardProvider {
|
||||||
pub mod provider {
|
pub fn name(&self) -> Cow<'_, str> {
|
||||||
use super::{ClipboardProvider, ClipboardType};
|
fn builtin_name<'a>(
|
||||||
use anyhow::Result;
|
name: &'static str,
|
||||||
use std::borrow::Cow;
|
provider: &'static CommandProvider,
|
||||||
|
) -> Cow<'a, str> {
|
||||||
|
if provider.yank.command != provider.paste.command {
|
||||||
|
Cow::Owned(format!(
|
||||||
|
"{} ({}+{})",
|
||||||
|
name, provider.yank.command, provider.paste.command
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
Cow::Owned(format!("{} ({})", name, provider.yank.command))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match self {
|
||||||
|
// These names should match the config option names from Serde
|
||||||
|
Self::Pasteboard => builtin_name("pasteboard", &PASTEBOARD),
|
||||||
|
Self::Wayland => builtin_name("wayland", &WL_CLIPBOARD),
|
||||||
|
Self::XClip => builtin_name("x-clip", &XCLIP),
|
||||||
|
Self::XSel => builtin_name("x-sel", &XSEL),
|
||||||
|
Self::Win32Yank => builtin_name("win-32-yank", &WIN32),
|
||||||
|
Self::Tmux => builtin_name("tmux", &TMUX),
|
||||||
|
Self::Termux => builtin_name("termux", &TERMUX),
|
||||||
|
#[cfg(windows)]
|
||||||
|
Self::Windows => "windows".into(),
|
||||||
|
#[cfg(feature = "term")]
|
||||||
|
Self::Termcode => "termcode".into(),
|
||||||
|
Self::Custom(command_provider) => Cow::Owned(format!(
|
||||||
|
"custom ({}+{})",
|
||||||
|
command_provider.yank.command, command_provider.paste.command
|
||||||
|
)),
|
||||||
|
Self::None => "none".into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_contents(&self, clipboard_type: &ClipboardType) -> Result<String> {
|
||||||
|
fn yank_from_builtin(
|
||||||
|
provider: CommandProvider,
|
||||||
|
clipboard_type: &ClipboardType,
|
||||||
|
) -> Result<String> {
|
||||||
|
match clipboard_type {
|
||||||
|
ClipboardType::Clipboard => execute_command(&provider.yank, None, true)?
|
||||||
|
.ok_or(ClipboardError::MissingStdout),
|
||||||
|
ClipboardType::Selection => {
|
||||||
|
if let Some(cmd) = provider.yank_primary.as_ref() {
|
||||||
|
return execute_command(cmd, None, true)?
|
||||||
|
.ok_or(ClipboardError::MissingStdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(String::new())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match self {
|
||||||
|
Self::Pasteboard => yank_from_builtin(PASTEBOARD, clipboard_type),
|
||||||
|
Self::Wayland => yank_from_builtin(WL_CLIPBOARD, clipboard_type),
|
||||||
|
Self::XClip => yank_from_builtin(XCLIP, clipboard_type),
|
||||||
|
Self::XSel => yank_from_builtin(XSEL, clipboard_type),
|
||||||
|
Self::Win32Yank => yank_from_builtin(WIN32, clipboard_type),
|
||||||
|
Self::Tmux => yank_from_builtin(TMUX, clipboard_type),
|
||||||
|
Self::Termux => yank_from_builtin(TERMUX, clipboard_type),
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
Self::Windows => match clipboard_type {
|
||||||
|
ClipboardType::Clipboard => {
|
||||||
|
let contents =
|
||||||
|
clipboard_win::get_clipboard(clipboard_win::formats::Unicode)?;
|
||||||
|
Ok(contents)
|
||||||
|
}
|
||||||
|
ClipboardType::Selection => Ok(String::new()),
|
||||||
|
},
|
||||||
|
#[cfg(feature = "term")]
|
||||||
|
Self::Termcode => Err(ClipboardError::ReadingNotSupported),
|
||||||
|
Self::Custom(command_provider) => {
|
||||||
|
execute_command(&command_provider.yank, None, true)?
|
||||||
|
.ok_or(ClipboardError::MissingStdout)
|
||||||
|
}
|
||||||
|
Self::None => Err(ClipboardError::ReadingNotSupported),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_contents(&self, content: &str, clipboard_type: ClipboardType) -> Result<()> {
|
||||||
|
fn paste_to_builtin(
|
||||||
|
provider: CommandProvider,
|
||||||
|
content: &str,
|
||||||
|
clipboard_type: ClipboardType,
|
||||||
|
) -> Result<()> {
|
||||||
|
let cmd = match clipboard_type {
|
||||||
|
ClipboardType::Clipboard => &provider.paste,
|
||||||
|
ClipboardType::Selection => {
|
||||||
|
if let Some(cmd) = provider.paste_primary.as_ref() {
|
||||||
|
cmd
|
||||||
|
} else {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
execute_command(cmd, Some(content), false).map(|_| ())
|
||||||
|
}
|
||||||
|
|
||||||
|
match self {
|
||||||
|
Self::Pasteboard => paste_to_builtin(PASTEBOARD, content, clipboard_type),
|
||||||
|
Self::Wayland => paste_to_builtin(WL_CLIPBOARD, content, clipboard_type),
|
||||||
|
Self::XClip => paste_to_builtin(XCLIP, content, clipboard_type),
|
||||||
|
Self::XSel => paste_to_builtin(XSEL, content, clipboard_type),
|
||||||
|
Self::Win32Yank => paste_to_builtin(WIN32, content, clipboard_type),
|
||||||
|
Self::Tmux => paste_to_builtin(TMUX, content, clipboard_type),
|
||||||
|
Self::Termux => paste_to_builtin(TERMUX, content, clipboard_type),
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
Self::Windows => match clipboard_type {
|
||||||
|
ClipboardType::Clipboard => {
|
||||||
|
clipboard_win::set_clipboard(clipboard_win::formats::Unicode, content)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
ClipboardType::Selection => Ok(()),
|
||||||
|
},
|
||||||
|
#[cfg(feature = "term")]
|
||||||
|
Self::Termcode => {
|
||||||
|
crossterm::queue!(
|
||||||
|
std::io::stdout(),
|
||||||
|
osc52::SetClipboardCommand::new(content, clipboard_type)
|
||||||
|
)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Self::Custom(command_provider) => match clipboard_type {
|
||||||
|
ClipboardType::Clipboard => {
|
||||||
|
execute_command(&command_provider.paste, Some(content), false).map(|_| ())
|
||||||
|
}
|
||||||
|
ClipboardType::Selection => {
|
||||||
|
if let Some(cmd) = &command_provider.paste_primary {
|
||||||
|
execute_command(cmd, Some(content), false).map(|_| ())
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Self::None => Ok(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! command_provider {
|
||||||
|
($name:ident,
|
||||||
|
yank => $yank_cmd:literal $( , $yank_arg:literal )* ;
|
||||||
|
paste => $paste_cmd:literal $( , $paste_arg:literal )* ; ) => {
|
||||||
|
const $name: CommandProvider = CommandProvider {
|
||||||
|
yank: Command {
|
||||||
|
command: Cow::Borrowed($yank_cmd),
|
||||||
|
args: Cow::Borrowed(&[ $( Cow::Borrowed($yank_arg) ),* ])
|
||||||
|
},
|
||||||
|
paste: Command {
|
||||||
|
command: Cow::Borrowed($paste_cmd),
|
||||||
|
args: Cow::Borrowed(&[ $( Cow::Borrowed($paste_arg) ),* ])
|
||||||
|
},
|
||||||
|
yank_primary: None,
|
||||||
|
paste_primary: None,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
($name:ident,
|
||||||
|
yank => $yank_cmd:literal $( , $yank_arg:literal )* ;
|
||||||
|
paste => $paste_cmd:literal $( , $paste_arg:literal )* ;
|
||||||
|
yank_primary => $yank_primary_cmd:literal $( , $yank_primary_arg:literal )* ;
|
||||||
|
paste_primary => $paste_primary_cmd:literal $( , $paste_primary_arg:literal )* ; ) => {
|
||||||
|
const $name: CommandProvider = CommandProvider {
|
||||||
|
yank: Command {
|
||||||
|
command: Cow::Borrowed($yank_cmd),
|
||||||
|
args: Cow::Borrowed(&[ $( Cow::Borrowed($yank_arg) ),* ])
|
||||||
|
},
|
||||||
|
paste: Command {
|
||||||
|
command: Cow::Borrowed($paste_cmd),
|
||||||
|
args: Cow::Borrowed(&[ $( Cow::Borrowed($paste_arg) ),* ])
|
||||||
|
},
|
||||||
|
yank_primary: Some(Command {
|
||||||
|
command: Cow::Borrowed($yank_primary_cmd),
|
||||||
|
args: Cow::Borrowed(&[ $( Cow::Borrowed($yank_primary_arg) ),* ])
|
||||||
|
}),
|
||||||
|
paste_primary: Some(Command {
|
||||||
|
command: Cow::Borrowed($paste_primary_cmd),
|
||||||
|
args: Cow::Borrowed(&[ $( Cow::Borrowed($paste_primary_arg) ),* ])
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
command_provider! {
|
||||||
|
TMUX,
|
||||||
|
yank => "tmux", "save-buffer", "-";
|
||||||
|
paste => "tmux", "load-buffer", "-w", "-";
|
||||||
|
}
|
||||||
|
command_provider! {
|
||||||
|
PASTEBOARD,
|
||||||
|
yank => "pbpaste";
|
||||||
|
paste => "pbcopy";
|
||||||
|
}
|
||||||
|
command_provider! {
|
||||||
|
WL_CLIPBOARD,
|
||||||
|
yank => "wl-paste", "--no-newline";
|
||||||
|
paste => "wl-copy", "--type", "text/plain";
|
||||||
|
yank_primary => "wl-paste", "-p", "--no-newline";
|
||||||
|
paste_primary => "wl-copy", "-p", "--type", "text/plain";
|
||||||
|
}
|
||||||
|
command_provider! {
|
||||||
|
XCLIP,
|
||||||
|
yank => "xclip", "-o", "-selection", "clipboard";
|
||||||
|
paste => "xclip", "-i", "-selection", "clipboard";
|
||||||
|
yank_primary => "xclip", "-o";
|
||||||
|
paste_primary => "xclip", "-i";
|
||||||
|
}
|
||||||
|
command_provider! {
|
||||||
|
XSEL,
|
||||||
|
yank => "xsel", "-o", "-b";
|
||||||
|
paste => "xsel", "-i", "-b";
|
||||||
|
yank_primary => "xsel", "-o";
|
||||||
|
paste_primary => "xsel", "-i";
|
||||||
|
}
|
||||||
|
command_provider! {
|
||||||
|
WIN32,
|
||||||
|
yank => "win32yank.exe", "-o", "--lf";
|
||||||
|
paste => "win32yank.exe", "-i", "--crlf";
|
||||||
|
}
|
||||||
|
command_provider! {
|
||||||
|
TERMUX,
|
||||||
|
yank => "termux-clipboard-get";
|
||||||
|
paste => "termux-clipboard-set";
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "term")]
|
#[cfg(feature = "term")]
|
||||||
mod osc52 {
|
mod osc52 {
|
||||||
use {super::ClipboardType, crate::base64};
|
use {super::ClipboardType, crate::base64};
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct SetClipboardCommand {
|
pub struct SetClipboardCommand {
|
||||||
encoded_content: String,
|
encoded_content: String,
|
||||||
clipboard_type: ClipboardType,
|
clipboard_type: ClipboardType,
|
||||||
@ -182,115 +426,39 @@ fn write_ansi(&self, f: &mut impl std::fmt::Write) -> std::fmt::Result {
|
|||||||
// Send an OSC 52 set command: https://terminalguide.namepad.de/seq/osc-52/
|
// Send an OSC 52 set command: https://terminalguide.namepad.de/seq/osc-52/
|
||||||
write!(f, "\x1b]52;{};{}\x1b\\", kind, &self.encoded_content)
|
write!(f, "\x1b]52;{};{}\x1b\\", kind, &self.encoded_content)
|
||||||
}
|
}
|
||||||
}
|
#[cfg(windows)]
|
||||||
}
|
fn execute_winapi(&self) -> std::result::Result<(), std::io::Error> {
|
||||||
|
Err(std::io::Error::new(
|
||||||
#[derive(Debug)]
|
std::io::ErrorKind::Other,
|
||||||
pub struct FallbackProvider {
|
"OSC clipboard codes not supported by winapi.",
|
||||||
buf: String,
|
))
|
||||||
primary_buf: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FallbackProvider {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
#[cfg(feature = "term")]
|
|
||||||
log::debug!(
|
|
||||||
"No native clipboard provider found. Yanking by OSC 52 and pasting will be internal to Helix"
|
|
||||||
);
|
|
||||||
#[cfg(not(feature = "term"))]
|
|
||||||
log::warn!(
|
|
||||||
"No native clipboard provider found! Yanking and pasting will be internal to Helix"
|
|
||||||
);
|
|
||||||
Self {
|
|
||||||
buf: String::new(),
|
|
||||||
primary_buf: String::new(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for FallbackProvider {
|
fn execute_command(
|
||||||
fn default() -> Self {
|
cmd: &Command,
|
||||||
Self::new()
|
input: Option<&str>,
|
||||||
}
|
pipe_output: bool,
|
||||||
}
|
) -> Result<Option<String>> {
|
||||||
|
|
||||||
impl ClipboardProvider for FallbackProvider {
|
|
||||||
#[cfg(feature = "term")]
|
|
||||||
fn name(&self) -> Cow<str> {
|
|
||||||
Cow::Borrowed("termcode")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "term"))]
|
|
||||||
fn name(&self) -> Cow<str> {
|
|
||||||
Cow::Borrowed("none")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_contents(&self, clipboard_type: ClipboardType) -> Result<String> {
|
|
||||||
// This is the same noop if term is enabled or not.
|
|
||||||
// We don't use the get side of OSC 52 as it isn't often enabled, it's a security hole,
|
|
||||||
// and it would require this to be async to listen for the response
|
|
||||||
let value = match clipboard_type {
|
|
||||||
ClipboardType::Clipboard => self.buf.clone(),
|
|
||||||
ClipboardType::Selection => self.primary_buf.clone(),
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_contents(&mut self, content: String, clipboard_type: ClipboardType) -> Result<()> {
|
|
||||||
#[cfg(feature = "term")]
|
|
||||||
crossterm::execute!(
|
|
||||||
std::io::stdout(),
|
|
||||||
osc52::SetClipboardCommand::new(&content, clipboard_type)
|
|
||||||
)?;
|
|
||||||
// Set our internal variables to use in get_content regardless of using OSC 52
|
|
||||||
match clipboard_type {
|
|
||||||
ClipboardType::Clipboard => self.buf = content,
|
|
||||||
ClipboardType::Selection => self.primary_buf = content,
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
|
||||||
pub mod command {
|
|
||||||
use super::*;
|
|
||||||
use anyhow::{bail, Context as _};
|
|
||||||
|
|
||||||
#[cfg(not(any(windows, target_os = "macos")))]
|
|
||||||
pub fn is_exit_success(program: &str, args: &[&str]) -> bool {
|
|
||||||
std::process::Command::new(program)
|
|
||||||
.args(args)
|
|
||||||
.output()
|
|
||||||
.ok()
|
|
||||||
.and_then(|out| out.status.success().then_some(()))
|
|
||||||
.is_some()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Config {
|
|
||||||
pub prg: &'static str,
|
|
||||||
pub args: &'static [&'static str],
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Config {
|
|
||||||
fn execute(&self, input: Option<&str>, pipe_output: bool) -> Result<Option<String>> {
|
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::process::{Command, Stdio};
|
use std::process::{Command, Stdio};
|
||||||
|
|
||||||
let stdin = input.map(|_| Stdio::piped()).unwrap_or_else(Stdio::null);
|
let stdin = input.map(|_| Stdio::piped()).unwrap_or_else(Stdio::null);
|
||||||
let stdout = pipe_output.then(Stdio::piped).unwrap_or_else(Stdio::null);
|
let stdout = pipe_output.then(Stdio::piped).unwrap_or_else(Stdio::null);
|
||||||
|
|
||||||
let mut command: Command = Command::new(self.prg);
|
let mut command: Command = Command::new(cmd.command.as_ref());
|
||||||
|
|
||||||
|
#[allow(unused_mut)]
|
||||||
let mut command_mut: &mut Command = command
|
let mut command_mut: &mut Command = command
|
||||||
.args(self.args)
|
.args(cmd.args.iter().map(AsRef::as_ref))
|
||||||
.stdin(stdin)
|
.stdin(stdin)
|
||||||
.stdout(stdout)
|
.stdout(stdout)
|
||||||
.stderr(Stdio::null());
|
.stderr(Stdio::null());
|
||||||
|
|
||||||
// Fix for https://github.com/helix-editor/helix/issues/5424
|
// Fix for https://github.com/helix-editor/helix/issues/5424
|
||||||
if cfg!(unix) {
|
#[cfg(unix)]
|
||||||
|
{
|
||||||
use std::os::unix::process::CommandExt;
|
use std::os::unix::process::CommandExt;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -304,17 +472,22 @@ fn execute(&self, input: Option<&str>, pipe_output: bool) -> Result<Option<Strin
|
|||||||
let mut child = command_mut.spawn()?;
|
let mut child = command_mut.spawn()?;
|
||||||
|
|
||||||
if let Some(input) = input {
|
if let Some(input) = input {
|
||||||
let mut stdin = child.stdin.take().context("stdin is missing")?;
|
let mut stdin = child.stdin.take().ok_or(ClipboardError::StdinWriteFailed)?;
|
||||||
stdin
|
stdin
|
||||||
.write_all(input.as_bytes())
|
.write_all(input.as_bytes())
|
||||||
.context("couldn't write in stdin")?;
|
.map_err(|_| ClipboardError::StdinWriteFailed)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: add timer?
|
// TODO: add timer?
|
||||||
let output = child.wait_with_output()?;
|
let output = child.wait_with_output()?;
|
||||||
|
|
||||||
if !output.status.success() {
|
if !output.status.success() {
|
||||||
bail!("clipboard provider {} failed", self.prg);
|
log::error!(
|
||||||
|
"clipboard provider {} failed with stderr: \"{}\"",
|
||||||
|
cmd.command,
|
||||||
|
String::from_utf8_lossy(&output.stderr)
|
||||||
|
);
|
||||||
|
return Err(ClipboardError::CommandFailed);
|
||||||
}
|
}
|
||||||
|
|
||||||
if pipe_output {
|
if pipe_output {
|
||||||
@ -323,91 +496,4 @@ fn execute(&self, input: Option<&str>, pipe_output: bool) -> Result<Option<Strin
|
|||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Provider {
|
|
||||||
pub get_cmd: Config,
|
|
||||||
pub set_cmd: Config,
|
|
||||||
pub get_primary_cmd: Option<Config>,
|
|
||||||
pub set_primary_cmd: Option<Config>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ClipboardProvider for Provider {
|
|
||||||
fn name(&self) -> Cow<str> {
|
|
||||||
if self.get_cmd.prg != self.set_cmd.prg {
|
|
||||||
Cow::Owned(format!("{}+{}", self.get_cmd.prg, self.set_cmd.prg))
|
|
||||||
} else {
|
|
||||||
Cow::Borrowed(self.get_cmd.prg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_contents(&self, clipboard_type: ClipboardType) -> Result<String> {
|
|
||||||
match clipboard_type {
|
|
||||||
ClipboardType::Clipboard => Ok(self
|
|
||||||
.get_cmd
|
|
||||||
.execute(None, true)?
|
|
||||||
.context("output is missing")?),
|
|
||||||
ClipboardType::Selection => {
|
|
||||||
if let Some(cmd) = &self.get_primary_cmd {
|
|
||||||
return cmd.execute(None, true)?.context("output is missing");
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(String::new())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_contents(&mut self, value: String, clipboard_type: ClipboardType) -> Result<()> {
|
|
||||||
let cmd = match clipboard_type {
|
|
||||||
ClipboardType::Clipboard => &self.set_cmd,
|
|
||||||
ClipboardType::Selection => {
|
|
||||||
if let Some(cmd) = &self.set_primary_cmd {
|
|
||||||
cmd
|
|
||||||
} else {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
cmd.execute(Some(&value), false).map(|_| ())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
mod provider {
|
|
||||||
use super::{ClipboardProvider, ClipboardType};
|
|
||||||
use anyhow::Result;
|
|
||||||
use std::borrow::Cow;
|
|
||||||
|
|
||||||
#[derive(Default, Debug)]
|
|
||||||
pub struct WindowsProvider;
|
|
||||||
|
|
||||||
impl ClipboardProvider for WindowsProvider {
|
|
||||||
fn name(&self) -> Cow<str> {
|
|
||||||
log::debug!("Using clipboard-win to interact with the system clipboard");
|
|
||||||
Cow::Borrowed("clipboard-win")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_contents(&self, clipboard_type: ClipboardType) -> Result<String> {
|
|
||||||
match clipboard_type {
|
|
||||||
ClipboardType::Clipboard => {
|
|
||||||
let contents = clipboard_win::get_clipboard(clipboard_win::formats::Unicode)?;
|
|
||||||
Ok(contents)
|
|
||||||
}
|
|
||||||
ClipboardType::Selection => Ok(String::new()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_contents(&mut self, contents: String, clipboard_type: ClipboardType) -> Result<()> {
|
|
||||||
match clipboard_type {
|
|
||||||
ClipboardType::Clipboard => {
|
|
||||||
clipboard_win::set_clipboard(clipboard_win::formats::Unicode, contents)?;
|
|
||||||
}
|
|
||||||
ClipboardType::Selection => {}
|
|
||||||
};
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1111,7 +1111,7 @@ pub fn detect_readonly(&mut self) {
|
|||||||
pub fn reload(
|
pub fn reload(
|
||||||
&mut self,
|
&mut self,
|
||||||
view: &mut View,
|
view: &mut View,
|
||||||
provider_registry: &DiffProviderRegistry,
|
provider_registry: &mut DiffProviderRegistry,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let encoding = self.encoding;
|
let encoding = self.encoding;
|
||||||
let path = match self.path() {
|
let path = match self.path() {
|
||||||
@ -1122,6 +1122,8 @@ pub fn reload(
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
provider_registry.reload(&path);
|
||||||
|
|
||||||
// Once we have a valid path we check if its readonly status has changed
|
// Once we have a valid path we check if its readonly status has changed
|
||||||
self.detect_readonly();
|
self.detect_readonly();
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
annotations::diagnostics::{DiagnosticFilter, InlineDiagnosticsConfig},
|
annotations::diagnostics::{DiagnosticFilter, InlineDiagnosticsConfig},
|
||||||
|
clipboard::ClipboardProvider,
|
||||||
document::{
|
document::{
|
||||||
DocumentOpenError, DocumentSavedEventFuture, DocumentSavedEventResult, Mode, SavePoint,
|
DocumentOpenError, DocumentSavedEventFuture, DocumentSavedEventResult, Mode, SavePoint,
|
||||||
},
|
},
|
||||||
@ -269,6 +270,8 @@ pub struct Config {
|
|||||||
pub auto_completion: bool,
|
pub auto_completion: bool,
|
||||||
/// Automatic formatting on save. Defaults to true.
|
/// Automatic formatting on save. Defaults to true.
|
||||||
pub auto_format: bool,
|
pub auto_format: bool,
|
||||||
|
/// Default register used for yank/paste. Defaults to '"'
|
||||||
|
pub default_yank_register: char,
|
||||||
/// Automatic save on focus lost and/or after delay.
|
/// Automatic save on focus lost and/or after delay.
|
||||||
/// Time delay in milliseconds since last edit after which auto save timer triggers.
|
/// Time delay in milliseconds since last edit after which auto save timer triggers.
|
||||||
/// Time delay defaults to false with 3000ms delay. Focus lost defaults to false.
|
/// Time delay defaults to false with 3000ms delay. Focus lost defaults to false.
|
||||||
@ -345,6 +348,8 @@ pub struct Config {
|
|||||||
/// Display diagnostic below the line they occur.
|
/// Display diagnostic below the line they occur.
|
||||||
pub inline_diagnostics: InlineDiagnosticsConfig,
|
pub inline_diagnostics: InlineDiagnosticsConfig,
|
||||||
pub end_of_line_diagnostics: DiagnosticFilter,
|
pub end_of_line_diagnostics: DiagnosticFilter,
|
||||||
|
// Set to override the default clipboard provider
|
||||||
|
pub clipboard_provider: ClipboardProvider,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, Eq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, Eq, PartialOrd, Ord)]
|
||||||
@ -948,6 +953,7 @@ fn default() -> Self {
|
|||||||
auto_pairs: AutoPairConfig::default(),
|
auto_pairs: AutoPairConfig::default(),
|
||||||
auto_completion: true,
|
auto_completion: true,
|
||||||
auto_format: true,
|
auto_format: true,
|
||||||
|
default_yank_register: '"',
|
||||||
auto_save: AutoSave::default(),
|
auto_save: AutoSave::default(),
|
||||||
idle_timeout: Duration::from_millis(250),
|
idle_timeout: Duration::from_millis(250),
|
||||||
completion_timeout: Duration::from_millis(250),
|
completion_timeout: Duration::from_millis(250),
|
||||||
@ -982,6 +988,7 @@ fn default() -> Self {
|
|||||||
jump_label_alphabet: ('a'..='z').collect(),
|
jump_label_alphabet: ('a'..='z').collect(),
|
||||||
inline_diagnostics: InlineDiagnosticsConfig::default(),
|
inline_diagnostics: InlineDiagnosticsConfig::default(),
|
||||||
end_of_line_diagnostics: DiagnosticFilter::Disable,
|
end_of_line_diagnostics: DiagnosticFilter::Disable,
|
||||||
|
clipboard_provider: ClipboardProvider::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1183,7 +1190,10 @@ pub fn new(
|
|||||||
theme_loader,
|
theme_loader,
|
||||||
last_theme: None,
|
last_theme: None,
|
||||||
last_selection: None,
|
last_selection: None,
|
||||||
registers: Registers::default(),
|
registers: Registers::new(Box::new(arc_swap::access::Map::new(
|
||||||
|
Arc::clone(&config),
|
||||||
|
|config: &Config| &config.clipboard_provider,
|
||||||
|
))),
|
||||||
status_msg: None,
|
status_msg: None,
|
||||||
autoinfo: None,
|
autoinfo: None,
|
||||||
idle_timer: Box::pin(sleep(conf.idle_timeout)),
|
idle_timer: Box::pin(sleep(conf.idle_timeout)),
|
||||||
@ -1719,6 +1729,8 @@ pub fn open(&mut self, path: &Path, action: Action) -> Result<DocumentId, Docume
|
|||||||
Editor::doc_diagnostics(&self.language_servers, &self.diagnostics, &doc);
|
Editor::doc_diagnostics(&self.language_servers, &self.diagnostics, &doc);
|
||||||
doc.replace_diagnostics(diagnostics, &[], None);
|
doc.replace_diagnostics(diagnostics, &[], None);
|
||||||
|
|
||||||
|
// When opening a *new* file, ensure its diff provider is loaded.
|
||||||
|
self.diff_providers.add(&path);
|
||||||
if let Some(diff_base) = self.diff_providers.get_diff_base(&path) {
|
if let Some(diff_base) = self.diff_providers.get_diff_base(&path) {
|
||||||
doc.set_diff_base(diff_base);
|
doc.set_diff_base(diff_base);
|
||||||
}
|
}
|
||||||
@ -1752,6 +1764,10 @@ pub fn close_document(&mut self, doc_id: DocumentId, force: bool) -> Result<(),
|
|||||||
return Err(CloseError::BufferModified(doc.display_name().into_owned()));
|
return Err(CloseError::BufferModified(doc.display_name().into_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(path) = doc.path() {
|
||||||
|
self.diff_providers.remove(path);
|
||||||
|
}
|
||||||
|
|
||||||
// This will also disallow any follow-up writes
|
// This will also disallow any follow-up writes
|
||||||
self.saves.remove(&doc_id);
|
self.saves.remove(&doc_id);
|
||||||
|
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
use std::{borrow::Cow, collections::HashMap, iter};
|
use std::{borrow::Cow, collections::HashMap, iter};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use arc_swap::access::DynAccess;
|
||||||
use helix_core::NATIVE_LINE_ENDING;
|
use helix_core::NATIVE_LINE_ENDING;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
clipboard::{get_clipboard_provider, ClipboardProvider, ClipboardType},
|
clipboard::{ClipboardProvider, ClipboardType},
|
||||||
Editor,
|
Editor,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -20,28 +21,25 @@
|
|||||||
/// * Document path (`%`): filename of the current buffer
|
/// * Document path (`%`): filename of the current buffer
|
||||||
/// * System clipboard (`*`)
|
/// * System clipboard (`*`)
|
||||||
/// * Primary clipboard (`+`)
|
/// * Primary clipboard (`+`)
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Registers {
|
pub struct Registers {
|
||||||
/// The mapping of register to values.
|
/// The mapping of register to values.
|
||||||
/// Values are stored in reverse order when inserted with `Registers::write`.
|
/// Values are stored in reverse order when inserted with `Registers::write`.
|
||||||
/// The order is reversed again in `Registers::read`. This allows us to
|
/// The order is reversed again in `Registers::read`. This allows us to
|
||||||
/// efficiently prepend new values in `Registers::push`.
|
/// efficiently prepend new values in `Registers::push`.
|
||||||
inner: HashMap<char, Vec<String>>,
|
inner: HashMap<char, Vec<String>>,
|
||||||
clipboard_provider: Box<dyn ClipboardProvider>,
|
clipboard_provider: Box<dyn DynAccess<ClipboardProvider>>,
|
||||||
pub last_search_register: char,
|
pub last_search_register: char,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Registers {
|
impl Registers {
|
||||||
fn default() -> Self {
|
pub fn new(clipboard_provider: Box<dyn DynAccess<ClipboardProvider>>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
inner: Default::default(),
|
inner: Default::default(),
|
||||||
clipboard_provider: get_clipboard_provider(),
|
clipboard_provider,
|
||||||
last_search_register: '/',
|
last_search_register: '/',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl Registers {
|
|
||||||
pub fn read<'a>(&'a self, name: char, editor: &'a Editor) -> Option<RegisterValues<'a>> {
|
pub fn read<'a>(&'a self, name: char, editor: &'a Editor) -> Option<RegisterValues<'a>> {
|
||||||
match name {
|
match name {
|
||||||
'_' => Some(RegisterValues::new(iter::empty())),
|
'_' => Some(RegisterValues::new(iter::empty())),
|
||||||
@ -64,7 +62,7 @@ pub fn read<'a>(&'a self, name: char, editor: &'a Editor) -> Option<RegisterValu
|
|||||||
Some(RegisterValues::new(iter::once(path)))
|
Some(RegisterValues::new(iter::once(path)))
|
||||||
}
|
}
|
||||||
'*' | '+' => Some(read_from_clipboard(
|
'*' | '+' => Some(read_from_clipboard(
|
||||||
self.clipboard_provider.as_ref(),
|
&self.clipboard_provider.load(),
|
||||||
self.inner.get(&name),
|
self.inner.get(&name),
|
||||||
match name {
|
match name {
|
||||||
'+' => ClipboardType::Clipboard,
|
'+' => ClipboardType::Clipboard,
|
||||||
@ -84,8 +82,8 @@ pub fn write(&mut self, name: char, mut values: Vec<String>) -> Result<()> {
|
|||||||
'_' => Ok(()),
|
'_' => Ok(()),
|
||||||
'#' | '.' | '%' => Err(anyhow::anyhow!("Register {name} does not support writing")),
|
'#' | '.' | '%' => Err(anyhow::anyhow!("Register {name} does not support writing")),
|
||||||
'*' | '+' => {
|
'*' | '+' => {
|
||||||
self.clipboard_provider.set_contents(
|
self.clipboard_provider.load().set_contents(
|
||||||
values.join(NATIVE_LINE_ENDING.as_str()),
|
&values.join(NATIVE_LINE_ENDING.as_str()),
|
||||||
match name {
|
match name {
|
||||||
'+' => ClipboardType::Clipboard,
|
'+' => ClipboardType::Clipboard,
|
||||||
'*' => ClipboardType::Selection,
|
'*' => ClipboardType::Selection,
|
||||||
@ -114,7 +112,10 @@ pub fn push(&mut self, name: char, mut value: String) -> Result<()> {
|
|||||||
'*' => ClipboardType::Selection,
|
'*' => ClipboardType::Selection,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
let contents = self.clipboard_provider.get_contents(clipboard_type)?;
|
let contents = self
|
||||||
|
.clipboard_provider
|
||||||
|
.load()
|
||||||
|
.get_contents(&clipboard_type)?;
|
||||||
let saved_values = self.inner.entry(name).or_default();
|
let saved_values = self.inner.entry(name).or_default();
|
||||||
|
|
||||||
if !contents_are_saved(saved_values, &contents) {
|
if !contents_are_saved(saved_values, &contents) {
|
||||||
@ -127,7 +128,8 @@ pub fn push(&mut self, name: char, mut value: String) -> Result<()> {
|
|||||||
}
|
}
|
||||||
value.push_str(&contents);
|
value.push_str(&contents);
|
||||||
self.clipboard_provider
|
self.clipboard_provider
|
||||||
.set_contents(value, clipboard_type)?;
|
.load()
|
||||||
|
.set_contents(&value, clipboard_type)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -198,7 +200,8 @@ pub fn remove(&mut self, name: char) -> bool {
|
|||||||
fn clear_clipboard(&mut self, clipboard_type: ClipboardType) {
|
fn clear_clipboard(&mut self, clipboard_type: ClipboardType) {
|
||||||
if let Err(err) = self
|
if let Err(err) = self
|
||||||
.clipboard_provider
|
.clipboard_provider
|
||||||
.set_contents("".into(), clipboard_type)
|
.load()
|
||||||
|
.set_contents("", clipboard_type)
|
||||||
{
|
{
|
||||||
log::error!(
|
log::error!(
|
||||||
"Failed to clear {} clipboard: {err}",
|
"Failed to clear {} clipboard: {err}",
|
||||||
@ -210,17 +213,17 @@ fn clear_clipboard(&mut self, clipboard_type: ClipboardType) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clipboard_provider_name(&self) -> Cow<str> {
|
pub fn clipboard_provider_name(&self) -> String {
|
||||||
self.clipboard_provider.name()
|
self.clipboard_provider.load().name().into_owned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_from_clipboard<'a>(
|
fn read_from_clipboard<'a>(
|
||||||
provider: &dyn ClipboardProvider,
|
provider: &ClipboardProvider,
|
||||||
saved_values: Option<&'a Vec<String>>,
|
saved_values: Option<&'a Vec<String>>,
|
||||||
clipboard_type: ClipboardType,
|
clipboard_type: ClipboardType,
|
||||||
) -> RegisterValues<'a> {
|
) -> RegisterValues<'a> {
|
||||||
match provider.get_contents(clipboard_type) {
|
match provider.get_contents(&clipboard_type) {
|
||||||
Ok(contents) => {
|
Ok(contents) => {
|
||||||
// If we're pasting the same values that we just yanked, re-use
|
// If we're pasting the same values that we just yanked, re-use
|
||||||
// the saved values. This allows pasting multiple selections
|
// the saved values. This allows pasting multiple selections
|
||||||
|
106
languages.toml
106
languages.toml
@ -44,6 +44,7 @@ gleam = { command = "gleam", args = ["lsp"] }
|
|||||||
glsl_analyzer = { command = "glsl_analyzer" }
|
glsl_analyzer = { command = "glsl_analyzer" }
|
||||||
graphql-language-service = { command = "graphql-lsp", args = ["server", "-m", "stream"] }
|
graphql-language-service = { command = "graphql-lsp", args = ["server", "-m", "stream"] }
|
||||||
haskell-language-server = { command = "haskell-language-server-wrapper", args = ["--lsp"] }
|
haskell-language-server = { command = "haskell-language-server-wrapper", args = ["--lsp"] }
|
||||||
|
hyprls = { command = "hyprls" }
|
||||||
idris2-lsp = { command = "idris2-lsp" }
|
idris2-lsp = { command = "idris2-lsp" }
|
||||||
intelephense = { command = "intelephense", args = ["--stdio"] }
|
intelephense = { command = "intelephense", args = ["--stdio"] }
|
||||||
jdtls = { command = "jdtls" }
|
jdtls = { command = "jdtls" }
|
||||||
@ -83,6 +84,7 @@ pyright = { command = "pyright-langserver", args = ["--stdio"], config = {} }
|
|||||||
basedpyright = { command = "basedpyright-langserver", args = ["--stdio"], config = {} }
|
basedpyright = { command = "basedpyright-langserver", args = ["--stdio"], config = {} }
|
||||||
pylyzer = { command = "pylyzer", args = ["--server"] }
|
pylyzer = { command = "pylyzer", args = ["--server"] }
|
||||||
qmlls = { command = "qmlls" }
|
qmlls = { command = "qmlls" }
|
||||||
|
quint-language-server = { command = "quint-language-server", args = ["--stdio"] }
|
||||||
r = { command = "R", args = ["--no-echo", "-e", "languageserver::run()"] }
|
r = { command = "R", args = ["--no-echo", "-e", "languageserver::run()"] }
|
||||||
racket = { command = "racket", args = ["-l", "racket-langserver"] }
|
racket = { command = "racket", args = ["-l", "racket-langserver"] }
|
||||||
regols = { command = "regols" }
|
regols = { command = "regols" }
|
||||||
@ -94,6 +96,7 @@ slint-lsp = { command = "slint-lsp", args = [] }
|
|||||||
solargraph = { command = "solargraph", args = ["stdio"] }
|
solargraph = { command = "solargraph", args = ["stdio"] }
|
||||||
solc = { command = "solc", args = ["--lsp"] }
|
solc = { command = "solc", args = ["--lsp"] }
|
||||||
sourcekit-lsp = { command = "sourcekit-lsp" }
|
sourcekit-lsp = { command = "sourcekit-lsp" }
|
||||||
|
spade-language-server = {command = "spade-language-server"}
|
||||||
svlangserver = { command = "svlangserver", args = [] }
|
svlangserver = { command = "svlangserver", args = [] }
|
||||||
swipl = { command = "swipl", args = [ "-g", "use_module(library(lsp_server))", "-g", "lsp_server:main", "-t", "halt", "--", "stdio" ] }
|
swipl = { command = "swipl", args = [ "-g", "use_module(library(lsp_server))", "-g", "lsp_server:main", "-t", "halt", "--", "stdio" ] }
|
||||||
superhtml = { command = "superhtml", args = ["lsp"]}
|
superhtml = { command = "superhtml", args = ["lsp"]}
|
||||||
@ -344,6 +347,19 @@ indent = { tab-width = 2, unit = " " }
|
|||||||
name = "protobuf"
|
name = "protobuf"
|
||||||
source = { git = "https://github.com/yusdacra/tree-sitter-protobuf", rev = "19c211a01434d9f03efff99f85e19f967591b175"}
|
source = { git = "https://github.com/yusdacra/tree-sitter-protobuf", rev = "19c211a01434d9f03efff99f85e19f967591b175"}
|
||||||
|
|
||||||
|
[[language]]
|
||||||
|
name = "textproto"
|
||||||
|
file-types = ["txtpb", "textpb", "textproto"]
|
||||||
|
comment-token = "#"
|
||||||
|
scope = "source.textproto"
|
||||||
|
indent = { tab-width = 2, unit = " " }
|
||||||
|
formatter = { command = "txtpbfmt" }
|
||||||
|
auto-format = true
|
||||||
|
|
||||||
|
[[grammar]]
|
||||||
|
name = "textproto"
|
||||||
|
source = { git = "https://github.com/PorterAtGoogle/tree-sitter-textproto", rev = "568471b80fd8793d37ed01865d8c2208a9fefd1b"}
|
||||||
|
|
||||||
[[language]]
|
[[language]]
|
||||||
name = "elixir"
|
name = "elixir"
|
||||||
scope = "source.elixir"
|
scope = "source.elixir"
|
||||||
@ -451,6 +467,7 @@ file-types = [
|
|||||||
"avsc",
|
"avsc",
|
||||||
"ldtk",
|
"ldtk",
|
||||||
"ldtkl",
|
"ldtkl",
|
||||||
|
{ glob = ".swift-format" },
|
||||||
]
|
]
|
||||||
language-servers = [ "vscode-json-language-server" ]
|
language-servers = [ "vscode-json-language-server" ]
|
||||||
auto-format = true
|
auto-format = true
|
||||||
@ -464,7 +481,7 @@ source = { git = "https://github.com/tree-sitter/tree-sitter-json", rev = "73076
|
|||||||
name = "jsonc"
|
name = "jsonc"
|
||||||
scope = "source.json"
|
scope = "source.json"
|
||||||
injection-regex = "jsonc"
|
injection-regex = "jsonc"
|
||||||
file-types = ["jsonc"]
|
file-types = ["jsonc", { glob = "tsconfig.json" }]
|
||||||
grammar = "json"
|
grammar = "json"
|
||||||
language-servers = [ "vscode-json-language-server" ]
|
language-servers = [ "vscode-json-language-server" ]
|
||||||
auto-format = true
|
auto-format = true
|
||||||
@ -729,6 +746,7 @@ injection-regex = "(js|javascript)"
|
|||||||
language-id = "javascript"
|
language-id = "javascript"
|
||||||
file-types = ["js", "mjs", "cjs", "rules", "es6", "pac", { glob = ".node_repl_history" }, { glob = "jakefile" }]
|
file-types = ["js", "mjs", "cjs", "rules", "es6", "pac", { glob = ".node_repl_history" }, { glob = "jakefile" }]
|
||||||
shebangs = ["node"]
|
shebangs = ["node"]
|
||||||
|
roots = [ "package.json" ]
|
||||||
comment-token = "//"
|
comment-token = "//"
|
||||||
block-comment-tokens = { start = "/*", end = "*/" }
|
block-comment-tokens = { start = "/*", end = "*/" }
|
||||||
language-servers = [ "typescript-language-server" ]
|
language-servers = [ "typescript-language-server" ]
|
||||||
@ -756,6 +774,7 @@ scope = "source.jsx"
|
|||||||
injection-regex = "jsx"
|
injection-regex = "jsx"
|
||||||
language-id = "javascriptreact"
|
language-id = "javascriptreact"
|
||||||
file-types = ["jsx"]
|
file-types = ["jsx"]
|
||||||
|
roots = [ "package.json" ]
|
||||||
comment-token = "//"
|
comment-token = "//"
|
||||||
block-comment-tokens = { start = "/*", end = "*/" }
|
block-comment-tokens = { start = "/*", end = "*/" }
|
||||||
language-servers = [ "typescript-language-server" ]
|
language-servers = [ "typescript-language-server" ]
|
||||||
@ -769,6 +788,7 @@ injection-regex = "(ts|typescript)"
|
|||||||
language-id = "typescript"
|
language-id = "typescript"
|
||||||
file-types = ["ts", "mts", "cts"]
|
file-types = ["ts", "mts", "cts"]
|
||||||
shebangs = ["deno", "bun", "ts-node"]
|
shebangs = ["deno", "bun", "ts-node"]
|
||||||
|
roots = [ "package.json", "tsconfig.json" ]
|
||||||
comment-token = "//"
|
comment-token = "//"
|
||||||
block-comment-tokens = { start = "/*", end = "*/" }
|
block-comment-tokens = { start = "/*", end = "*/" }
|
||||||
language-servers = [ "typescript-language-server" ]
|
language-servers = [ "typescript-language-server" ]
|
||||||
@ -801,6 +821,7 @@ scope = "source.tsx"
|
|||||||
injection-regex = "(tsx)" # |typescript
|
injection-regex = "(tsx)" # |typescript
|
||||||
language-id = "typescriptreact"
|
language-id = "typescriptreact"
|
||||||
file-types = ["tsx"]
|
file-types = ["tsx"]
|
||||||
|
roots = [ "package.json", "tsconfig.json" ]
|
||||||
comment-token = "//"
|
comment-token = "//"
|
||||||
block-comment-tokens = { start = "/*", end = "*/" }
|
block-comment-tokens = { start = "/*", end = "*/" }
|
||||||
language-servers = [ "typescript-language-server" ]
|
language-servers = [ "typescript-language-server" ]
|
||||||
@ -1305,7 +1326,7 @@ source = { git = "https://github.com/ikatyang/tree-sitter-vue", rev = "91fe27547
|
|||||||
[[language]]
|
[[language]]
|
||||||
name = "yaml"
|
name = "yaml"
|
||||||
scope = "source.yaml"
|
scope = "source.yaml"
|
||||||
file-types = ["yml", "yaml", { glob = ".prettierrc" }]
|
file-types = ["yml", "yaml", { glob = ".prettierrc" }, { glob = ".clangd" }, { glob = ".clang-format" }]
|
||||||
comment-token = "#"
|
comment-token = "#"
|
||||||
indent = { tab-width = 2, unit = " " }
|
indent = { tab-width = 2, unit = " " }
|
||||||
language-servers = [ "yaml-language-server", "ansible-language-server" ]
|
language-servers = [ "yaml-language-server", "ansible-language-server" ]
|
||||||
@ -1315,6 +1336,15 @@ injection-regex = "yml|yaml"
|
|||||||
name = "yaml"
|
name = "yaml"
|
||||||
source = { git = "https://github.com/ikatyang/tree-sitter-yaml", rev = "0e36bed171768908f331ff7dff9d956bae016efb" }
|
source = { git = "https://github.com/ikatyang/tree-sitter-yaml", rev = "0e36bed171768908f331ff7dff9d956bae016efb" }
|
||||||
|
|
||||||
|
[[language]]
|
||||||
|
name = "nestedtext"
|
||||||
|
scope = "text.nested"
|
||||||
|
injection-regex = "nestedtext"
|
||||||
|
file-types = ["nt"]
|
||||||
|
comment-token = "#"
|
||||||
|
indent = { tab-width = 4, unit = " " }
|
||||||
|
grammar = "yaml"
|
||||||
|
|
||||||
[[language]]
|
[[language]]
|
||||||
name = "haskell"
|
name = "haskell"
|
||||||
scope = "source.haskell"
|
scope = "source.haskell"
|
||||||
@ -1365,7 +1395,7 @@ injection-regex = "zig"
|
|||||||
file-types = ["zig", "zon"]
|
file-types = ["zig", "zon"]
|
||||||
roots = ["build.zig"]
|
roots = ["build.zig"]
|
||||||
auto-format = true
|
auto-format = true
|
||||||
comment-token = "//"
|
comment-tokens = ["//", "///", "//!"]
|
||||||
language-servers = [ "zls" ]
|
language-servers = [ "zls" ]
|
||||||
indent = { tab-width = 4, unit = " " }
|
indent = { tab-width = 4, unit = " " }
|
||||||
formatter = { command = "zig" , args = ["fmt", "--stdin"] }
|
formatter = { command = "zig" , args = ["fmt", "--stdin"] }
|
||||||
@ -1470,7 +1500,7 @@ indent = { tab-width = 2, unit = " " }
|
|||||||
|
|
||||||
[[grammar]]
|
[[grammar]]
|
||||||
name = "perl"
|
name = "perl"
|
||||||
source = { git = "https://github.com/tree-sitter-perl/tree-sitter-perl", rev = "e99bb5283805db4cb86c964722d709df21b0ac16" }
|
source = { git = "https://github.com/tree-sitter-perl/tree-sitter-perl", rev = "72a08a496a23212f23802490ef6f4700d68cfd0e" }
|
||||||
|
|
||||||
[[language]]
|
[[language]]
|
||||||
name = "pod"
|
name = "pod"
|
||||||
@ -1480,7 +1510,7 @@ file-types = ["pod"]
|
|||||||
|
|
||||||
[[grammar]]
|
[[grammar]]
|
||||||
name = "pod"
|
name = "pod"
|
||||||
source = { git = "https://github.com/tree-sitter-perl/tree-sitter-pod", rev = "39da859947b94abdee43e431368e1ae975c0a424" }
|
source = { git = "https://github.com/tree-sitter-perl/tree-sitter-pod", rev = "0bf8387987c21bf2f8ed41d2575a8f22b139687f" }
|
||||||
|
|
||||||
[[language]]
|
[[language]]
|
||||||
name = "racket"
|
name = "racket"
|
||||||
@ -1542,7 +1572,7 @@ injection-regex = "llvm"
|
|||||||
|
|
||||||
[[grammar]]
|
[[grammar]]
|
||||||
name = "llvm"
|
name = "llvm"
|
||||||
source = { git = "https://github.com/benwilliamgraham/tree-sitter-llvm", rev = "e9948edc41e9e5869af99dddb2b5ff5cc5581af6" }
|
source = { git = "https://github.com/benwilliamgraham/tree-sitter-llvm", rev = "c14cb839003348692158b845db9edda201374548" }
|
||||||
|
|
||||||
[[language]]
|
[[language]]
|
||||||
name = "llvm-mir"
|
name = "llvm-mir"
|
||||||
@ -1554,7 +1584,7 @@ injection-regex = "mir"
|
|||||||
|
|
||||||
[[grammar]]
|
[[grammar]]
|
||||||
name = "llvm-mir"
|
name = "llvm-mir"
|
||||||
source = { git = "https://github.com/Flakebi/tree-sitter-llvm-mir", rev = "06fabca19454b2dc00c1b211a7cb7ad0bc2585f1" }
|
source = { git = "https://github.com/Flakebi/tree-sitter-llvm-mir", rev = "d166ff8c5950f80b0a476956e7a0ad2f27c12505" }
|
||||||
|
|
||||||
[[language]]
|
[[language]]
|
||||||
name = "llvm-mir-yaml"
|
name = "llvm-mir-yaml"
|
||||||
@ -1577,13 +1607,13 @@ injection-regex = "tablegen"
|
|||||||
|
|
||||||
[[grammar]]
|
[[grammar]]
|
||||||
name = "tablegen"
|
name = "tablegen"
|
||||||
source = { git = "https://github.com/Flakebi/tree-sitter-tablegen", rev = "568dd8a937347175fd58db83d4c4cdaeb6069bd2" }
|
source = { git = "https://github.com/Flakebi/tree-sitter-tablegen", rev = "3e9c4822ab5cdcccf4f8aa9dcd42117f736d51d9" }
|
||||||
|
|
||||||
[[language]]
|
[[language]]
|
||||||
name = "markdown"
|
name = "markdown"
|
||||||
scope = "source.md"
|
scope = "source.md"
|
||||||
injection-regex = "md|markdown"
|
injection-regex = "md|markdown"
|
||||||
file-types = ["md", "markdown", "mdx", "mkd", "mkdn", "mdwn", "mdown", "markdn", "mdtxt", "mdtext", "workbook", { glob = "PULLREQ_EDITMSG" }]
|
file-types = ["md", "livemd", "markdown", "mdx", "mkd", "mkdn", "mdwn", "mdown", "markdn", "mdtxt", "mdtext", "workbook", { glob = "PULLREQ_EDITMSG" }]
|
||||||
roots = [".marksman.toml"]
|
roots = [".marksman.toml"]
|
||||||
language-servers = [ "marksman", "markdown-oxide" ]
|
language-servers = [ "marksman", "markdown-oxide" ]
|
||||||
indent = { tab-width = 2, unit = " " }
|
indent = { tab-width = 2, unit = " " }
|
||||||
@ -1808,7 +1838,7 @@ indent = { tab-width = 2, unit = " " }
|
|||||||
|
|
||||||
[[grammar]]
|
[[grammar]]
|
||||||
name = "rescript"
|
name = "rescript"
|
||||||
source = { git = "https://github.com/jaredramirez/tree-sitter-rescript", rev = "467dcf99f68c47823d7b378779a6b282d7ef9782" }
|
source = { git = "https://github.com/rescript-lang/tree-sitter-rescript", rev = "5e2a44a9d886b0a509f5bfd0437d33b4871fbac5" }
|
||||||
|
|
||||||
[[language]]
|
[[language]]
|
||||||
name = "erlang"
|
name = "erlang"
|
||||||
@ -1967,7 +1997,6 @@ roots = [ "Package.swift" ]
|
|||||||
comment-token = "//"
|
comment-token = "//"
|
||||||
block-comment-tokens = { start = "/*", end = "*/" }
|
block-comment-tokens = { start = "/*", end = "*/" }
|
||||||
formatter = { command = "swift-format" }
|
formatter = { command = "swift-format" }
|
||||||
auto-format = true
|
|
||||||
language-servers = [ "sourcekit-lsp" ]
|
language-servers = [ "sourcekit-lsp" ]
|
||||||
|
|
||||||
[[grammar]]
|
[[grammar]]
|
||||||
@ -2202,7 +2231,7 @@ source = { git = "https://github.com/staysail/tree-sitter-meson", rev = "32a83e8
|
|||||||
[[language]]
|
[[language]]
|
||||||
name = "sshclientconfig"
|
name = "sshclientconfig"
|
||||||
scope = "source.sshclientconfig"
|
scope = "source.sshclientconfig"
|
||||||
file-types = [{ glob = ".ssh/config" }, { glob = "/etc/ssh/ssh_config" }]
|
file-types = [{ glob = ".ssh/config" }, { glob = "/etc/ssh/ssh_config" }, { glob = "ssh_config.d/*.conf" } ]
|
||||||
comment-token = "#"
|
comment-token = "#"
|
||||||
|
|
||||||
[[grammar]]
|
[[grammar]]
|
||||||
@ -2793,7 +2822,7 @@ source = { git = "https://github.com/inko-lang/tree-sitter-inko", rev = "7860637
|
|||||||
[[language]]
|
[[language]]
|
||||||
name = "bicep"
|
name = "bicep"
|
||||||
scope = "source.bicep"
|
scope = "source.bicep"
|
||||||
file-types = ["bicep"]
|
file-types = ["bicep","bicepparam"]
|
||||||
auto-format = true
|
auto-format = true
|
||||||
comment-token = "//"
|
comment-token = "//"
|
||||||
block-comment-tokens = { start = "/*", end = "*/" }
|
block-comment-tokens = { start = "/*", end = "*/" }
|
||||||
@ -2802,7 +2831,7 @@ language-servers = [ "bicep-langserver" ]
|
|||||||
|
|
||||||
[[grammar]]
|
[[grammar]]
|
||||||
name = "bicep"
|
name = "bicep"
|
||||||
source = { git = "https://github.com/the-mikedavis/tree-sitter-bicep", rev = "d8e097fcfa143854861ef737161163a09cc2916b" }
|
source = { git = "https://github.com/tree-sitter-grammars/tree-sitter-bicep", rev = "0092c7d1bd6bb22ce0a6f78497d50ea2b87f19c0" }
|
||||||
|
|
||||||
[[language]]
|
[[language]]
|
||||||
name = "qml"
|
name = "qml"
|
||||||
@ -2983,7 +3012,7 @@ indent = { tab-width = 8, unit = " " }
|
|||||||
|
|
||||||
[[grammar]]
|
[[grammar]]
|
||||||
name = "nasm"
|
name = "nasm"
|
||||||
source = { git = "https://github.com/naclsn/tree-sitter-nasm", rev = "a0db15db6fcfb1bf2cc8702500e55e558825c48b" }
|
source = { git = "https://github.com/naclsn/tree-sitter-nasm", rev = "570f3d7be01fffc751237f4cfcf52d04e20532d1" }
|
||||||
|
|
||||||
[[language]]
|
[[language]]
|
||||||
name = "gas"
|
name = "gas"
|
||||||
@ -3316,7 +3345,7 @@ indent = { tab-width = 4, unit = " " }
|
|||||||
|
|
||||||
[[grammar]]
|
[[grammar]]
|
||||||
name = "unison"
|
name = "unison"
|
||||||
source = { git = "https://github.com/kylegoetz/tree-sitter-unison", rev = "1f505e2447fa876a87aee47ff3d70b9e141c744f" }
|
source = { git = "https://github.com/kylegoetz/tree-sitter-unison", rev = "3c97db76d3cdbd002dfba493620c2d5df2fd6fa9" }
|
||||||
|
|
||||||
[[language]]
|
[[language]]
|
||||||
name = "todotxt"
|
name = "todotxt"
|
||||||
@ -3550,6 +3579,7 @@ roots = ["hyprland.conf"]
|
|||||||
file-types = [ { glob = "hyprland.conf" }, { glob = "hyprpaper.conf" }, { glob = "hypridle.conf" }, { glob = "hyprlock.conf" } ]
|
file-types = [ { glob = "hyprland.conf" }, { glob = "hyprpaper.conf" }, { glob = "hypridle.conf" }, { glob = "hyprlock.conf" } ]
|
||||||
comment-token = "#"
|
comment-token = "#"
|
||||||
grammar = "hyprlang"
|
grammar = "hyprlang"
|
||||||
|
language-servers = ["hyprls"]
|
||||||
|
|
||||||
[[grammar]]
|
[[grammar]]
|
||||||
name = "hyprlang"
|
name = "hyprlang"
|
||||||
@ -3839,11 +3869,15 @@ source = { git = "https://github.com/Decurity/tree-sitter-circom", rev = "021505
|
|||||||
name = "snakemake"
|
name = "snakemake"
|
||||||
scope = "source.snakemake"
|
scope = "source.snakemake"
|
||||||
roots = ["Snakefile", "config.yaml", "environment.yaml", "workflow/"]
|
roots = ["Snakefile", "config.yaml", "environment.yaml", "workflow/"]
|
||||||
file-types = ["smk", "Snakefile"]
|
file-types = ["smk", { glob = "Snakefile" } ]
|
||||||
comment-tokens = ["#", "##"]
|
comment-tokens = ["#", "##"]
|
||||||
indent = { tab-width = 2, unit = " " }
|
indent = { tab-width = 2, unit = " " }
|
||||||
language-servers = ["pylsp" ]
|
language-servers = ["pylsp" ]
|
||||||
|
|
||||||
|
[language.formatter]
|
||||||
|
command = "snakefmt"
|
||||||
|
args = ["-"]
|
||||||
|
|
||||||
[[grammar]]
|
[[grammar]]
|
||||||
name = "snakemake"
|
name = "snakemake"
|
||||||
source = { git = "https://github.com/osthomas/tree-sitter-snakemake", rev = "e909815acdbe37e69440261ebb1091ed52e1dec6" }
|
source = { git = "https://github.com/osthomas/tree-sitter-snakemake", rev = "e909815acdbe37e69440261ebb1091ed52e1dec6" }
|
||||||
@ -3859,3 +3893,41 @@ indent = { tab-width = 4, unit = " " }
|
|||||||
[[grammar]]
|
[[grammar]]
|
||||||
name = "cylc"
|
name = "cylc"
|
||||||
source = { git = "https://github.com/elliotfontaine/tree-sitter-cylc", rev = "30dd40d9bf23912e4aefa93eeb4c7090bda3d0f6" }
|
source = { git = "https://github.com/elliotfontaine/tree-sitter-cylc", rev = "30dd40d9bf23912e4aefa93eeb4c7090bda3d0f6" }
|
||||||
|
|
||||||
|
[[language]]
|
||||||
|
name = "quint"
|
||||||
|
scope = "source.quint"
|
||||||
|
file-types = ["qnt"]
|
||||||
|
language-servers = ["quint-language-server"]
|
||||||
|
comment-token = "//"
|
||||||
|
block-comment-tokens = { start = "/*", end = "*/" }
|
||||||
|
indent = { tab-width = 2, unit = " " }
|
||||||
|
|
||||||
|
[[grammar]]
|
||||||
|
name = "quint"
|
||||||
|
source = { git = "https://github.com/gruhn/tree-sitter-quint", rev = "eebbd01edfeff6404778c92efe5554e42e506a18" }
|
||||||
|
|
||||||
|
[[language]]
|
||||||
|
name = "spade"
|
||||||
|
scope = "source.spade"
|
||||||
|
roots = ["swim.toml"]
|
||||||
|
file-types = ['spade']
|
||||||
|
injection-regex = "spade"
|
||||||
|
comment-tokens = ["//", "///"]
|
||||||
|
block-comment-tokens = [
|
||||||
|
{ start = "/*", end = "*/" },
|
||||||
|
{ start = "/**", end = "*/" },
|
||||||
|
]
|
||||||
|
language-servers = [ "spade-language-server" ]
|
||||||
|
indent = { tab-width = 4, unit = " " }
|
||||||
|
|
||||||
|
[language.auto-pairs]
|
||||||
|
'(' = ')'
|
||||||
|
'{' = '}'
|
||||||
|
'[' = ']'
|
||||||
|
'"' = '"'
|
||||||
|
'<' = '>'
|
||||||
|
|
||||||
|
[[grammar]]
|
||||||
|
name = "spade"
|
||||||
|
source = { git = "https://gitlab.com/spade-lang/tree-sitter-spade/", rev = "4d5b141017c61fe7e168e0a5c5721ee62b0d9572" }
|
||||||
|
24
pr.md
Normal file
24
pr.md
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
Syntax symbol pickers
|
||||||
|
==
|
||||||
|
|
||||||
|
This adds two new symbol picker commands that use tree-sitter rather than LSP. We run a new `symbols.scm` query across the file and extract tagged things like function definitions, types, classes, etc. For languages with unambiguous syntax this behaves roughly the same as the LSP symbol picker (`<space>s`). It's less precise though since we don't have semantic info about the language. For example it can easily produce false positives for C/C++ because of preprocessor magic.
|
||||||
|
|
||||||
|
The hope is to start introducing LSP-like features for navigation that can work without installing or running a language server. I made these two pickers in particular because I don't like LSP equivalents in ErlangLS - the document symbol picker can take a long time to show up during boot and the workspace symbol picker only searches for module names. The other motivation is to have some navigation features in cases when running a language server is too cumbersome - either to set up or because of resource constraints. For example `clangd` needs a fair amount of setup (`compile_commands.json`) that you might not want to do when quickly reading through a codebase.
|
||||||
|
|
||||||
|
GitHub already uses tree-sitter like this to provide [imprecise code navigation](https://docs.github.com/en/repositories/working-with-files/using-files/navigating-code-on-github#about-navigating-code-on-github). It should be possible to find definitions and references as well like `gd` and `gr` - this is left as a follow-up.
|
||||||
|
|
||||||
|
This PR also adds commands that either open the LSP symbol picker or the syntax one if a language server is not available. This way you can customize a language to not use the LSP symbol pickers, for example:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[[language]]
|
||||||
|
name = "erlang"
|
||||||
|
language-servers = [{ name = "erlang-ls", except-features = ["document-symbols", "workspace-symbols"] }]
|
||||||
|
```
|
||||||
|
|
||||||
|
and `<space>s` will use the syntax symbol picker, while `<space>s` on a Rust file will still prefer the language server.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Outstanding question - how closely should we try to match LSP symbol kind? Not at all? Should we have markup specific symbol kinds? (For example see markdown's `symbols.scm`).
|
||||||
|
|
||||||
|
Also this PR needs docs on writing `symbols.scm` queries.
|
@ -1,73 +1,232 @@
|
|||||||
; Keywords
|
; Includes
|
||||||
|
|
||||||
[
|
[
|
||||||
"module"
|
|
||||||
"var"
|
|
||||||
"param"
|
|
||||||
"import"
|
"import"
|
||||||
"resource"
|
"provider"
|
||||||
"existing"
|
"with"
|
||||||
"if"
|
"as"
|
||||||
"targetScope"
|
"from"
|
||||||
"output"
|
] @keyword.control.import
|
||||||
] @keyword
|
|
||||||
|
; Namespaces
|
||||||
|
(module_declaration
|
||||||
|
(identifier) @namespace)
|
||||||
|
|
||||||
|
; Builtins
|
||||||
|
(primitive_type) @type.builtin
|
||||||
|
|
||||||
|
((member_expression
|
||||||
|
object: (identifier) @type.builtin)
|
||||||
|
(#eq? @type.builtin "sys"))
|
||||||
|
|
||||||
; Functions
|
; Functions
|
||||||
|
(call_expression
|
||||||
|
function: (identifier) @function)
|
||||||
|
|
||||||
(decorator) @function.builtin
|
(user_defined_function
|
||||||
|
name: (identifier) @function)
|
||||||
|
|
||||||
(functionCall) @function
|
; Properties
|
||||||
|
(object_property
|
||||||
|
(identifier) @function.method
|
||||||
|
":" @punctuation.delimiter
|
||||||
|
(_))
|
||||||
|
|
||||||
(functionCall
|
(object_property
|
||||||
(functionArgument
|
(compatible_identifier) @function.method
|
||||||
(variableAccess) @variable))
|
":" @punctuation.delimiter
|
||||||
|
(_))
|
||||||
|
|
||||||
; Literals/Types
|
(property_identifier) @function.method
|
||||||
|
|
||||||
|
; Attributes
|
||||||
|
(decorator
|
||||||
|
"@" @attribute)
|
||||||
|
|
||||||
|
(decorator
|
||||||
|
(call_expression
|
||||||
|
(identifier) @attribute))
|
||||||
|
|
||||||
|
(decorator
|
||||||
|
(call_expression
|
||||||
|
(member_expression
|
||||||
|
object: (identifier) @attribute
|
||||||
|
property: (property_identifier) @attribute)))
|
||||||
|
|
||||||
|
; Types
|
||||||
|
(type_declaration
|
||||||
|
(identifier) @type)
|
||||||
|
|
||||||
|
(type_declaration
|
||||||
|
(identifier)
|
||||||
|
"="
|
||||||
|
(identifier) @type)
|
||||||
|
|
||||||
|
(type
|
||||||
|
(identifier) @type)
|
||||||
|
|
||||||
|
(resource_declaration
|
||||||
|
(identifier) @type)
|
||||||
|
|
||||||
|
(resource_expression
|
||||||
|
(identifier) @type)
|
||||||
|
|
||||||
|
; Parameters
|
||||||
|
(parameter_declaration
|
||||||
|
(identifier) @variable.parameter
|
||||||
|
(_))
|
||||||
|
|
||||||
|
(call_expression
|
||||||
|
function: (_)
|
||||||
|
(arguments
|
||||||
|
(identifier) @variable.parameter))
|
||||||
|
|
||||||
|
(call_expression
|
||||||
|
function: (_)
|
||||||
|
(arguments
|
||||||
|
(member_expression
|
||||||
|
object: (identifier) @variable.parameter)))
|
||||||
|
|
||||||
|
(parameter
|
||||||
|
.
|
||||||
|
(identifier) @variable.parameter)
|
||||||
|
|
||||||
|
; Variables
|
||||||
|
(variable_declaration
|
||||||
|
(identifier) @variable
|
||||||
|
(_))
|
||||||
|
|
||||||
|
(metadata_declaration
|
||||||
|
(identifier) @variable
|
||||||
|
(_))
|
||||||
|
|
||||||
|
(output_declaration
|
||||||
|
(identifier) @variable
|
||||||
|
(_))
|
||||||
|
|
||||||
|
(object_property
|
||||||
|
(_)
|
||||||
|
":"
|
||||||
|
(identifier) @variable)
|
||||||
|
|
||||||
|
(for_statement
|
||||||
|
"for"
|
||||||
|
(for_loop_parameters
|
||||||
|
(loop_variable) @variable
|
||||||
|
(loop_enumerator) @variable))
|
||||||
|
|
||||||
|
; Conditionals
|
||||||
|
"if" @keyword.conditional
|
||||||
|
|
||||||
|
(ternary_expression
|
||||||
|
"?" @keyword.control.conditional
|
||||||
|
":" @keyword.control.conditional)
|
||||||
|
|
||||||
|
; Loops
|
||||||
|
(for_statement
|
||||||
|
"for" @keyword.control.repeat
|
||||||
|
"in"
|
||||||
|
":" @punctuation.delimiter)
|
||||||
|
|
||||||
|
; Keywords
|
||||||
|
[
|
||||||
|
"module"
|
||||||
|
"metadata"
|
||||||
|
"output"
|
||||||
|
"param"
|
||||||
|
"resource"
|
||||||
|
"existing"
|
||||||
|
"targetScope"
|
||||||
|
"type"
|
||||||
|
"var"
|
||||||
|
"using"
|
||||||
|
"test"
|
||||||
|
] @keyword
|
||||||
|
|
||||||
|
"func" @keyword.function
|
||||||
|
|
||||||
|
"assert" @keyword.control.exception
|
||||||
|
|
||||||
|
; Operators
|
||||||
|
[
|
||||||
|
"+"
|
||||||
|
"-"
|
||||||
|
"*"
|
||||||
|
"/"
|
||||||
|
"%"
|
||||||
|
"||"
|
||||||
|
"&&"
|
||||||
|
"|"
|
||||||
|
"=="
|
||||||
|
"!="
|
||||||
|
"=~"
|
||||||
|
"!~"
|
||||||
|
">"
|
||||||
|
">="
|
||||||
|
"<="
|
||||||
|
"<"
|
||||||
|
"??"
|
||||||
|
"="
|
||||||
|
"!"
|
||||||
|
".?"
|
||||||
|
] @operator
|
||||||
|
|
||||||
|
(subscript_expression
|
||||||
|
"?" @operator)
|
||||||
|
|
||||||
|
(nullable_type
|
||||||
|
"?" @operator)
|
||||||
|
|
||||||
|
"in" @keyword.operator
|
||||||
|
|
||||||
|
; Literals
|
||||||
|
(string) @string
|
||||||
|
|
||||||
|
(escape_sequence) @constant.character
|
||||||
|
|
||||||
|
(number) @constant.number
|
||||||
|
|
||||||
|
(boolean) @constant.builtin.boolean
|
||||||
|
|
||||||
|
(null) @constant.builtin
|
||||||
|
|
||||||
|
; Misc
|
||||||
|
(compatible_identifier
|
||||||
|
"?" @punctuation.special)
|
||||||
|
|
||||||
|
(nullable_return_type) @punctuation.special
|
||||||
|
|
||||||
[
|
[
|
||||||
"("
|
|
||||||
")"
|
|
||||||
"["
|
|
||||||
"]"
|
|
||||||
"{"
|
"{"
|
||||||
"}"
|
"}"
|
||||||
] @punctuation.bracket
|
] @punctuation.bracket
|
||||||
|
|
||||||
(resourceDeclaration
|
[
|
||||||
(string
|
"["
|
||||||
(stringLiteral) @string.special))
|
"]"
|
||||||
|
] @punctuation.bracket
|
||||||
(moduleDeclaration
|
|
||||||
(string
|
|
||||||
(stringLiteral) @string.special))
|
|
||||||
|
|
||||||
[
|
[
|
||||||
(string)
|
"("
|
||||||
(stringLiteral)
|
")"
|
||||||
] @string
|
] @punctuation.bracket
|
||||||
|
|
||||||
(nullLiteral) @keyword
|
[
|
||||||
(booleanLiteral) @constant.builtin.boolean
|
"."
|
||||||
(integerLiteral) @constant.numeric.integer
|
":"
|
||||||
(comment) @comment
|
"::"
|
||||||
|
"=>"
|
||||||
|
] @punctuation.delimiter
|
||||||
|
|
||||||
(string
|
; Interpolation
|
||||||
(variableAccess
|
(interpolation
|
||||||
(identifier) @variable))
|
"${" @punctuation.special
|
||||||
|
"}" @punctuation.special)
|
||||||
|
|
||||||
(type) @type
|
(interpolation
|
||||||
|
(identifier) @variable)
|
||||||
|
|
||||||
; Variables
|
; Comments
|
||||||
|
[
|
||||||
(localVariable) @variable
|
(comment)
|
||||||
|
(diagnostic_comment)
|
||||||
; Statements
|
] @comment
|
||||||
|
|
||||||
(object
|
|
||||||
(objectProperty
|
|
||||||
(identifier) @identifier))
|
|
||||||
|
|
||||||
(propertyAccess
|
|
||||||
(identifier) @identifier)
|
|
||||||
|
|
||||||
(ifCondition) @keyword.control.conditional
|
|
||||||
|
@ -21,10 +21,10 @@
|
|||||||
|
|
||||||
; Error level tags
|
; Error level tags
|
||||||
((tag (name) @error)
|
((tag (name) @error)
|
||||||
(#match? @error "^(BUG|FIXME|ISSUE|XXX|FIX|SAFETY|FIXIT|FAILED|DEBUG)$"))
|
(#match? @error "^(BUG|FIXME|ISSUE|XXX|FIX|SAFETY|FIXIT|FAILED|DEBUG|INVARIANT)$"))
|
||||||
|
|
||||||
("text" @error
|
("text" @error
|
||||||
(#match? @error "^(BUG|FIXME|ISSUE|XXX|FIX|SAFETY|FIXIT|FAILED|DEBUG)$"))
|
(#match? @error "^(BUG|FIXME|ISSUE|XXX|FIX|SAFETY|FIXIT|FAILED|DEBUG|INVARIANT)$"))
|
||||||
|
|
||||||
(tag
|
(tag
|
||||||
(name) @ui.text
|
(name) @ui.text
|
||||||
|
@ -75,11 +75,16 @@
|
|||||||
"pre-instr-symbol"
|
"pre-instr-symbol"
|
||||||
"post-instr-symbol"
|
"post-instr-symbol"
|
||||||
"heap-alloc-marker"
|
"heap-alloc-marker"
|
||||||
|
"pcsections"
|
||||||
|
"mmra"
|
||||||
|
"cfi-type"
|
||||||
"debug-instr-number"
|
"debug-instr-number"
|
||||||
"debug-location"
|
"debug-location"
|
||||||
|
"dbg-instr-ref"
|
||||||
"mcsymbol"
|
"mcsymbol"
|
||||||
"tied-def"
|
"tied-def"
|
||||||
"target-flags"
|
"target-flags"
|
||||||
|
"vscale"
|
||||||
"CustomRegMask"
|
"CustomRegMask"
|
||||||
"same_value"
|
"same_value"
|
||||||
"def_cfa_register"
|
"def_cfa_register"
|
||||||
@ -118,11 +123,16 @@
|
|||||||
"got"
|
"got"
|
||||||
"jump-table"
|
"jump-table"
|
||||||
"syncscope"
|
"syncscope"
|
||||||
"address-taken"
|
"machine-block-address-taken"
|
||||||
|
"ir-block-address-taken"
|
||||||
"landing-pad"
|
"landing-pad"
|
||||||
"inlineasm-br-indirect-target"
|
"inlineasm-br-indirect-target"
|
||||||
"ehfunclet-entry"
|
"ehfunclet-entry"
|
||||||
|
"bb_id"
|
||||||
|
"call-frame-size"
|
||||||
"bbsections"
|
"bbsections"
|
||||||
|
"Exception"
|
||||||
|
"Cold"
|
||||||
|
|
||||||
(intpred)
|
(intpred)
|
||||||
(floatpred)
|
(floatpred)
|
||||||
|
@ -17,9 +17,11 @@
|
|||||||
|
|
||||||
[
|
[
|
||||||
"to"
|
"to"
|
||||||
|
"nneg"
|
||||||
"nuw"
|
"nuw"
|
||||||
"nsw"
|
"nsw"
|
||||||
"exact"
|
"exact"
|
||||||
|
"disjoint"
|
||||||
"unwind"
|
"unwind"
|
||||||
"from"
|
"from"
|
||||||
"cleanup"
|
"cleanup"
|
||||||
|
1
runtime/queries/nestedtext/highlights.scm
Normal file
1
runtime/queries/nestedtext/highlights.scm
Normal file
@ -0,0 +1 @@
|
|||||||
|
; inherits: yaml
|
1
runtime/queries/nestedtext/indents.scm
Normal file
1
runtime/queries/nestedtext/indents.scm
Normal file
@ -0,0 +1 @@
|
|||||||
|
; inherits: yaml
|
1
runtime/queries/nestedtext/injections.scm
Normal file
1
runtime/queries/nestedtext/injections.scm
Normal file
@ -0,0 +1 @@
|
|||||||
|
; inherits: yaml
|
1
runtime/queries/nestedtext/textobjects.scm
Normal file
1
runtime/queries/nestedtext/textobjects.scm
Normal file
@ -0,0 +1 @@
|
|||||||
|
; inherits: yaml
|
@ -127,6 +127,16 @@
|
|||||||
(#set! injection.language "haskell")
|
(#set! injection.language "haskell")
|
||||||
(#set! injection.combined))
|
(#set! injection.combined))
|
||||||
|
|
||||||
|
; pkgs.writers.writeNim[Bin] name attrs content
|
||||||
|
(apply_expression
|
||||||
|
(apply_expression
|
||||||
|
function: (apply_expression
|
||||||
|
function: ((_) @_func)))
|
||||||
|
argument: (indented_string_expression (string_fragment) @injection.content)
|
||||||
|
(#match? @_func "(^|\\.)writeNim(Bin)?$")
|
||||||
|
(#set! injection.language "nim")
|
||||||
|
(#set! injection.combined))
|
||||||
|
|
||||||
; pkgs.writers.writeJS[Bin] name attrs content
|
; pkgs.writers.writeJS[Bin] name attrs content
|
||||||
(apply_expression
|
(apply_expression
|
||||||
(apply_expression
|
(apply_expression
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
[
|
[
|
||||||
"use" "no" "require" "package"
|
"use" "no" "require" "package" "class" "role"
|
||||||
] @keyword.control.import
|
] @keyword.control.import
|
||||||
|
|
||||||
[
|
[
|
||||||
"sub"
|
"sub" "method" "async" "extended"
|
||||||
] @keyword.function
|
] @keyword.function
|
||||||
|
|
||||||
[
|
[
|
||||||
@ -17,7 +17,7 @@
|
|||||||
] @keyword.control.repeat
|
] @keyword.control.repeat
|
||||||
|
|
||||||
[
|
[
|
||||||
"my" "our" "local"
|
"my" "our" "local" "state"
|
||||||
] @keyword.storage.modifier
|
] @keyword.storage.modifier
|
||||||
|
|
||||||
[
|
[
|
||||||
@ -29,9 +29,10 @@
|
|||||||
] @constant.builtin
|
] @constant.builtin
|
||||||
|
|
||||||
(phaser_statement phase: _ @keyword.directive)
|
(phaser_statement phase: _ @keyword.directive)
|
||||||
|
(class_phaser_statement phase: _ @keyword.directive)
|
||||||
|
|
||||||
[
|
[
|
||||||
"or" "and"
|
"or" "xor" "and"
|
||||||
"eq" "ne" "cmp" "lt" "le" "ge" "gt"
|
"eq" "ne" "cmp" "lt" "le" "ge" "gt"
|
||||||
"isa"
|
"isa"
|
||||||
] @keyword.operator
|
] @keyword.operator
|
||||||
@ -55,7 +56,7 @@
|
|||||||
|
|
||||||
[(quoted_regexp) (match_regexp)] @string.regexp
|
[(quoted_regexp) (match_regexp)] @string.regexp
|
||||||
|
|
||||||
(autoquoted_bareword _?) @string.special
|
(autoquoted_bareword) @string.special
|
||||||
|
|
||||||
[(scalar) (arraylen)] @variable
|
[(scalar) (arraylen)] @variable
|
||||||
(scalar_deref_expression ["->" "$" "*"] @variable)
|
(scalar_deref_expression ["->" "$" "*"] @variable)
|
||||||
|
94
runtime/queries/quint/highlights.scm
Normal file
94
runtime/queries/quint/highlights.scm
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
[
|
||||||
|
"module"
|
||||||
|
"type"
|
||||||
|
"assume"
|
||||||
|
"const"
|
||||||
|
"var"
|
||||||
|
"val"
|
||||||
|
"nondet"
|
||||||
|
"def"
|
||||||
|
"pure"
|
||||||
|
"action"
|
||||||
|
"temporal"
|
||||||
|
"run"
|
||||||
|
] @keyword
|
||||||
|
|
||||||
|
(match_expr "match" @keyword.control.conditional)
|
||||||
|
|
||||||
|
(if_else_condition
|
||||||
|
"if" @keyword.control.conditional
|
||||||
|
"else" @keyword.control.conditional)
|
||||||
|
|
||||||
|
(import "import" @keyword.control.import)
|
||||||
|
(import "as" @keyword.control.import)
|
||||||
|
(import "from" @keyword.control.import)
|
||||||
|
(export "export" @keyword.control.import)
|
||||||
|
(export "as" @keyword.control.import)
|
||||||
|
|
||||||
|
[
|
||||||
|
"true"
|
||||||
|
"false"
|
||||||
|
"Int"
|
||||||
|
"Nat"
|
||||||
|
"Bool"
|
||||||
|
] @constant.builtin
|
||||||
|
|
||||||
|
[
|
||||||
|
";"
|
||||||
|
"."
|
||||||
|
","
|
||||||
|
] @punctuation.delimiter
|
||||||
|
|
||||||
|
[
|
||||||
|
"-"
|
||||||
|
"+"
|
||||||
|
"*"
|
||||||
|
"/"
|
||||||
|
"%"
|
||||||
|
"<"
|
||||||
|
"<="
|
||||||
|
"="
|
||||||
|
"=="
|
||||||
|
"!="
|
||||||
|
"=>"
|
||||||
|
">"
|
||||||
|
">="
|
||||||
|
"^"
|
||||||
|
"->"
|
||||||
|
] @operator
|
||||||
|
|
||||||
|
(infix_and "and" @operator)
|
||||||
|
(infix_or "or" @operator)
|
||||||
|
(infix_iff "iff" @operator)
|
||||||
|
(infix_implies "implies" @operator)
|
||||||
|
|
||||||
|
(braced_and "and" @keyword)
|
||||||
|
(braced_or "or" @keyword)
|
||||||
|
(braced_all "all" @keyword)
|
||||||
|
(braced_any "any" @keyword)
|
||||||
|
|
||||||
|
[
|
||||||
|
"("
|
||||||
|
")"
|
||||||
|
"["
|
||||||
|
"]"
|
||||||
|
"{"
|
||||||
|
"}"
|
||||||
|
] @punctuation.bracket
|
||||||
|
|
||||||
|
(polymorphic_type
|
||||||
|
(type) @type.parameter)
|
||||||
|
|
||||||
|
(variant_constructor) @type.enum.variant
|
||||||
|
|
||||||
|
(type) @type
|
||||||
|
(int_literal) @constant.numeric.integer
|
||||||
|
(comment) @comment
|
||||||
|
(string) @string
|
||||||
|
|
||||||
|
(operator_application
|
||||||
|
operator: (qualified_identifier) @function)
|
||||||
|
|
||||||
|
(operator_definition
|
||||||
|
name: (qualified_identifier) @function
|
||||||
|
arguments: (typed_argument_list))
|
@ -10,11 +10,10 @@
|
|||||||
[
|
[
|
||||||
(type_identifier)
|
(type_identifier)
|
||||||
(unit_type)
|
(unit_type)
|
||||||
|
(list)
|
||||||
|
(list_pattern)
|
||||||
] @type
|
] @type
|
||||||
|
|
||||||
(list ["list{" "}"] @type)
|
|
||||||
(list_pattern ["list{" "}"] @type)
|
|
||||||
|
|
||||||
[
|
[
|
||||||
(variant_identifier)
|
(variant_identifier)
|
||||||
(polyvar_identifier)
|
(polyvar_identifier)
|
||||||
@ -72,14 +71,16 @@
|
|||||||
; single parameter with no parens
|
; single parameter with no parens
|
||||||
(function parameter: (value_identifier) @variable.parameter)
|
(function parameter: (value_identifier) @variable.parameter)
|
||||||
|
|
||||||
|
; first-level descructuring (required for nvim-tree-sitter as it only matches direct
|
||||||
|
; children and the above patterns do not match destructuring patterns in NeoVim)
|
||||||
|
(parameter (tuple_pattern (tuple_item_pattern (value_identifier) @variable.parameter)))
|
||||||
|
(parameter (array_pattern (value_identifier) @variable.parameter))
|
||||||
|
(parameter (record_pattern (value_identifier) @variable.parameter))
|
||||||
|
|
||||||
; Meta
|
; Meta
|
||||||
;-----
|
;-----
|
||||||
|
|
||||||
[
|
(decorator_identifier) @keyword.directive
|
||||||
"@"
|
|
||||||
"@@"
|
|
||||||
(decorator_identifier)
|
|
||||||
] @keyword.directive
|
|
||||||
|
|
||||||
(extension_identifier) @keyword
|
(extension_identifier) @keyword
|
||||||
("%") @keyword
|
("%") @keyword
|
||||||
@ -87,7 +88,7 @@
|
|||||||
; Misc
|
; Misc
|
||||||
;-----
|
;-----
|
||||||
|
|
||||||
; (subscript_expression index: (string) @attribute)
|
(subscript_expression index: (string) @attribute)
|
||||||
(polyvar_type_pattern "#" @constant)
|
(polyvar_type_pattern "#" @constant)
|
||||||
|
|
||||||
[
|
[
|
||||||
@ -101,18 +102,21 @@
|
|||||||
"external"
|
"external"
|
||||||
"let"
|
"let"
|
||||||
"module"
|
"module"
|
||||||
|
"mutable"
|
||||||
"private"
|
"private"
|
||||||
"rec"
|
"rec"
|
||||||
"type"
|
"type"
|
||||||
"and"
|
"and"
|
||||||
"assert"
|
"assert"
|
||||||
"async"
|
|
||||||
"await"
|
"await"
|
||||||
"with"
|
"with"
|
||||||
"unpack"
|
"lazy"
|
||||||
] @keyword.storage.type
|
"constraint"
|
||||||
|
] @keyword
|
||||||
|
|
||||||
"mutable" @keyword.storage.modifier
|
((function "async" @keyword.storage))
|
||||||
|
|
||||||
|
(module_unpack "unpack" @keyword)
|
||||||
|
|
||||||
[
|
[
|
||||||
"if"
|
"if"
|
||||||
@ -169,6 +173,7 @@
|
|||||||
"->"
|
"->"
|
||||||
"|>"
|
"|>"
|
||||||
":>"
|
":>"
|
||||||
|
"+="
|
||||||
(uncurry)
|
(uncurry)
|
||||||
] @operator
|
] @operator
|
||||||
|
|
||||||
|
@ -1,8 +1,29 @@
|
|||||||
((comment) @injection.content
|
((comment) @injection.content (#set! injection.language "comment"))
|
||||||
(#set! injection.language "comment"))
|
|
||||||
|
|
||||||
((raw_js) @injection.content
|
; %re
|
||||||
(#set! injection.language "javascript"))
|
(extension_expression
|
||||||
|
(extension_identifier) @_name
|
||||||
|
(#eq? @_name "re")
|
||||||
|
(expression_statement (_) @injection.content (#set! injection.language "regex")))
|
||||||
|
|
||||||
|
; %raw
|
||||||
|
(extension_expression
|
||||||
|
(extension_identifier) @_name
|
||||||
|
(#eq? @_name "raw")
|
||||||
|
(expression_statement
|
||||||
|
(_ (_) @injection.content (#set! injection.language "javascript"))))
|
||||||
|
|
||||||
|
; %graphql
|
||||||
|
(extension_expression
|
||||||
|
(extension_identifier) @_name
|
||||||
|
(#eq? @_name "graphql")
|
||||||
|
(expression_statement
|
||||||
|
(_ (_) @injection.content (#set! injection.language "graphql"))))
|
||||||
|
|
||||||
|
; %relay
|
||||||
|
(extension_expression
|
||||||
|
(extension_identifier) @_name
|
||||||
|
(#eq? @_name "relay")
|
||||||
|
(expression_statement
|
||||||
|
(_ (_) @injection.content (#set! injection.language "graphql") )))
|
||||||
|
|
||||||
((raw_gql) @injection.content
|
|
||||||
(#set! injection.language "graphql"))
|
|
@ -1,7 +1,7 @@
|
|||||||
(switch_expression) @local.scope
|
(switch_expression) @local.scope
|
||||||
(if_expression) @local.scope
|
|
||||||
|
|
||||||
; Definitions
|
; Definitions
|
||||||
;------------
|
;------------
|
||||||
(type_declaration) @local.defintion
|
(type_declaration) @local.definition
|
||||||
(let_binding) @local.defintion
|
(let_binding) @local.definition
|
||||||
|
(module_declaration) @local.definition
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
; Classes (modules)
|
; Classes (modules)
|
||||||
;------------------
|
;------------------
|
||||||
|
|
||||||
(module_declaration definition: ((_) @class.inside)) @class.around
|
(module_binding definition: ((_) @class.inside)) @class.around
|
||||||
|
|
||||||
; Blocks
|
; Blocks
|
||||||
;-------
|
;-------
|
||||||
|
130
runtime/queries/spade/highlights.scm
Normal file
130
runtime/queries/spade/highlights.scm
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
(self) @variable.builtin
|
||||||
|
|
||||||
|
(unit_definition (identifier) @function)
|
||||||
|
|
||||||
|
(parameter (identifier) @variable.parameter)
|
||||||
|
|
||||||
|
((pipeline_reg_marker) @keyword)
|
||||||
|
|
||||||
|
(scoped_identifier
|
||||||
|
path: (identifier) @namespace)
|
||||||
|
(scoped_identifier
|
||||||
|
(scoped_identifier
|
||||||
|
name: (identifier) @namespace))
|
||||||
|
|
||||||
|
((builtin_type) @type.builtin)
|
||||||
|
|
||||||
|
((identifier) @type.builtin
|
||||||
|
(#any-of?
|
||||||
|
@type.builtin
|
||||||
|
"uint"
|
||||||
|
"Option"
|
||||||
|
"Memory"))
|
||||||
|
|
||||||
|
((identifier) @type.enum.variant.builtin
|
||||||
|
(#any-of? @type.enum.variant.builtin "Some" "None"))
|
||||||
|
|
||||||
|
((pipeline_stage_name) @label)
|
||||||
|
|
||||||
|
((stage_reference
|
||||||
|
stage: (identifier) @label))
|
||||||
|
|
||||||
|
[
|
||||||
|
"pipeline"
|
||||||
|
"let"
|
||||||
|
"set"
|
||||||
|
"entity"
|
||||||
|
"fn"
|
||||||
|
"reg"
|
||||||
|
"reset"
|
||||||
|
"initial"
|
||||||
|
"inst"
|
||||||
|
"assert"
|
||||||
|
"struct"
|
||||||
|
"enum"
|
||||||
|
"stage"
|
||||||
|
"impl"
|
||||||
|
"port"
|
||||||
|
"decl"
|
||||||
|
"mod"
|
||||||
|
"where"
|
||||||
|
"trait"
|
||||||
|
] @keyword
|
||||||
|
|
||||||
|
[
|
||||||
|
"use"
|
||||||
|
] @keyword.import
|
||||||
|
|
||||||
|
[
|
||||||
|
"$if"
|
||||||
|
"$else"
|
||||||
|
"$config"
|
||||||
|
] @keyword.directive
|
||||||
|
|
||||||
|
((comptime_if ["{" "}"] @keyword.directive))
|
||||||
|
((comptime_else ["{" "}"] @keyword.directive))
|
||||||
|
|
||||||
|
((attribute) ["#" "[" "]"] @punctuation.delimiter)
|
||||||
|
|
||||||
|
[
|
||||||
|
"else"
|
||||||
|
"if"
|
||||||
|
"match"
|
||||||
|
] @keyword.control.conditional
|
||||||
|
|
||||||
|
(bool_literal) @constant.builtin.boolean
|
||||||
|
(int_literal) @constant.numeric.integer
|
||||||
|
|
||||||
|
[
|
||||||
|
"&"
|
||||||
|
"inv"
|
||||||
|
"-"
|
||||||
|
"=>"
|
||||||
|
">"
|
||||||
|
"<"
|
||||||
|
"::<"
|
||||||
|
"::$<"
|
||||||
|
"="
|
||||||
|
"->"
|
||||||
|
"~"
|
||||||
|
"!"
|
||||||
|
] @operator
|
||||||
|
|
||||||
|
|
||||||
|
((op_add) @operator)
|
||||||
|
((op_sub) @operator)
|
||||||
|
((op_mul) @operator)
|
||||||
|
((op_equals) @operator)
|
||||||
|
((op_lt) @operator)
|
||||||
|
((op_gt) @operator)
|
||||||
|
((op_le) @operator)
|
||||||
|
((op_ge) @operator)
|
||||||
|
((op_lshift) @operator)
|
||||||
|
((op_rshift) @operator)
|
||||||
|
((op_bitwise_and) @operator)
|
||||||
|
((op_bitwise_xor) @operator)
|
||||||
|
((op_bitwise_or) @operator)
|
||||||
|
((op_logical_and) @operator)
|
||||||
|
((op_logical_or) @operator)
|
||||||
|
|
||||||
|
|
||||||
|
[
|
||||||
|
(line_comment)
|
||||||
|
(block_comment)
|
||||||
|
] @comment
|
||||||
|
|
||||||
|
[
|
||||||
|
(doc_comment)
|
||||||
|
] @comment.block.documentation
|
||||||
|
|
||||||
|
|
||||||
|
((identifier) @type
|
||||||
|
(#match? @type "[A-Z]"))
|
||||||
|
|
||||||
|
((scoped_identifier
|
||||||
|
name: (identifier) @type)
|
||||||
|
(#match? @type "^[A-Z]"))
|
||||||
|
|
||||||
|
((identifier) @constant
|
||||||
|
(#match? @constant "^[A-Z][A-Z\\d_]*$"))
|
||||||
|
|
27
runtime/queries/spade/indents.scm
Normal file
27
runtime/queries/spade/indents.scm
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
[
|
||||||
|
(unit_definition)
|
||||||
|
(struct_definition)
|
||||||
|
(enum_definition)
|
||||||
|
(enum_member)
|
||||||
|
(impl)
|
||||||
|
(mod)
|
||||||
|
(argument_list)
|
||||||
|
(let_binding)
|
||||||
|
(block)
|
||||||
|
(tuple_literal)
|
||||||
|
(array_literal)
|
||||||
|
(paren_expression)
|
||||||
|
(turbofish)
|
||||||
|
(generic_parameters)
|
||||||
|
(named_unpack)
|
||||||
|
(positional_unpack)
|
||||||
|
(tuple_pattern)
|
||||||
|
] @indent
|
||||||
|
|
||||||
|
[
|
||||||
|
"}"
|
||||||
|
"]"
|
||||||
|
")"
|
||||||
|
] @outdent
|
||||||
|
|
@ -68,7 +68,9 @@
|
|||||||
"def"
|
"def"
|
||||||
"defset"
|
"defset"
|
||||||
"defvar"
|
"defvar"
|
||||||
|
"deftype"
|
||||||
"assert"
|
"assert"
|
||||||
|
"dump"
|
||||||
] @keyword
|
] @keyword
|
||||||
|
|
||||||
[
|
[
|
||||||
|
22
runtime/queries/textproto/highlights.scm
Normal file
22
runtime/queries/textproto/highlights.scm
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
(string) @string
|
||||||
|
|
||||||
|
(field_name) @variable.other.member
|
||||||
|
|
||||||
|
(comment) @comment
|
||||||
|
|
||||||
|
(number) @constant.numeric
|
||||||
|
; covers e.g. booleans and "inf"
|
||||||
|
(scalar_value (identifier)) @constant
|
||||||
|
; Covers "-inf"
|
||||||
|
(scalar_value (signed_identifier)) @constant.numeric
|
||||||
|
|
||||||
|
[
|
||||||
|
(open_squiggly)
|
||||||
|
(close_squiggly)
|
||||||
|
(open_square)
|
||||||
|
(close_square)
|
||||||
|
(open_arrow)
|
||||||
|
(close_arrow)
|
||||||
|
] @punctuation.bracket
|
||||||
|
|
||||||
|
"," @punctuation.delimiter
|
11
runtime/queries/textproto/indents.scm
Normal file
11
runtime/queries/textproto/indents.scm
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
[
|
||||||
|
(message_value)
|
||||||
|
(message_list)
|
||||||
|
(scalar_list)
|
||||||
|
] @indent
|
||||||
|
|
||||||
|
[
|
||||||
|
(close_arrow)
|
||||||
|
(close_square)
|
||||||
|
(close_squiggly)
|
||||||
|
] @outdent
|
12
runtime/queries/textproto/textobjects.scm
Normal file
12
runtime/queries/textproto/textobjects.scm
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
(message_field
|
||||||
|
(_) @entry.inside) @entry.around
|
||||||
|
|
||||||
|
(scalar_field
|
||||||
|
(_) @entry.inside) @entry.around
|
||||||
|
|
||||||
|
(message_list
|
||||||
|
(_) @entry.around)
|
||||||
|
|
||||||
|
(scalar_list
|
||||||
|
(_) @entry.around)
|
||||||
|
|
@ -9,32 +9,25 @@
|
|||||||
;; Keywords
|
;; Keywords
|
||||||
[
|
[
|
||||||
(kw_forall)
|
(kw_forall)
|
||||||
(type_kw)
|
|
||||||
(kw_equals)
|
(kw_equals)
|
||||||
(do)
|
(do)
|
||||||
|
(kw_let)
|
||||||
(ability)
|
(ability)
|
||||||
(where)
|
(where)
|
||||||
] @keyword
|
] @keyword
|
||||||
|
|
||||||
(kw_let) @keyword.function
|
(kw_let) @keyword.function
|
||||||
(type_kw) @keyword.storage.type
|
(type_kw) @keyword.storage.modifier
|
||||||
(unique) @keyword.storage.modifier
|
|
||||||
(structural) @keyword.storage.modifier
|
(structural) @keyword.storage.modifier
|
||||||
("use") @keyword.control.import
|
("use") @keyword.control.import
|
||||||
|
(unique) @keyword.storage.modifier
|
||||||
|
|
||||||
[
|
|
||||||
(type_constructor)
|
|
||||||
] @constructor
|
|
||||||
|
|
||||||
[
|
[
|
||||||
(operator)
|
(operator)
|
||||||
(pipe)
|
(pipe)
|
||||||
(arrow_symbol)
|
(arrow_symbol)
|
||||||
(">")
|
|
||||||
(or)
|
(or)
|
||||||
(and)
|
(and)
|
||||||
(bang)
|
|
||||||
] @operator
|
] @operator
|
||||||
|
|
||||||
[
|
[
|
||||||
@ -48,24 +41,62 @@
|
|||||||
|
|
||||||
(blank_pattern) @variable.builtin
|
(blank_pattern) @variable.builtin
|
||||||
|
|
||||||
|
(pattern) @variable
|
||||||
|
|
||||||
|
(use_clause) @keyword.import
|
||||||
|
|
||||||
;; Types
|
;; Types
|
||||||
(record_field name: (wordy_id) @variable.other.member type: (_) @type)
|
(record_field
|
||||||
(type_constructor (type_name (wordy_id) @constructor))
|
(field_name) @variable.other.member
|
||||||
(ability_declaration type_name: (wordy_id) @type type_arg: (wordy_id) @variable.parameter)
|
type: (regular_identifier) @type)
|
||||||
(effect (wordy_id) @special) ;; NOTE: an effect is just like a type, but in signature we special case it
|
|
||||||
|
|
||||||
;; Namespaces
|
(type_name) @type
|
||||||
(path) @namespace
|
|
||||||
(namespace) @namespace
|
|
||||||
|
|
||||||
;; Terms
|
(type_declaration
|
||||||
(type_signature term_name: (path)? @variable term_name: (wordy_id) @variable)
|
(regular_identifier) @type.enum.variant)
|
||||||
(type_signature (wordy_id) @type)
|
|
||||||
(type_signature (term_type(delayed(wordy_id))) @type)
|
|
||||||
|
|
||||||
(term_definition param: (wordy_id) @variable.parameter)
|
(ability_name
|
||||||
|
(path)? @namespace
|
||||||
|
(regular_identifier) @type)
|
||||||
|
|
||||||
(function_application function_name: (path)? function_name: (wordy_id) @function)
|
(ability_declaration
|
||||||
|
(ability_name) @type
|
||||||
|
(type_argument) @variable.parameter)
|
||||||
|
|
||||||
|
(type_constructor) @constructor
|
||||||
|
|
||||||
|
(constructor
|
||||||
|
(constructor_name) @constructor)
|
||||||
|
|
||||||
|
(constructor
|
||||||
|
type: (regular_identifier) @type)
|
||||||
|
|
||||||
|
(effect
|
||||||
|
(regular_identifier) @special) ; NOTE: an effect is a special type
|
||||||
|
|
||||||
|
; Namespaces
|
||||||
|
(path) @module
|
||||||
|
|
||||||
|
(namespace) @module
|
||||||
|
|
||||||
|
; Terms
|
||||||
|
(type_signature
|
||||||
|
term_name: (path) @module
|
||||||
|
term_name: (regular_identifier) @variable)
|
||||||
|
|
||||||
|
(type_signature
|
||||||
|
term_name: (regular_identifier) @variable)
|
||||||
|
|
||||||
|
(term_type) @type
|
||||||
|
|
||||||
|
(term_definition
|
||||||
|
name: (path) @namespace)
|
||||||
|
|
||||||
|
(term_definition
|
||||||
|
name: (regular_identifier) @variable)
|
||||||
|
|
||||||
|
(term_definition
|
||||||
|
param: (regular_identifier) @variable.parameter)
|
||||||
|
|
||||||
;; Punctuation
|
;; Punctuation
|
||||||
[
|
[
|
||||||
@ -82,4 +113,6 @@
|
|||||||
"]"
|
"]"
|
||||||
] @punctuation.bracket
|
] @punctuation.bracket
|
||||||
|
|
||||||
(test_watch_expression (wordy_id) @keyword.directive)
|
(watch_expression) @keyword.directive
|
||||||
|
|
||||||
|
(test_watch_expression) @keyword.directive
|
||||||
|
@ -1,11 +1,6 @@
|
|||||||
[
|
[
|
||||||
(term_definition)
|
(term_definition)
|
||||||
(type_declaration)
|
|
||||||
(pattern)
|
(pattern)
|
||||||
(tuple_or_parenthesized)
|
|
||||||
(literal_list)
|
|
||||||
(tuple_pattern)
|
|
||||||
(function_application)
|
|
||||||
(exp_if)
|
(exp_if)
|
||||||
(constructor)
|
(constructor)
|
||||||
(delay_block)
|
(delay_block)
|
||||||
|
15
runtime/queries/unison/textobjects.scm
Normal file
15
runtime/queries/unison/textobjects.scm
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
(term_declaration) @function.around
|
||||||
|
|
||||||
|
(type_declaration) @class.inside
|
||||||
|
(record) @class.inside
|
||||||
|
|
||||||
|
(comment) @comment.inside
|
||||||
|
(comment)+ @comment.around
|
||||||
|
|
||||||
|
(doc_block) @comment.around
|
||||||
|
|
||||||
|
(literal_list) @entry.around
|
||||||
|
|
||||||
|
(parenthesized_or_tuple_pattern) @entry.around
|
||||||
|
|
||||||
|
(pattern) @entry.around
|
110
runtime/themes/adwaita-light.toml
Normal file
110
runtime/themes/adwaita-light.toml
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
inherits="adwaita-dark"
|
||||||
|
"attribute" = "orange_5"
|
||||||
|
|
||||||
|
"type" = "teal_4"
|
||||||
|
"type.builtin" = "teal_4"
|
||||||
|
|
||||||
|
"constructor" = "blue_4"
|
||||||
|
|
||||||
|
"constant" = "violet_4"
|
||||||
|
"constant.builtin" = { fg = "violet_4", modifiers = ["bold"] }
|
||||||
|
"constant.character" = "teal_5"
|
||||||
|
"constant.numeric" = { fg = "teal_5", modifiers = ["bold"] }
|
||||||
|
"constant.character.escape" = "violet_4"
|
||||||
|
|
||||||
|
"string" = "teal_3"
|
||||||
|
"string.regexp" = "purple_4"
|
||||||
|
"string.special" = "blue_4"
|
||||||
|
|
||||||
|
"comment" = "light_6"
|
||||||
|
|
||||||
|
"variable" = "dark_5"
|
||||||
|
"variable.parameter" = "orange_4"
|
||||||
|
"variable.builtin" = "orange_4"
|
||||||
|
"variable.other" = "teal_4"
|
||||||
|
"variable.other.member" = "teal_5"
|
||||||
|
|
||||||
|
"label" = "purple_4"
|
||||||
|
|
||||||
|
"punctuation" = "dark_4"
|
||||||
|
"punctuation.delimiter" = "dark_4"
|
||||||
|
"punctuation.bracket" = "dark_4"
|
||||||
|
"punctuation.special" = "red_5"
|
||||||
|
|
||||||
|
"keyword" = { fg = "orange_4", modifiers = ["bold"] }
|
||||||
|
"keyword.control" = { fg = "orange_4", modifiers = ["bold"] }
|
||||||
|
"keyword.operator" = "purple_4"
|
||||||
|
"keyword.directive" = { fg = "orange_4", modifiers = ["bold"] }
|
||||||
|
"keyword.function" = "orange_4"
|
||||||
|
"keyword.storage" = { fg = "orange_4", modifiers = ["bold"] }
|
||||||
|
|
||||||
|
"operator" = "purple_4"
|
||||||
|
|
||||||
|
"function" = "blue_4"
|
||||||
|
"function.builtin" = "blue_4"
|
||||||
|
"function.macro" = { fg = "blue_4", modifiers = ["bold"] }
|
||||||
|
"function.special" = { fg = "blue_4", modifiers = ["bold"] }
|
||||||
|
|
||||||
|
"tag" = "teal_4"
|
||||||
|
|
||||||
|
"namespace" = "orange_4"
|
||||||
|
|
||||||
|
"markup" = "dark_4"
|
||||||
|
"markup.heading" = { fg = "teal_4", modifiers = ["bold"] }
|
||||||
|
"markup.list" = { fg = "orange_4", modifiers = ["bold"] }
|
||||||
|
"markup.bold" = { fg = "dark_4", modifiers = ["bold"] }
|
||||||
|
"markup.italic" = { fg = "dark_4", modifiers = ["italic"] }
|
||||||
|
"markup.link" = { fg = "blue_5", modifiers = ["underlined"] }
|
||||||
|
"markup.quote" = { fg = "dark_3", modifiers = ["italic"] }
|
||||||
|
"diff.plus" = "teal_5"
|
||||||
|
"diff.minus" = "red_3"
|
||||||
|
"diff.delta" = "orange_5"
|
||||||
|
"diff.delta.moved" = "orange_4"
|
||||||
|
|
||||||
|
"ui.background" = { fg = "dark_4", bg = "light_1" }
|
||||||
|
"ui.background.separator" = { fg = "split_and_borders", bg = "light_2" }
|
||||||
|
"ui.cursor" = { fg = "light_2", bg = "dark_5" }
|
||||||
|
"ui.cursor.insert" = { fg = "light_2", bg = "dark_4" }
|
||||||
|
"ui.cursor.primary.insert" = { fg = "light_2", bg = "yellow_5" }
|
||||||
|
"ui.cursor.select" = { fg = "light_2", bg = "dark_5" }
|
||||||
|
"ui.cursor.match" = { fg = "light_2", bg = "blue_1" }
|
||||||
|
"ui.cursor.primary" = { fg = "light_2", bg = "dark_6" }
|
||||||
|
"ui.linenr" = "light_5"
|
||||||
|
"ui.linenr.selected" = { fg = "dark_2", bg = "light_3", modifiers = [
|
||||||
|
"bold",
|
||||||
|
] }
|
||||||
|
"ui.statusline" = { fg = "dark_4", bg = "light_4" }
|
||||||
|
"ui.statusline.inactive" = { fg = "dark_3", bg = "light_3" }
|
||||||
|
"ui.statusline.insert" = { fg = "light_5", bg = "teal_3" }
|
||||||
|
"ui.statusline.select" = { fg = "light_4", bg = "blue_3" }
|
||||||
|
"ui.popup" = { bg = "light_3" }
|
||||||
|
"ui.window" = "split_and_borders"
|
||||||
|
"ui.help" = { bg = "light_3" }
|
||||||
|
"ui.text" = "dark_4"
|
||||||
|
"ui.virtual" = "light_1"
|
||||||
|
"ui.virtual.ruler" = { bg = "light_5"}
|
||||||
|
"ui.menu" = { fg = "dark_4", bg = "light_3" }
|
||||||
|
"ui.menu.selected" = { fg = "dark_4", bg = "blue_1" }
|
||||||
|
"ui.menu.scroll" = { fg = "dark_6", bg = "light_3" }
|
||||||
|
"ui.selection" = { bg = "blue_0" }
|
||||||
|
"ui.selection.primary" = { bg = "blue_0" }
|
||||||
|
"ui.cursorline.primary" = { bg = "light_3" }
|
||||||
|
"ui.virtual.whitespace" = "light_7"
|
||||||
|
|
||||||
|
"warning" = "yellow_4"
|
||||||
|
"error" = "red_5"
|
||||||
|
"info" = "purple_3"
|
||||||
|
"hint" = "blue_3"
|
||||||
|
|
||||||
|
"diagnostic.hint" = { fg = "blue_4", modifiers = ["dim"] }
|
||||||
|
"diagnostic.info" = { fg = "purple_4", modifiers = ["dim"] }
|
||||||
|
"diagnostic.error" = { fg = "red_5", modifiers = ["underlined"] }
|
||||||
|
"diagnostic.warning" = { fg = "yellow_4", modifiers = ["underlined"] }
|
||||||
|
"diagnostic.unnecessary" = { modifiers = ["dim"] }
|
||||||
|
"diagnostic.deprecated" = { modifiers = ["crossed_out"] }
|
||||||
|
|
||||||
|
"ui.bufferline" = { fg = "light_7", bg = "light_2" }
|
||||||
|
"ui.bufferline.active" = { fg = "dark_4", bg = "light_4", modifiers = ["bold"]}
|
||||||
|
|
||||||
|
[palette]
|
||||||
|
blue_0 = "#d3e4f9"
|
50
runtime/themes/carbonfox.toml
Normal file
50
runtime/themes/carbonfox.toml
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
# Author: github.com/ETCaton
|
||||||
|
# License: MIT License
|
||||||
|
# Carbonfox
|
||||||
|
#
|
||||||
|
# Based on Helix's Nightfox port with changes to align it to Nightfox's Carbonfox theme
|
||||||
|
# Any 'custom' colors are replicating the result of the linear color blending done in the original
|
||||||
|
# Neovim theme.
|
||||||
|
# https://github.com/EdenEast/nightfox.nvim/blob/d3e8b1acc095baf57af81bb5e89fe7c4359eb619/lua/nightfox/lib/color.lua#L236-L247
|
||||||
|
|
||||||
|
inherits = 'nightfox'
|
||||||
|
|
||||||
|
# DIAGNOSTICS
|
||||||
|
# For brevity: All blends here are a blend between bg1 and the fg value with factor of 0.15
|
||||||
|
"warning" = { fg = "magenta", bg = "#2f2939" }
|
||||||
|
"error.bg" = "#361f29"
|
||||||
|
"info.bg" = "#252c39"
|
||||||
|
"hint" = { fg = "orange", bg = "#1c3433" }
|
||||||
|
|
||||||
|
[palette]
|
||||||
|
black = "#282828"
|
||||||
|
red = "#ee5396"
|
||||||
|
red-dim = "#ca4780"
|
||||||
|
green = "#25be6a"
|
||||||
|
green-dim = "#1fa25a"
|
||||||
|
yellow = "#08bdba"
|
||||||
|
yellow-bright = "#2dc7c4"
|
||||||
|
blue = "#78a9ff"
|
||||||
|
blue-bright = "#8cb6ff"
|
||||||
|
blue-dim = "#6690d9"
|
||||||
|
magenta = "#be95ff"
|
||||||
|
magenta-bright = "#c8a5ff"
|
||||||
|
cyan = "#33b1ff"
|
||||||
|
cyan-bright = "#52bdff"
|
||||||
|
cyan-dim = "#2b96d9"
|
||||||
|
orange = "#3ddbd9"
|
||||||
|
orange-bright = "#5ae0df"
|
||||||
|
pink = "#ff7eb6"
|
||||||
|
pink-bright = "#ff91c1"
|
||||||
|
# spec
|
||||||
|
bg0 = "#0c0c0c"
|
||||||
|
bg1 = "#161616"
|
||||||
|
bg2 = "#252525"
|
||||||
|
bg3 = "#353535"
|
||||||
|
bg4 = "#535353"
|
||||||
|
fg0 = "#f9fbff"
|
||||||
|
fg1 = "#f2f4f8"
|
||||||
|
fg2 = "#b6b8bb"
|
||||||
|
fg3 = "#7b7c7e"
|
||||||
|
sel0 = "#2a2a2a"
|
||||||
|
sel1 = "#525253"
|
180
runtime/themes/eiffel.toml
Normal file
180
runtime/themes/eiffel.toml
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
## Author: mesmere <95945959+mesmere@users.noreply.github.com>
|
||||||
|
## Original design by Ian Joyner
|
||||||
|
|
||||||
|
"attribute" = { fg = "markup", modifiers = ["italic"] }
|
||||||
|
"comment" = "comments"
|
||||||
|
"comment.block" = "comments"
|
||||||
|
"comment.block.documentation" = "comments"
|
||||||
|
"comment.line" = "comments"
|
||||||
|
#"constant" = ""
|
||||||
|
"constant.builtin" = { fg = "builtins", modifiers = ["italic"] }
|
||||||
|
"constant.character" = "strings"
|
||||||
|
"constant.character.escape" = "symbols"
|
||||||
|
"constant.numeric" = { fg = "constants_numeric", modifiers = ["italic"] }
|
||||||
|
"constructor" = { modifiers = ["italic"] }
|
||||||
|
"function" = { fg = "members" }
|
||||||
|
"function.builtin" = "builtins"
|
||||||
|
"function.macro" = "preprocessor"
|
||||||
|
"function.method" = { fg = "members", modifiers = ["italic"] }
|
||||||
|
#"function.method.private" = ""
|
||||||
|
"function.special" = "preprocessor"
|
||||||
|
"keyword" = { fg = "ui_text" }
|
||||||
|
"keyword.control" = { fg = "keywords", modifiers = ["bold"] }
|
||||||
|
"keyword.directive" = { fg = "preprocessor", modifiers = ["bold"] }
|
||||||
|
#"keyword.function" = ""
|
||||||
|
"keyword.operator" = { fg = "operators", modifiers = ["italic"] }
|
||||||
|
#"keyword.storage" = ""
|
||||||
|
#"label" = ""
|
||||||
|
#"namespace" = ""
|
||||||
|
"operator" = { fg = "operators", modifiers = ["bold"] }
|
||||||
|
#"punctuation" = ""
|
||||||
|
#"punctuation.bracket" = ""
|
||||||
|
#"punctuation.delimiter" = ""
|
||||||
|
"punctuation.special" = "strings"
|
||||||
|
#"special" = ""
|
||||||
|
"string" = "strings"
|
||||||
|
"string.regexp" = "symbols"
|
||||||
|
"string.special" = "symbols"
|
||||||
|
"tag" = "markup"
|
||||||
|
"type" = { modifiers = ["italic"] }
|
||||||
|
#"type.builtin" = ""
|
||||||
|
#"type.enum" = ""
|
||||||
|
#"type.parameter" = ""
|
||||||
|
#"variable" = ""
|
||||||
|
"variable.builtin" = "builtins"
|
||||||
|
"variable.other.member" = { fg = "members", modifiers = ["italic"] }
|
||||||
|
#"variable.other.member.private" = ""
|
||||||
|
#"variable.parameter" = ""
|
||||||
|
"markup" = "markup"
|
||||||
|
"markup.heading" = { fg = "markup_headings", modifiers = ["bold"] }
|
||||||
|
#"markup.heading.marker" = ""
|
||||||
|
"markup.list" = "markup_lists"
|
||||||
|
"markup.bold" = { modifiers = ["bold"] }
|
||||||
|
"markup.italic" = { modifiers = ["italic"] }
|
||||||
|
"markup.strikethrough" = { modifiers = ["crossed_out"] }
|
||||||
|
"markup.link.url" = { fg = "strings", underline.style = "line" } # Match HTML href/src attributes.
|
||||||
|
#"markup.link.label" = ""
|
||||||
|
"markup.link.text" = "ui_text"
|
||||||
|
"markup.quote" = { fg = "black", modifiers = ["italic"] }
|
||||||
|
"markup.raw" = "strings"
|
||||||
|
#"markup.raw.inline" = ""
|
||||||
|
#"markup.raw.block" = ""
|
||||||
|
|
||||||
|
"diff.delta" = "diff_delta"
|
||||||
|
"diff.minus" = "diff_minus"
|
||||||
|
"diff.plus" = "diff_plus"
|
||||||
|
|
||||||
|
"ui.background" = { bg = "ui_background" }
|
||||||
|
#"ui.background.separator" = ""
|
||||||
|
"ui.bufferline" = { fg = "ui_text_dim", bg = "ui_background_accent" }
|
||||||
|
"ui.bufferline.active" = { fg = "ui_text", bg = "ui_background_accent" }
|
||||||
|
"ui.bufferline.background" = { bg = "ui_background_accent" }
|
||||||
|
#"ui.cursor" = { modifiers = ['reversed'] }
|
||||||
|
"ui.cursor.insert" = { bg = "ui_mode_insert_accent" }
|
||||||
|
"ui.cursor.match" = { modifiers = ['reversed'] }
|
||||||
|
"ui.cursor.normal" = { bg = "ui_mode_normal_accent" }
|
||||||
|
"ui.cursor.select" = { bg = "ui_mode_select_accent" }
|
||||||
|
#"ui.cursor.primary" = ""
|
||||||
|
"ui.cursor.primary.insert" = { bg = "ui_mode_insert" }
|
||||||
|
#"ui.cursor.primary.match" = ""
|
||||||
|
"ui.cursor.primary.normal" = { bg = "ui_mode_normal" }
|
||||||
|
"ui.cursor.primary.select" = { bg = "ui_mode_select" }
|
||||||
|
"ui.cursorcolumn.primary" = { bg = "ui_background_accent" }
|
||||||
|
#"ui.cursorcolumn.secondary" = ""
|
||||||
|
"ui.cursorline.primary" = { bg = "ui_background_accent" }
|
||||||
|
#"ui.cursorline.secondary" = ""
|
||||||
|
"ui.debug.active" = { fg = "ui_debug_breakpoint" }
|
||||||
|
"ui.debug.breakpoint" = { fg = "ui_debug_breakpoint" }
|
||||||
|
"ui.gutter" = { bg = "ui_background" }
|
||||||
|
"ui.gutter.selected" = { bg = "ui_background_accent" }
|
||||||
|
"ui.help" = { fg = "ui_text", bg = "ui_menu" }
|
||||||
|
"ui.highlight" = { fg = "ui_highlight_line_text", bg = "ui_highlight_line" } # fg is not respected https://github.com/helix-editor/helix/issues/11141
|
||||||
|
"ui.highlight.frameline" = { fg = "ui_highlight_line_text", bg = "ui_highlight_line" }
|
||||||
|
"ui.linenr" = "ui_text_dim"
|
||||||
|
"ui.linenr.selected" = { fg = "ui_text_dim", bg = "ui_background_accent" }
|
||||||
|
"ui.menu" = { fg = "ui_menu_text", bg = "ui_menu" }
|
||||||
|
"ui.menu.scroll" = { fg = "ui_menu_handle", bg = "ui_menu_selected" }
|
||||||
|
"ui.menu.selected" = { fg = "ui_text", bg = "ui_menu_selected" }
|
||||||
|
#"ui.picker" = { fg = "ui_text", bg = "ui_menu" } # Styling the picker is currently unsupported.
|
||||||
|
"ui.picker.header" = { bg = "ui_background_accent" }
|
||||||
|
"ui.picker.header.column" = "ui_text"
|
||||||
|
"ui.picker.header.column.active" = { fg = "ui_text", modifiers = ["bold"], underline = { style = "line" } }
|
||||||
|
"ui.popup" = { fg = "ui_text", bg = "ui_background_accent" }
|
||||||
|
"ui.popup.info" = { fg = "ui_text", bg = "ui_menu" }
|
||||||
|
"ui.selection" = { bg = "ui_selection" }
|
||||||
|
#"ui.selection.primary" = { bg = "ui_selection", underline.style = "line" }
|
||||||
|
"ui.statusline" = { fg = "ui_text", bg = "ui_background_accent" }
|
||||||
|
#"ui.statusline.inactive" = { fg = "", bg = "" }
|
||||||
|
"ui.statusline.insert" = { fg = "ui_mode_insert_text", bg = "ui_mode_insert", modifiers = ["bold"] }
|
||||||
|
"ui.statusline.normal" = { fg = "ui_mode_normal_text", bg = "ui_mode_normal", modifiers = ["bold"] }
|
||||||
|
"ui.statusline.select" = { fg = "ui_mode_select_text", bg = "ui_mode_select", modifiers = ["bold"] }
|
||||||
|
"ui.text" = "ui_text"
|
||||||
|
"ui.text.focus" = { fg = "ui_text", modifiers = ["bold"] }
|
||||||
|
"ui.text.inactive" = "ui_text_dim"
|
||||||
|
#"ui.text.info" = ""
|
||||||
|
"ui.virtual.indent-guide" = "ui_text_dim"
|
||||||
|
"ui.virtual.inlay-hint" = "ui_text_dim"
|
||||||
|
#"ui.virtual.inlay-hint.parameter" = ""
|
||||||
|
#"ui.virtual.inlay-hint.type" = ""
|
||||||
|
"ui.virtual.jump-label" = { fg = "white", bg = "ui_jumplabel", modifiers = ["bold"] }
|
||||||
|
"ui.virtual.ruler" = { bg = "ui_background_accent" }
|
||||||
|
"ui.virtual.whitespace" = "ui_text_dim"
|
||||||
|
"ui.virtual.wrap" = "ui_text_dim"
|
||||||
|
"ui.window" = "ui_split_line"
|
||||||
|
|
||||||
|
info = { fg = 'ui_diagnostic_info' }
|
||||||
|
hint = { fg = 'ui_diagnostic_hint', modifiers = ['bold'] }
|
||||||
|
warning = { fg = 'ui_diagnostic_warning', modifiers = ['bold'] }
|
||||||
|
error = { fg = 'ui_diagnostic_error', modifiers = ['bold'] }
|
||||||
|
|
||||||
|
"diagnostic.info" = { fg = "ui_diagnostic_info", underline = { style = "curl", color = "ui_diagnostic_info" } }
|
||||||
|
"diagnostic.hint" = { fg = "ui_diagnostic_hint", underline = { style = "curl", color = "ui_diagnostic_hint" } }
|
||||||
|
"diagnostic.warning" = { fg = "ui_diagnostic_warning", underline = { style = "curl", color = "ui_diagnostic_warning" } }
|
||||||
|
"diagnostic.error" = { fg = "ui_diagnostic_error", underline = { style = "curl", color = "ui_diagnostic_error" } }
|
||||||
|
"diagnostic.unnecessary" = { modifiers = ["dim"] }
|
||||||
|
"diagnostic.deprecated" = { modifiers = ["crossed_out"] }
|
||||||
|
|
||||||
|
[palette]
|
||||||
|
builtins = "#585cf6"
|
||||||
|
comments = "#00b418"
|
||||||
|
constants_numeric = "#cd0000"
|
||||||
|
diff_delta = "#0000a2"
|
||||||
|
diff_minus = "#990000"
|
||||||
|
diff_plus = "#00b418"
|
||||||
|
keywords = "#0100b6"
|
||||||
|
markup = "#1c02ff"
|
||||||
|
markup_headings = "#0c07ff"
|
||||||
|
markup_lists = "#b90690"
|
||||||
|
members = "#0206ff"
|
||||||
|
operators = "#0100b6"
|
||||||
|
preprocessor = "#0c450d"
|
||||||
|
strings = "#d80800"
|
||||||
|
symbols = "#26b31a"
|
||||||
|
ui_background = "#ffffff"
|
||||||
|
ui_background_accent = "#ededed"
|
||||||
|
ui_highlight_line = "#0100b6"
|
||||||
|
ui_highlight_line_text = "#ffffff"
|
||||||
|
ui_debug_breakpoint = "#990000"
|
||||||
|
ui_diagnostic_error = "#990000"
|
||||||
|
ui_diagnostic_hint = "#06960e"
|
||||||
|
ui_diagnostic_info = "#808080"
|
||||||
|
ui_diagnostic_warning = "#fafa28"
|
||||||
|
ui_jumplabel = "#990000"
|
||||||
|
ui_menu = "#c3dcff"
|
||||||
|
ui_menu_selected = "#a3bcdf"
|
||||||
|
ui_menu_handle = "#839cbf"
|
||||||
|
ui_menu_text = "#000000"
|
||||||
|
ui_mode_insert = "#009608"
|
||||||
|
ui_mode_insert_accent = "#73e678"
|
||||||
|
ui_mode_insert_text = "#ffffff"
|
||||||
|
ui_mode_normal = "#444444"
|
||||||
|
ui_mode_normal_accent = "#cccccc"
|
||||||
|
ui_mode_normal_text = "#ffffff"
|
||||||
|
ui_mode_select = "#000096"
|
||||||
|
ui_mode_select_accent = "#7373e6"
|
||||||
|
ui_mode_select_text = "#ffffff"
|
||||||
|
ui_selection = "#c3dcff"
|
||||||
|
ui_split_line = "#000000"
|
||||||
|
ui_statusline = "#000000"
|
||||||
|
ui_text = "#000000"
|
||||||
|
ui_text_dim = "#808080"
|
@ -1,13 +1,15 @@
|
|||||||
|
# Author : portalsurfer <https://github.com/PORTALSURFER>
|
||||||
|
|
||||||
inherits = "hex_steel"
|
inherits = "hex_steel"
|
||||||
|
|
||||||
[palette]
|
[palette]
|
||||||
t1 = "#0e0e0d"
|
t1 = "#0e0e0d"
|
||||||
t2 = "#121311"
|
t2 = "#181a17"
|
||||||
t3 = "#2b3444"
|
t3 = "#2b3444"
|
||||||
t4 = "#61586f"
|
t4 = "#61586f"
|
||||||
t5 = "#686e73"
|
t5 = "#686e73"
|
||||||
t6 = "#878480"
|
t6 = "#878480"
|
||||||
t7 = "#897dca"
|
t7 = "#8e80de"
|
||||||
t8 = "#7b89a3"
|
t8 = "#7b89a3"
|
||||||
t9 = "#bcb6ba"
|
t9 = "#bcb6ba"
|
||||||
t10 = "#9db2b8"
|
t10 = "#9db2b8"
|
||||||
@ -20,12 +22,20 @@ highlight_three = "#29bbff"
|
|||||||
black = "#000000"
|
black = "#000000"
|
||||||
|
|
||||||
selection = "#290019"
|
selection = "#290019"
|
||||||
|
selection_fg = "#958e9a"
|
||||||
|
|
||||||
comment = "#9aacfe"
|
comment = "#404768"
|
||||||
comment_doc = "#0affa9"
|
comment_doc = "#0affa9"
|
||||||
|
|
||||||
error = "#ff0900"
|
error = "#ff0900"
|
||||||
warning = "#ffbf00"
|
warning = "#ffbf00"
|
||||||
display = "#57ff89"
|
display = "#57ff89"
|
||||||
info = "#dad7d5"
|
info = "#dad7d5"
|
||||||
#
|
|
||||||
|
hints = "#44273f"
|
||||||
|
ruler = "#1c1f1b"
|
||||||
|
|
||||||
|
diff_minus = "#ff4000"
|
||||||
|
diff_delta = "#0078bd"
|
||||||
|
diff_plus = "#c9d400"
|
||||||
|
diff_delta_moved = "#0048bd"
|
41
runtime/themes/hex_poison.toml
Normal file
41
runtime/themes/hex_poison.toml
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
# Author : portalsurfer <https://github.com/PORTALSURFER>
|
||||||
|
|
||||||
|
inherits = "hex_steel"
|
||||||
|
|
||||||
|
[palette]
|
||||||
|
t1 = "#121211"
|
||||||
|
t2 = "#1e1f1b"
|
||||||
|
t3 = "#4c513a"
|
||||||
|
t4 = "#5a6052"
|
||||||
|
t5 = "#6f6d6f"
|
||||||
|
t8 = "#7e808a"
|
||||||
|
t7 = "#b1b354"
|
||||||
|
t10 = "#6fa197"
|
||||||
|
t9 = "#3f4a4e"
|
||||||
|
t6 = "#98acaa"
|
||||||
|
t11 = "#6fd7a8"
|
||||||
|
|
||||||
|
highlight = "#ff2e5f"
|
||||||
|
highlight_two = "#0affa9"
|
||||||
|
highlight_three = "#d7ff52"
|
||||||
|
|
||||||
|
black = "#000000"
|
||||||
|
|
||||||
|
selection = "#290019"
|
||||||
|
selection_fg = "#c8e732"
|
||||||
|
|
||||||
|
comment = "#396884"
|
||||||
|
comment_doc = "#234048"
|
||||||
|
|
||||||
|
error = "#c73500"
|
||||||
|
warning = "#dcbb00"
|
||||||
|
display = "#57ff89"
|
||||||
|
info = "#dad7d5"
|
||||||
|
|
||||||
|
hints = "#313d3c"
|
||||||
|
ruler = "#21221e"
|
||||||
|
|
||||||
|
diff_minus = "#ff4000"
|
||||||
|
diff_delta = "#16a7c7"
|
||||||
|
diff_plus = "#c9d400"
|
||||||
|
diff_delta_moved = "#0048bd"
|
@ -1,14 +1,16 @@
|
|||||||
|
# Author : portalsurfer <https://github.com/PORTALSURFER>
|
||||||
|
|
||||||
"comment" = { fg = "comment" }
|
"comment" = { fg = "comment" }
|
||||||
"comment.block.documentation" = { bg = "comment_doc", modifiers = ["italic"] }
|
"comment.block.documentation" = { bg = "comment_doc", modifiers = ["italic"] }
|
||||||
|
|
||||||
"constant" = { fg = "t11" }
|
"constant" = { fg = "t11" }
|
||||||
"function" = { fg = "t10" }
|
"function" = { fg = "t10" }
|
||||||
"function.method" = { fg = "t10" }
|
"function.method" = { fg = "t7" }
|
||||||
"function.macro" = { fg = "t7" }
|
"function.macro" = { fg = "t7" }
|
||||||
"keyword.storage.modifier" = { fg = "t7" }
|
"keyword.storage.modifier" = { fg = "t7" }
|
||||||
"keyword.control.import" = { fg = "t8" }
|
"keyword.control.import" = { fg = "t8" }
|
||||||
"keyword.control" = { fg = "t8" }
|
"keyword.control" = { fg = "t8" }
|
||||||
"keyword.function" = { fg = "t7" }
|
"keyword.function" = { fg = "t11" }
|
||||||
"keyword" = { fg = "t6" }
|
"keyword" = { fg = "t6" }
|
||||||
"operator" = { fg = "t8" }
|
"operator" = { fg = "t8" }
|
||||||
"punctuation" = { fg = "t9" }
|
"punctuation" = { fg = "t9" }
|
||||||
@ -18,6 +20,8 @@
|
|||||||
"type" = { fg = "t8", modifiers = ["bold"] }
|
"type" = { fg = "t8", modifiers = ["bold"] }
|
||||||
"namespace" = { fg = "t6", modifiers = ["bold"] }
|
"namespace" = { fg = "t6", modifiers = ["bold"] }
|
||||||
"variable" = { fg = "t4" }
|
"variable" = { fg = "t4" }
|
||||||
|
"variable.parameter" = { fg = "t6" }
|
||||||
|
"variable.other.member" = { fg = "t3" }
|
||||||
"label" = { fg = "t4" }
|
"label" = { fg = "t4" }
|
||||||
|
|
||||||
"diff.plus" = { fg = "diff_plus" }
|
"diff.plus" = { fg = "diff_plus" }
|
||||||
@ -25,10 +29,12 @@
|
|||||||
"diff.delta.moved" = { fg = "diff_delta_moved" }
|
"diff.delta.moved" = { fg = "diff_delta_moved" }
|
||||||
"diff.minus" = { fg = "diff_minus" }
|
"diff.minus" = { fg = "diff_minus" }
|
||||||
|
|
||||||
"ui.cursor.insert" = { fg = "t2", bg = "highlight" }
|
"ui.cursor.primary.insert" = { fg = "t2", bg = "highlight" }
|
||||||
"ui.cursor.select" = { fg = "t2", bg = "highlight_two" }
|
"ui.cursor.primary.select" = { fg = "t2", bg = "highlight_two" }
|
||||||
"ui.cursor" = { fg = "t1", bg = "highlight_three" }
|
"ui.cursor.primary" = { fg = "t1", bg = "highlight_three" }
|
||||||
"ui.cursor.match" = { fg = "highlight", bg = "selection", modifiers = ["bold"] }
|
"ui.cursor.match" = { fg = "highlight", bg = "t1", modifiers = ["bold"] }
|
||||||
|
"ui.cursorline.primary" = { bg = "ruler" }
|
||||||
|
"ui.cursorline.secondary" = { bg = "ruler" }
|
||||||
|
|
||||||
"ui.linenr" = { fg = "t3", bg = "t2" }
|
"ui.linenr" = { fg = "t3", bg = "t2" }
|
||||||
"ui.linenr.selected" = { fg = "highlight_three", bg = "t2" }
|
"ui.linenr.selected" = { fg = "highlight_three", bg = "t2" }
|
||||||
@ -42,10 +48,7 @@
|
|||||||
"ui.popup" = { fg = "t4", bg = "t1" }
|
"ui.popup" = { fg = "t4", bg = "t1" }
|
||||||
"ui.window" = { fg = "t4" }
|
"ui.window" = { fg = "t4" }
|
||||||
|
|
||||||
"ui.selection.primary" = { bg = "selection" }
|
"ui.selection" = { fg = "selection_fg", bg = "selection" }
|
||||||
"ui.selection" = { bg = "selection" }
|
|
||||||
|
|
||||||
"ui.cursorline.primary" = { bg = "t1" }
|
|
||||||
|
|
||||||
"ui.statusline" = { fg = "t4", bg = "t1" }
|
"ui.statusline" = { fg = "t4", bg = "t1" }
|
||||||
"ui.statusline.inactive" = { fg = "t4", bg = "t1" }
|
"ui.statusline.inactive" = { fg = "t4", bg = "t1" }
|
||||||
@ -55,17 +58,20 @@
|
|||||||
|
|
||||||
"ui.text" = { fg = "t4" }
|
"ui.text" = { fg = "t4" }
|
||||||
"ui.text.focus" = { fg = "highlight_three", modifiers = ["bold"] }
|
"ui.text.focus" = { fg = "highlight_three", modifiers = ["bold"] }
|
||||||
#
|
|
||||||
"ui.virtual.ruler" = { bg = "t1" }
|
"ui.virtual.ruler" = { bg = "ruler" }
|
||||||
"ui.virtual.indent-guide" = { fg = "t3" }
|
"ui.virtual.indent-guide" = { fg = "t3" }
|
||||||
"ui.virtual.whitespace" = { fg = "t3" }
|
"ui.virtual.whitespace" = { fg = "t3" }
|
||||||
|
"ui.virtual.jump-label" = { fg = "t11", modifiers = ["bold"] }
|
||||||
|
"ui.virtual.inlay-hint" = { fg = "hints", modifiers = ["bold"] }
|
||||||
|
|
||||||
|
"ui.bufferline" = { fg = "t3", bg = "t1" }
|
||||||
|
"ui.bufferline.active" = { fg = "t7", bg = "t2" }
|
||||||
|
|
||||||
"diagnostic.error" = { underline = { color = "error", style = "curl" } }
|
"diagnostic.error" = { underline = { color = "error", style = "curl" } }
|
||||||
"diagnostic.warning" = { underline = { color = "warning", style = "curl" } }
|
"diagnostic.warning" = { underline = { color = "warning", style = "curl" } }
|
||||||
"diagnostic.info" = { underline = { color = "info", style = "curl" } }
|
"diagnostic.info" = { underline = { color = "info", style = "curl" } }
|
||||||
"diagnostic.hint" = { underline = { color = "display", style = "curl" } }
|
"diagnostic.hint" = { underline = { color = "display", style = "curl" } }
|
||||||
"diagnostic.unnecessary" = { modifiers = ["dim"] }
|
|
||||||
"diagnostic.deprecated" = { modifiers = ["crossed_out"] }
|
|
||||||
|
|
||||||
"error" = { fg = "error", modifiers = ["bold"] }
|
"error" = { fg = "error", modifiers = ["bold"] }
|
||||||
"warning" = { fg = "warning", modifiers = ["bold"] }
|
"warning" = { fg = "warning", modifiers = ["bold"] }
|
||||||
@ -73,14 +79,14 @@
|
|||||||
"hint" = { fg = "display", modifiers = ["bold"] }
|
"hint" = { fg = "display", modifiers = ["bold"] }
|
||||||
"special" = { fg = "t7", modifiers = ["bold"] }
|
"special" = { fg = "t7", modifiers = ["bold"] }
|
||||||
|
|
||||||
"markup.heading" = { fg = "t4" }
|
"markup.heading" = { fg = "t7" }
|
||||||
"markup.list" = { fg = "t4" }
|
"markup.list" = { fg = "t7" }
|
||||||
"markup.bold" = { fg = "t4" }
|
"markup.bold" = { fg = "t4" }
|
||||||
"markup.italic" = { fg = "t4" }
|
"markup.italic" = { fg = "t4" }
|
||||||
"markup.strikethrough" = { fg = "t4", modifiers = ["crossed_out"] }
|
"markup.strikethrough" = { fg = "t4", modifiers = ["crossed_out"] }
|
||||||
"markup.link.url" = { fg = "t4", modifiers = ["underlined"] }
|
"markup.link.url" = { fg = "t11", modifiers = ["underlined"] }
|
||||||
"markup.link.text" = { fg = "t4" }
|
"markup.link.text" = { fg = "t11" }
|
||||||
"markup.quote" = { fg = "t4" }
|
"markup.quote" = { fg = "t5" }
|
||||||
"markup.raw" = { fg = "t4" }
|
"markup.raw" = { fg = "t4" }
|
||||||
|
|
||||||
[palette]
|
[palette]
|
||||||
@ -93,25 +99,28 @@ t6 = "#6e8789"
|
|||||||
t7 = "#d85c60"
|
t7 = "#d85c60"
|
||||||
t8 = "#9bc1bb"
|
t8 = "#9bc1bb"
|
||||||
t9 = "#b5c5c5"
|
t9 = "#b5c5c5"
|
||||||
t10 = "#c0d0ce"
|
t10 = "#c3c3bd"
|
||||||
t11 = "#f78c5e"
|
t11 = "#f78c5e"
|
||||||
|
|
||||||
highlight = "#3f36f2"
|
highlight = "#f23672"
|
||||||
highlight_two = "#f69c3c"
|
highlight_two = "#f69c3c"
|
||||||
highlight_three = "#d4d987"
|
highlight_three = "#d4d987"
|
||||||
|
|
||||||
selection = "#032d4a"
|
selection = "#4a9aa6"
|
||||||
|
selection_fg = "#080a0b"
|
||||||
|
|
||||||
black = "#000000"
|
black = "#000000"
|
||||||
comment = "#d4d987"
|
comment = "#654642"
|
||||||
comment_doc = "#234048"
|
comment_doc = "#234048"
|
||||||
|
hints = "#31353c"
|
||||||
|
ruler = "#222320"
|
||||||
|
|
||||||
error = "#ff0900"
|
error = "#ff4000"
|
||||||
warning = "#ffbf00"
|
warning = "#ffbf00"
|
||||||
display = "#42baff"
|
display = "#42baff"
|
||||||
info = "#dad7d5"
|
info = "#dad7d5"
|
||||||
|
|
||||||
diff_minus = "#ff0900"
|
diff_minus = "#ff4000"
|
||||||
diff_delta = "#0078bd"
|
diff_delta = "#0078bd"
|
||||||
diff_plus = "#87a800"
|
diff_plus = "#c9d400"
|
||||||
diff_delta_moved = "#0048bd"
|
diff_delta_moved = "#0048bd"
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
# Author : portalsurfer <https://github.com/PORTALSURFER>
|
||||||
|
|
||||||
inherits = "hex_steel"
|
inherits = "hex_steel"
|
||||||
|
|
||||||
[palette]
|
[palette]
|
||||||
@ -19,12 +21,21 @@ highlight_three = "#f8ed8b"
|
|||||||
|
|
||||||
black = "#000000"
|
black = "#000000"
|
||||||
|
|
||||||
selection = "#382e1e"
|
selection = "#b10656"
|
||||||
|
selection_fg = "#101719"
|
||||||
|
|
||||||
comment = "#61bdd1"
|
comment = "#417e8c"
|
||||||
comment_doc = "#234048"
|
comment_doc = "#234048"
|
||||||
|
|
||||||
error = "#ff0900"
|
error = "#ff0900"
|
||||||
warning = "#ffbf00"
|
warning = "#ffbf00"
|
||||||
display = "#57ff89"
|
display = "#57ff89"
|
||||||
info = "#dad7d5"
|
info = "#dad7d5"
|
||||||
|
|
||||||
|
hints = "#39515c"
|
||||||
|
ruler = "#1e3039"
|
||||||
|
|
||||||
|
diff_minus = "#ff4000"
|
||||||
|
diff_delta = "#0078bd"
|
||||||
|
diff_plus = "#c9d400"
|
||||||
|
diff_delta_moved = "#0048bd"
|
21
runtime/themes/licenses/carbonfox.license
Normal file
21
runtime/themes/licenses/carbonfox.license
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2021 James Simpson
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
@ -1,6 +1,6 @@
|
|||||||
# Author: Alexis Mousset <contact@amousset.me>
|
# Author: Alexis Mousset <contact@amousset.me>
|
||||||
# Adapted from https://protesilaos.com/emacs/modus-themes, by Protesilaos Stavrou
|
# Adapted from https://protesilaos.com/emacs/modus-themes, by Protesilaos Stavrou
|
||||||
# Version 4.4.0
|
# Version 4.6.0
|
||||||
#
|
#
|
||||||
|
|
||||||
# Syntax highlighting
|
# Syntax highlighting
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
# modus_operandi.toml variant
|
# modus_operandi.toml variant
|
||||||
#
|
#
|
||||||
# This variant is optimized for users with red-green color deficiency (deuteranopia)
|
# This variant is optimized for users with red-green color deficiency (deuteranopia)
|
||||||
# Version 4.4.0
|
# Version 4.6.0
|
||||||
|
|
||||||
inherits = "modus_operandi"
|
inherits = "modus_operandi"
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# Author: Alexis Mousset <contact@amousset.me>
|
# Author: Alexis Mousset <contact@amousset.me>
|
||||||
# modus_operandi.toml variant
|
# modus_operandi.toml variant
|
||||||
# Version 4.4.0
|
# Version 4.6.0
|
||||||
|
|
||||||
inherits = "modus_operandi"
|
inherits = "modus_operandi"
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
# modus_operandi.toml variant
|
# modus_operandi.toml variant
|
||||||
#
|
#
|
||||||
# This variant is optimized for users with blue-yellow color deficiency (tritanopia)
|
# This variant is optimized for users with blue-yellow color deficiency (tritanopia)
|
||||||
# Version 4.4.0
|
# Version 4.6.0
|
||||||
|
|
||||||
inherits = "modus_operandi"
|
inherits = "modus_operandi"
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# Author: Matous Dzivjak <matousdzivjak@gmail.com>
|
# Author: Matous Dzivjak <matousdzivjak@gmail.com>
|
||||||
# Adapted from https://protesilaos.com/emacs/modus-themes, by Protesilaos Stavrou
|
# Adapted from https://protesilaos.com/emacs/modus-themes, by Protesilaos Stavrou
|
||||||
# Source: https://github.com/protesilaos/modus-themes/blob/main/modus-vivendi-theme.el
|
# Source: https://github.com/protesilaos/modus-themes/blob/main/modus-vivendi-theme.el
|
||||||
# Version 4.4.0
|
# Version 4.6.0
|
||||||
|
|
||||||
# Syntax highlighting
|
# Syntax highlighting
|
||||||
# -------------------
|
# -------------------
|
||||||
@ -124,7 +124,7 @@ bg-inactive = "#303030"
|
|||||||
# Common accent foregrounds
|
# Common accent foregrounds
|
||||||
red = "#ff5f59"
|
red = "#ff5f59"
|
||||||
red-warmer = "#ff6b55"
|
red-warmer = "#ff6b55"
|
||||||
red-cooler = "#ff7f9f"
|
red-cooler = "#ff7f86"
|
||||||
red-faint = "#ff9580"
|
red-faint = "#ff9580"
|
||||||
red-intense = "#ff5f5f"
|
red-intense = "#ff5f5f"
|
||||||
green = "#44bc44"
|
green = "#44bc44"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# Author: Matous Dzivjak <matousdzivjak@gmail.com>
|
# Author: Matous Dzivjak <matousdzivjak@gmail.com>
|
||||||
# Adapted from https://protesilaos.com/emacs/modus-themes, by Protesilaos Stavrou
|
# Adapted from https://protesilaos.com/emacs/modus-themes, by Protesilaos Stavrou
|
||||||
# Source: https://github.com/protesilaos/modus-themes/blob/main/modus-vivendi-deuteranopia-theme.el
|
# Source: https://github.com/protesilaos/modus-themes/blob/main/modus-vivendi-deuteranopia-theme.el
|
||||||
# Version 4.3.0
|
# Version 4.6.0
|
||||||
|
|
||||||
inherits = "modus_vivendi"
|
inherits = "modus_vivendi"
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ border = "#646464"
|
|||||||
# Common accent foregrounds
|
# Common accent foregrounds
|
||||||
red = "#ff5f59"
|
red = "#ff5f59"
|
||||||
red-warmer = "#ff6b55"
|
red-warmer = "#ff6b55"
|
||||||
red-cooler = "#ff7f9f"
|
red-cooler = "#ff7f86"
|
||||||
red-faint = "#ff9580"
|
red-faint = "#ff9580"
|
||||||
red-intense = "#ff5f5f"
|
red-intense = "#ff5f5f"
|
||||||
green = "#44bc44"
|
green = "#44bc44"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# Author: Matous Dzivjak <matousdzivjak@gmail.com>
|
# Author: Matous Dzivjak <matousdzivjak@gmail.com>
|
||||||
# Adapted from: https://protesilaos.com/emacs/modus-themes, by Protesilaos Stavrou
|
# Adapted from: https://protesilaos.com/emacs/modus-themes, by Protesilaos Stavrou
|
||||||
# Source: https://github.com/protesilaos/modus-themes/blob/main/modus-vivendi-tinted-theme.el
|
# Source: https://github.com/protesilaos/modus-themes/blob/main/modus-vivendi-tinted-theme.el
|
||||||
# Version 4.4.0
|
# Version 4.6.0
|
||||||
|
|
||||||
inherits = "modus_vivendi"
|
inherits = "modus_vivendi"
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ border = "#61647a"
|
|||||||
# Common accent foregrounds
|
# Common accent foregrounds
|
||||||
red = "#ff5f59"
|
red = "#ff5f59"
|
||||||
red-warmer = "#ff6b55"
|
red-warmer = "#ff6b55"
|
||||||
red-cooler = "#ff7f9f"
|
red-cooler = "#ff7f86"
|
||||||
red-faint = "#ff9f80"
|
red-faint = "#ff9f80"
|
||||||
red-intense = "#ff5f5f"
|
red-intense = "#ff5f5f"
|
||||||
green = "#44bc44"
|
green = "#44bc44"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# Author: Matous Dzivjak <matousdzivjak@gmail.com>
|
# Author: Matous Dzivjak <matousdzivjak@gmail.com>
|
||||||
# Adapted from https://protesilaos.com/emacs/modus-themes, by Protesilaos Stavrou
|
# Adapted from https://protesilaos.com/emacs/modus-themes, by Protesilaos Stavrou
|
||||||
# Source: https://github.com/protesilaos/modus-themes/blob/main/modus-vivendi-tritanopia-theme.el
|
# Source: https://github.com/protesilaos/modus-themes/blob/main/modus-vivendi-tritanopia-theme.el
|
||||||
# Version 4.3.0
|
# Version 4.6.0
|
||||||
|
|
||||||
inherits = "modus_vivendi"
|
inherits = "modus_vivendi"
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ border = "#646464"
|
|||||||
# Common accent foregrounds
|
# Common accent foregrounds
|
||||||
red = "#ff5f59"
|
red = "#ff5f59"
|
||||||
red-warmer = "#ff6740"
|
red-warmer = "#ff6740"
|
||||||
red-cooler = "#ff6f9f"
|
red-cooler = "#ff7f86"
|
||||||
red-faint = "#ff9070"
|
red-faint = "#ff9070"
|
||||||
red-intense = "#ff5f5f"
|
red-intense = "#ff5f5f"
|
||||||
green = "#44bc44"
|
green = "#44bc44"
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
# Author: Shafkath Shuhan <shafkathshuhannyc@gmail.com>
|
# Author: Shafkath Shuhan <shafkathshuhannyc@gmail.com>
|
||||||
|
|
||||||
|
"tag" = { fg = "tag" }
|
||||||
|
|
||||||
"namespace" = { fg = "type" }
|
"namespace" = { fg = "type" }
|
||||||
"module" = { fg = "type" }
|
"module" = { fg = "type" }
|
||||||
|
|
||||||
@ -116,3 +118,4 @@ cursor = "#a6a6a6"
|
|||||||
inactive_cursor = "#878b91"
|
inactive_cursor = "#878b91"
|
||||||
widget = "#1e1f1c"
|
widget = "#1e1f1c"
|
||||||
selection = "#414339"
|
selection = "#414339"
|
||||||
|
tag = "#F92672"
|
||||||
|
@ -74,9 +74,9 @@
|
|||||||
|
|
||||||
"ui.statusline" = { fg = "white", bg = "light-black" }
|
"ui.statusline" = { fg = "white", bg = "light-black" }
|
||||||
"ui.statusline.inactive" = { fg = "light-gray", bg = "light-black" }
|
"ui.statusline.inactive" = { fg = "light-gray", bg = "light-black" }
|
||||||
"ui.statusline.normal" = { fg = "light-black", bg = "purple" }
|
"ui.statusline.normal" = { fg = "light-black", bg = "purple", modifiers = ["bold"] }
|
||||||
"ui.statusline.insert" = { fg = "light-black", bg = "green" }
|
"ui.statusline.insert" = { fg = "light-black", bg = "green", modifiers = ["bold"] }
|
||||||
"ui.statusline.select" = { fg = "light-black", bg = "cyan" }
|
"ui.statusline.select" = { fg = "light-black", bg = "cyan", modifiers = ["bold"] }
|
||||||
|
|
||||||
"ui.bufferline" = { fg = "light-gray", bg = "light-black" }
|
"ui.bufferline" = { fg = "light-gray", bg = "light-black" }
|
||||||
"ui.bufferline.active" = { fg = "light-black", bg = "blue", underline = { color = "light-black", style = "line" } }
|
"ui.bufferline.active" = { fg = "light-black", bg = "blue", underline = { color = "light-black", style = "line" } }
|
||||||
|
16
runtime/themes/seoul256-dark-hard.toml
Normal file
16
runtime/themes/seoul256-dark-hard.toml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# Seoul256 Dark Hard
|
||||||
|
# Author : EricHenry
|
||||||
|
# Original Creator: https://github.com/junegunn/seoul256.vim
|
||||||
|
|
||||||
|
inherits = "seoul256-dark"
|
||||||
|
|
||||||
|
"ui.background" = { bg = "gray1" }
|
||||||
|
"ui.gutter" = { bg = "gray2" }
|
||||||
|
"ui.cursorline.primary" = { bg = "gray" }
|
||||||
|
"ui.gutter.selected" = { bg = "gray" }
|
||||||
|
"ui.linenr.selected" = { bg = "gray", fg = "magenta", modifiers = ["bold"] }
|
||||||
|
"ui.virtual.inlay-hint" = { fg = "gray4", modifiers = ["bold"] }
|
||||||
|
|
||||||
|
"ui.help" = { bg = "gray" }
|
||||||
|
"ui.popup" = { bg = "gray" }
|
||||||
|
"ui.menu" = { bg = "gray" }
|
15
runtime/themes/seoul256-dark-soft.toml
Normal file
15
runtime/themes/seoul256-dark-soft.toml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# Seoul256 Dark Soft
|
||||||
|
# Author : EricHenry
|
||||||
|
# Original Creator: https://github.com/junegunn/seoul256.vim
|
||||||
|
|
||||||
|
inherits = "seoul256-dark"
|
||||||
|
|
||||||
|
"ui.background" = { bg = "gray8" }
|
||||||
|
"ui.gutter" = { bg = "gray6" }
|
||||||
|
"ui.cursorline.primary" = { bg = "gray5" }
|
||||||
|
"ui.gutter.selected" = { bg = "gray5" }
|
||||||
|
"ui.linenr.selected" = { bg = "gray5", fg = "magenta", modifiers = ["bold"] }
|
||||||
|
|
||||||
|
"ui.help" = { bg = "gray5" }
|
||||||
|
"ui.popup" = { bg = "gray5" }
|
||||||
|
"ui.menu" = { bg = "gray5" }
|
161
runtime/themes/seoul256-dark.toml
Normal file
161
runtime/themes/seoul256-dark.toml
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
# Seoul256 Dark
|
||||||
|
# Author : EricHenry
|
||||||
|
# Original Creator: https://github.com/junegunn/seoul256.vim
|
||||||
|
|
||||||
|
# Syntax highlighting configuration
|
||||||
|
"attribute" = { fg = "yellow" }
|
||||||
|
"comment" = { fg = "green1" }
|
||||||
|
"constant" = { fg = "blue5" }
|
||||||
|
"constant.numeric" = { fg = "yellow1" }
|
||||||
|
"constant.builtin.boolean" = { fg = "purple" }
|
||||||
|
"constant.character.escape" = { fg = "salmon" }
|
||||||
|
"constructor" = { fg = "yellow" }
|
||||||
|
"function" = { fg = "yellow2" }
|
||||||
|
"function.builtin" = { fg = "blue1" }
|
||||||
|
"function.method" = { fg = "salmon" }
|
||||||
|
"function.macro" = { fg = "yellow2" }
|
||||||
|
"keyword" = { fg = "mauve" }
|
||||||
|
"label" = { fg = "magenta" }
|
||||||
|
"namespace" = { fg = "cyan" }
|
||||||
|
"operator" = { fg = "yellow3" }
|
||||||
|
"punctuation" = { fg = "brown" }
|
||||||
|
"special" = { fg = "yellow2" }
|
||||||
|
"string" = { fg = "blue" }
|
||||||
|
"type" = { fg = "yellow" }
|
||||||
|
"type.builtin" = { fg = "salmon" }
|
||||||
|
"variable" = { fg = "white" }
|
||||||
|
"variable.builtin" = { fg = "salmon" }
|
||||||
|
"variable.parameter" = { fg = "white" }
|
||||||
|
"variable.other.member" = { fg = "white" }
|
||||||
|
|
||||||
|
"markup.heading" = { fg = "salmon2", modifiers = ["bold"] }
|
||||||
|
"markup.raw.inline" = { fg = "green" }
|
||||||
|
"markup.bold" = { fg = "yellow1", modifiers = ["bold"] }
|
||||||
|
"markup.italic" = { fg = "magenta1", modifiers = ["italic"] }
|
||||||
|
"markup.strikethrough" = { modifiers = ["crossed_out"] }
|
||||||
|
"markup.list" = { fg = "salmon" }
|
||||||
|
"markup.quote" = { fg = "yellow" }
|
||||||
|
"markup.link.url" = { fg = "cyan", modifiers = ["underlined"] }
|
||||||
|
"markup.link.text" = { fg = "salmon2" }
|
||||||
|
|
||||||
|
"diff.plus" = { fg = "green3" }
|
||||||
|
"diff.delta" = { fg = "blue1" }
|
||||||
|
"diff.minus" = { fg = "magenta3" }
|
||||||
|
|
||||||
|
"diagnostic.info".underline = { color = "cyan", style = "curl" }
|
||||||
|
"diagnostic.hint".underline = { color = "green1", style = "curl" }
|
||||||
|
"diagnostic.warning".underline = { color = "yellow1", style = "curl" }
|
||||||
|
"diagnostic.error".underline = { color = "red", style = "curl" }
|
||||||
|
"diagnostic.unnecessary" = { modifiers = ["dim"] }
|
||||||
|
"diagnostic.deprecated" = { modifiers = ["crossed_out"] }
|
||||||
|
"info" = { fg = "blue2", modifiers = ["bold"] }
|
||||||
|
"hint" = { fg = "blue3", modifiers = ["bold"] }
|
||||||
|
"warning" = { fg = "yellow", modifiers = ["bold"] }
|
||||||
|
"error" = { fg = "red", modifiers = ["bold"] }
|
||||||
|
|
||||||
|
"ui.background" = { bg = "gray4" }
|
||||||
|
"ui.gutter" = { bg = "gray5" }
|
||||||
|
"ui.gutter.selected" = { bg = "gray3" }
|
||||||
|
"ui.virtual" = { fg = "gray6" }
|
||||||
|
"ui.virtual.indent-guide" = { fg = "gray6" }
|
||||||
|
"ui.virtual.whitespace" = { fg = "gray6" }
|
||||||
|
"ui.virtual.ruler" = { bg = "gray5" }
|
||||||
|
"ui.virtual.inlay-hint" = { fg = "gray9", modifiers = ["bold"] }
|
||||||
|
"ui.virtual.jump-label" = { fg = "red", modifiers = ["bold"] }
|
||||||
|
|
||||||
|
"ui.cursor" = { fg = "white", modifiers = ["reversed"] }
|
||||||
|
"ui.cursor.primary" = { fg = "white", modifiers = ["reversed"] }
|
||||||
|
"ui.cursor.match" = { bg = "gray4", modifiers = ["underlined"] }
|
||||||
|
"ui.cursor.insert" = { fg = "blue1" }
|
||||||
|
|
||||||
|
"ui.selection" = { bg = "magenta2" }
|
||||||
|
"ui.selection.primary" = { bg = "blue4" }
|
||||||
|
"ui.cursorline.primary" = { bg = "gray3" }
|
||||||
|
|
||||||
|
"ui.highlight" = { bg = "gray5" }
|
||||||
|
"ui.highlight.frameline" = { bg = "red" }
|
||||||
|
|
||||||
|
"ui.linenr" = { fg = "yellow4" }
|
||||||
|
"ui.linenr.selected" = { bg = "gray3", fg = "magenta", modifiers = ["bold"] }
|
||||||
|
|
||||||
|
"ui.statusline" = { fg = "magenta2", bg = "yellow2" }
|
||||||
|
"ui.statusline.inactive" = { fg = "gray6", bg = "black" }
|
||||||
|
"ui.statusline.normal" = { fg = "black", bg = "blue2" }
|
||||||
|
"ui.statusline.insert" = { fg = "black", bg = "green2" }
|
||||||
|
"ui.statusline.select" = { fg = "black", bg = "magenta" }
|
||||||
|
|
||||||
|
"ui.text" = { fg = "white" }
|
||||||
|
"ui.text.focus" = { fg = "white", bg = "magenta2", modifiers = ["bold"] }
|
||||||
|
|
||||||
|
"ui.help" = { fg = "white", bg = "gray3" }
|
||||||
|
"ui.popup" = { fg = "white", bg = "gray3" }
|
||||||
|
"ui.window" = { fg = "white" }
|
||||||
|
"ui.menu" = { fg = "white", bg = "gray3" }
|
||||||
|
"ui.menu.selected" = { fg = "white", bg = "magenta2" }
|
||||||
|
"ui.menu.scroll" = { fg = "gray7", bg = "gray6" }
|
||||||
|
|
||||||
|
"ui.debug" = { fg = "red" }
|
||||||
|
|
||||||
|
# Colors (Seoul256)
|
||||||
|
[palette]
|
||||||
|
black = '#000000' # Black
|
||||||
|
black1 = '#14161B'
|
||||||
|
red = '#d70000' # Red
|
||||||
|
green = '#afd75f' # Greenish Yellow
|
||||||
|
green1 = '#5f875f' # Greenish Gray
|
||||||
|
green2 = '#5f8700' # Green
|
||||||
|
green3 = '#87af87'
|
||||||
|
green4 = '#5f5f00'
|
||||||
|
yellow = '#d8af5f' # Yellow
|
||||||
|
yellow1 = '#ffd787' # Bright Yellow
|
||||||
|
yellow2 = '#d7d7af' # Yellowish
|
||||||
|
yellow3 = '#d7d787' # Yellow Dim
|
||||||
|
yellow4 = '#87875f' # Olive
|
||||||
|
yellow5 = '#6B5300'
|
||||||
|
blue = '#87afaf' # Light Blue
|
||||||
|
blue1 = '#5f87d7' # Bright Blue
|
||||||
|
blue2 = '#5f5f87' # Blue
|
||||||
|
blue3 = '#a6dbff' # Lightest Blue
|
||||||
|
blue4 = '#005f5f' # Blue Green
|
||||||
|
blue5 = '#5fafaf' # Dark Blue
|
||||||
|
blue6 = '#008787'
|
||||||
|
magenta = '#af5f5f' # Magenta
|
||||||
|
magenta1 = '#af5f87' # Soft Magenta
|
||||||
|
magenta2 = '#875f5f' # Dark Magenta
|
||||||
|
magenta3 = '#d7005f' # Darker Magenta
|
||||||
|
cyan = '#87d7d7' # Bright Cyan
|
||||||
|
cyan1 = '#afd7d7'
|
||||||
|
white = '#d0d0d0' # White
|
||||||
|
white1 = '#dadada' # White
|
||||||
|
purple = '#8787af' # Purple
|
||||||
|
brown = '#af875f' # Brownish
|
||||||
|
brown1 = '#875f00' # Brownish
|
||||||
|
orange = '#ff5f00' # Orange
|
||||||
|
salmon = '#ffaf87' # Salmon
|
||||||
|
salmon1 = '#d78787' # Salmon Bright
|
||||||
|
salmon2 = '#d7afaf' # Salmon Light
|
||||||
|
salmon3 = '#d7875f' # Yellowish
|
||||||
|
mauve = '#d75f87' # Mauve
|
||||||
|
|
||||||
|
gray = '#121212' # Very Dark Gray
|
||||||
|
gray1 = '#1c1c1c' # Darker Gray
|
||||||
|
gray2 = '#262626' # Dark Gray
|
||||||
|
gray3 = '#303030' # Dark Medium Gray
|
||||||
|
gray4 = '#3a3a3a' # Medium Gray
|
||||||
|
gray5 = '#444444' # Lighter Medium Gray
|
||||||
|
gray6 = '#585858' # Light Gray
|
||||||
|
gray7 = '#626262' # Lighter Gray
|
||||||
|
gray8 = '#4e4e4e' # Even Lighter Gray
|
||||||
|
gray9 = '#5f5f5f'
|
||||||
|
gray10 = '#c6c6c6'
|
||||||
|
gray11 = '#eeeeee'
|
||||||
|
gray12 = '#e4e4e4'
|
||||||
|
gray13 = '#bcbcbc'
|
||||||
|
|
||||||
|
# 233 = '#121212'
|
||||||
|
# 234 = '#1c1c1c'
|
||||||
|
# 235 = '#262626'
|
||||||
|
# 236 = '#303030'
|
||||||
|
# 237 = '#3a3a3a' # Default
|
||||||
|
# 238 = '#444444'
|
||||||
|
# 239 = '#4e4e4e'
|
16
runtime/themes/seoul256-light-hard.toml
Normal file
16
runtime/themes/seoul256-light-hard.toml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# Seoul256 Light Hard
|
||||||
|
# Author : EricHenry
|
||||||
|
# Original Creator: https://github.com/junegunn/seoul256.vim
|
||||||
|
|
||||||
|
inherits = "seoul256-light"
|
||||||
|
|
||||||
|
"ui.background" = { bg = "gray11" }
|
||||||
|
"ui.cursor.match" = { bg = "gray10", modifiers = ["underlined"] }
|
||||||
|
"ui.gutter" = { bg = "white1" }
|
||||||
|
"ui.cursorline.primary" = { bg = "gray12" }
|
||||||
|
"ui.gutter.selected" = { bg = "gray12" }
|
||||||
|
"ui.linenr.selected" = { bg = "gray12", fg = "magenta", modifiers = ["bold"] }
|
||||||
|
|
||||||
|
"ui.help" = { fg = "black1", bg = "gray12" }
|
||||||
|
"ui.popup" = { fg = "black1", bg = "gray12" }
|
||||||
|
"ui.menu" = { fg = "black1", bg = "gray12" }
|
16
runtime/themes/seoul256-light-soft.toml
Normal file
16
runtime/themes/seoul256-light-soft.toml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# Seoul256 Light Soft
|
||||||
|
# Author : EricHenry
|
||||||
|
# Original Creator: https://github.com/junegunn/seoul256.vim
|
||||||
|
|
||||||
|
inherits = "seoul256-light"
|
||||||
|
|
||||||
|
"ui.background" = { bg = "white" }
|
||||||
|
"ui.cursor.match" = { bg = "gray13", modifiers = ["underlined"] }
|
||||||
|
"ui.gutter" = { bg = "gray13" }
|
||||||
|
"ui.cursorline.primary" = { bg = "gray10" }
|
||||||
|
"ui.gutter.selected" = { bg = "gray10" }
|
||||||
|
"ui.linenr.selected" = { bg = "gray10", fg = "magenta", modifiers = ["bold"] }
|
||||||
|
|
||||||
|
"ui.help" = { fg = "black1", bg = "gray10" }
|
||||||
|
"ui.popup" = { fg = "black1", bg = "gray10" }
|
||||||
|
"ui.menu" = { fg = "black1", bg = "gray10" }
|
51
runtime/themes/seoul256-light.toml
Normal file
51
runtime/themes/seoul256-light.toml
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
# Seoul256 Light
|
||||||
|
# Author : EricHenry
|
||||||
|
# Original Creator: https://github.com/junegunn/seoul256.vim
|
||||||
|
|
||||||
|
inherits = "seoul256-dark"
|
||||||
|
|
||||||
|
"constructor" = { fg = "brown1" }
|
||||||
|
"constant.numeric" = { fg = "magenta2" }
|
||||||
|
"constant.builtin.boolean" = { fg = "mauve" }
|
||||||
|
"constant.character.escape" = { fg = "salmon3" }
|
||||||
|
"function" = { fg = "green4" }
|
||||||
|
"function.builtin" = { fg = "blue1" }
|
||||||
|
"function.method" = { fg = "salmon" }
|
||||||
|
"function.macro" = { fg = "green4" }
|
||||||
|
"namespace" = { fg = "blue4" }
|
||||||
|
"operator" = { fg = "brown1" }
|
||||||
|
"punctuation" = { fg = "brown1" }
|
||||||
|
"special" = { fg = "green4" }
|
||||||
|
"string" = { fg = "blue6" }
|
||||||
|
"type" = { fg = "brown1" }
|
||||||
|
"type.builtin" = { fg = "salmon3" }
|
||||||
|
"variable" = { fg = "black1" }
|
||||||
|
"variable.builtin" = { fg = "salmon3" }
|
||||||
|
"variable.parameter" = { fg = "black1" }
|
||||||
|
"variable.other.member" = { fg = "black1" }
|
||||||
|
|
||||||
|
"diagnostic.info".underline = { color = "green1", style = "curl" }
|
||||||
|
"info" = { fg = "green1", modifiers = ["bold"] }
|
||||||
|
"hint" = { fg = "blue", modifiers = ["bold"] }
|
||||||
|
"warning" = { fg = "yellow5", modifiers = ["bold"] }
|
||||||
|
|
||||||
|
"ui.background" = { bg = "white1" }
|
||||||
|
"ui.cursor" = { fg = "gray4", modifiers = ["reversed"] }
|
||||||
|
"ui.cursor.primary" = { fg = "gray4", modifiers = ["reversed"] }
|
||||||
|
"ui.cursor.match" = { bg = "gray13", modifiers = ["underlined"] }
|
||||||
|
"ui.cursor.insert" = { fg = "blue1" }
|
||||||
|
"ui.cursorline.primary" = { bg = "white" }
|
||||||
|
"ui.gutter" = { bg = "gray10" }
|
||||||
|
"ui.gutter.selected" = { bg = "white" }
|
||||||
|
"ui.linenr.selected" = { bg = "white", fg = "magenta", modifiers = ["bold"] }
|
||||||
|
"ui.virtual.inlay-hint" = { fg = "gray6", modifiers = ["bold"] }
|
||||||
|
|
||||||
|
"ui.selection" = { bg = "yellow2" }
|
||||||
|
"ui.selection.primary" = { bg = "cyan1" }
|
||||||
|
|
||||||
|
"ui.text" = { fg = "black1" }
|
||||||
|
|
||||||
|
"ui.help" = { fg = "black1", bg = "white" }
|
||||||
|
"ui.popup" = { fg = "black1", bg = "white" }
|
||||||
|
"ui.menu" = { fg = "black1", bg = "white" }
|
||||||
|
|
@ -53,6 +53,7 @@
|
|||||||
"ui.virtual.whitespace" = "bg2"
|
"ui.virtual.whitespace" = "bg2"
|
||||||
"ui.virtual.ruler" = { bg = "grey2" }
|
"ui.virtual.ruler" = { bg = "grey2" }
|
||||||
"ui.virtual.inlay-hint" = { fg = "grey2", modifiers = ["italic"] }
|
"ui.virtual.inlay-hint" = { fg = "grey2", modifiers = ["italic"] }
|
||||||
|
"ui.virtual.jump-label" = { fg = "nasty-red", modifiers = ["bold"] }
|
||||||
|
|
||||||
"hint" = "blue"
|
"hint" = "blue"
|
||||||
"info" = "aqua"
|
"info" = "aqua"
|
||||||
|
@ -63,7 +63,7 @@
|
|||||||
"ui.window" = { bg = "bg1" }
|
"ui.window" = { bg = "bg1" }
|
||||||
"ui.help" = { bg = "bg1", fg = "fg1" }
|
"ui.help" = { bg = "bg1", fg = "fg1" }
|
||||||
"ui.text" = { fg = "fg1" }
|
"ui.text" = { fg = "fg1" }
|
||||||
"ui.text.focus" = { fg = "fg1" }
|
"ui.text.focus" = { fg = "fg1", modifiers = ["bold"] }
|
||||||
"ui.selection" = { bg = "hl2" }
|
"ui.selection" = { bg = "hl2" }
|
||||||
"ui.selection.primary" = { bg = "hl1" }
|
"ui.selection.primary" = { bg = "hl1" }
|
||||||
"ui.cursor.primary" = { modifiers = ["reversed"] }
|
"ui.cursor.primary" = { modifiers = ["reversed"] }
|
||||||
|
159
runtime/themes/sunset.toml
Normal file
159
runtime/themes/sunset.toml
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
# Sunset
|
||||||
|
# Author : Egor Afanasin <afanasin.egor@gmail.com>
|
||||||
|
# Repo: https://github.com/pithecantrope/sunset
|
||||||
|
|
||||||
|
# Syntax highlighting
|
||||||
|
# ----------------------------------------------------------------
|
||||||
|
attribute = "rose"
|
||||||
|
|
||||||
|
type = "rose"
|
||||||
|
"type.builtin" = { fg = "rose", modifiers = ["italic"] }
|
||||||
|
|
||||||
|
constructor = "wood"
|
||||||
|
|
||||||
|
constant = "fire"
|
||||||
|
"constant.builtin" = { fg = "fire", modifiers = ["italic"] }
|
||||||
|
"constant.character" = "wood"
|
||||||
|
"constant.character.escape" = "pink"
|
||||||
|
"constant.numeric" = "wood"
|
||||||
|
|
||||||
|
string = "grass"
|
||||||
|
"string.regexp" = "pink"
|
||||||
|
"string.special" = "rose"
|
||||||
|
"string.special.symbol" = "fire"
|
||||||
|
|
||||||
|
comment = { fg = "cmnt", modifiers = ["italic"] }
|
||||||
|
"comment.block.documentation" = "grass"
|
||||||
|
|
||||||
|
variable = "text"
|
||||||
|
"variable.builtin" = { fg = "sky", modifiers = ["italic"] }
|
||||||
|
# TODO: variable.parameter
|
||||||
|
"variable.other.member" = "mud"
|
||||||
|
|
||||||
|
label = "sky"
|
||||||
|
|
||||||
|
punctuation = "cmnt"
|
||||||
|
"punctuation.special" = "wine"
|
||||||
|
|
||||||
|
keyword = "sun"
|
||||||
|
"keyword.control.return" = { fg = "sun", modifiers = ["italic"] }
|
||||||
|
"keyword.control.exception" = { fg = "sun", modifiers = ["italic"] }
|
||||||
|
"keyword.directive" = "sky"
|
||||||
|
|
||||||
|
operator = "wine"
|
||||||
|
|
||||||
|
function = "peach"
|
||||||
|
"function.builtin" = { fg = "peach", modifiers = ["italic"] }
|
||||||
|
"function.macro" = "pink"
|
||||||
|
|
||||||
|
tag = "peach"
|
||||||
|
|
||||||
|
namespace = { fg = "pink", modifiers = ["italic"] }
|
||||||
|
|
||||||
|
special = "sky"
|
||||||
|
|
||||||
|
# Editor interface
|
||||||
|
# ----------------------------------------------------------------
|
||||||
|
"markup.heading.marker" = "sun"
|
||||||
|
"markup.heading.1" = "attn"
|
||||||
|
"markup.heading.2" = "fire"
|
||||||
|
"markup.heading.3" = "rose"
|
||||||
|
"markup.heading.4" = "peach"
|
||||||
|
"markup.heading.5" = "wine"
|
||||||
|
"markup.heading.6" = "grass"
|
||||||
|
|
||||||
|
"markup.list" = "wood"
|
||||||
|
|
||||||
|
"markup.bold" = { modifiers = ["bold"] }
|
||||||
|
"markup.italic" = { modifiers = ["italic"] }
|
||||||
|
"markup.strikethrough" = { modifiers = ["crossed_out"] }
|
||||||
|
|
||||||
|
"markup.link.url" = { fg = "sky", underline.style = "line" }
|
||||||
|
"markup.link.label" = { fg = "sky", modifiers = ["italic"] }
|
||||||
|
"markup.link.text" = "mud"
|
||||||
|
|
||||||
|
"markup.quote" = "grass"
|
||||||
|
|
||||||
|
"markup.raw" = "pink"
|
||||||
|
|
||||||
|
"diff.plus" = "grass"
|
||||||
|
"diff.minus" = "attn"
|
||||||
|
"diff.delta" = "sky"
|
||||||
|
|
||||||
|
# User interface
|
||||||
|
# ----------------------------------------------------------------
|
||||||
|
"ui.background" = { fg = "text", bg = "base" }
|
||||||
|
|
||||||
|
"ui.cursor" = { modifiers = ["reversed"] }
|
||||||
|
"ui.cursor.match" = { fg = "attn", modifiers = ["bold"] }
|
||||||
|
|
||||||
|
# TODO: ui.debug
|
||||||
|
|
||||||
|
"ui.linenr" = "block"
|
||||||
|
"ui.linenr.selected" = "cmnt"
|
||||||
|
|
||||||
|
"ui.statusline" = { bg = "block" }
|
||||||
|
"ui.statusline.inactive" = { fg = "cmnt" }
|
||||||
|
"ui.statusline.normal" = { fg = "block", bg = "sun", modifiers = ["bold"] }
|
||||||
|
"ui.statusline.insert" = { fg = "block", bg = "grass", modifiers = ["bold"] }
|
||||||
|
"ui.statusline.select" = { fg = "block", bg = "wine", modifiers = ["bold"] }
|
||||||
|
|
||||||
|
"ui.bufferline" = { fg = "cmnt", bg = "block" }
|
||||||
|
"ui.bufferline.active" = "sun"
|
||||||
|
|
||||||
|
"ui.popup" = { fg = "text", bg = "base" }
|
||||||
|
"ui.popup.info" = { fg = "text", bg = "block" }
|
||||||
|
|
||||||
|
"ui.window" = { fg = "block", modifiers = ["bold"] }
|
||||||
|
|
||||||
|
"ui.help" = { fg = "text", bg = "block" }
|
||||||
|
|
||||||
|
"ui.text" = { fg = "text", bg = "base" }
|
||||||
|
"ui.text.focus" = "sun"
|
||||||
|
"ui.text.inactive" = { fg = "cmnt", modifiers = ["italic"] }
|
||||||
|
"ui.text.info" = { bg = "block" }
|
||||||
|
|
||||||
|
"ui.virtual" = { fg = "block" }
|
||||||
|
"ui.virtual.ruler" = { bg = "block" }
|
||||||
|
"ui.virtual.indent-guide" = "sel"
|
||||||
|
"ui.virtual.jump-label" = { fg = "attn", modifiers = ["bold"] }
|
||||||
|
|
||||||
|
"ui.menu" = { fg = "text", bg = "base" }
|
||||||
|
"ui.menu.selected" = { bg = "sel" }
|
||||||
|
"ui.menu.scroll" = "sel"
|
||||||
|
|
||||||
|
"ui.selection" = { bg = "sel" }
|
||||||
|
|
||||||
|
"ui.highlight" = { bg = "sel" }
|
||||||
|
|
||||||
|
error = "attn"
|
||||||
|
warning = "fire"
|
||||||
|
info = "pink"
|
||||||
|
hint = "sky"
|
||||||
|
|
||||||
|
diagnostic = { underline.style = "line" }
|
||||||
|
|
||||||
|
[palette]
|
||||||
|
# Reddish
|
||||||
|
fire = "#EE7711"
|
||||||
|
rose = "#EE7777"
|
||||||
|
peach = "#EEBB77"
|
||||||
|
pink = "#EEAAAA"
|
||||||
|
wood = "#997755"
|
||||||
|
|
||||||
|
# Greenish
|
||||||
|
grass = "#66CC33"
|
||||||
|
mud = "#BBCC77"
|
||||||
|
sun = "#EEEE11"
|
||||||
|
|
||||||
|
# Bluish
|
||||||
|
sky = "#77AAAA"
|
||||||
|
wine = "#775599"
|
||||||
|
|
||||||
|
# Ui
|
||||||
|
base = "#111111"
|
||||||
|
block = "#222222"
|
||||||
|
sel = "#333333"
|
||||||
|
cmnt = "#777777"
|
||||||
|
text = "#EEEEEE"
|
||||||
|
attn = "#EE1111"
|
125
runtime/themes/yo.toml
Normal file
125
runtime/themes/yo.toml
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
# Author: Michael McClintock <michael.mcclintock@hey.com>
|
||||||
|
# License: MIT
|
||||||
|
|
||||||
|
# Yo - Themes for Helix inspired by Zenbones & Alabaster with Radix Colors.
|
||||||
|
# https://github.com/mrmcc3/yo-theme-helix
|
||||||
|
|
||||||
|
# background/text
|
||||||
|
"ui.background" = { fg = "p11", bg = "p2" }
|
||||||
|
"ui.background.separator" = { fg = "p7" }
|
||||||
|
"ui.text" = { fg = "p11" }
|
||||||
|
"ui.text.focus" = { fg = "p12", modifiers = ["bold"] }
|
||||||
|
|
||||||
|
# popups/menus
|
||||||
|
"ui.window" = { fg = "p7" }
|
||||||
|
"ui.popup" = { fg = "p12", bg = "p4" }
|
||||||
|
"ui.popup.info" = { fg = "p12", bg = "p2" }
|
||||||
|
"ui.text.info" = { fg = "p12", bg = "p2" }
|
||||||
|
"ui.help" = { fg = "p12", bg = "p2" }
|
||||||
|
"ui.menu" = { fg = "p11", bg = "p4" }
|
||||||
|
"ui.menu.selected" = { fg = "p12", modifiers = ["bold"] }
|
||||||
|
"ui.menu.scroll" = { fg = "p8", bg = "p4" }
|
||||||
|
"ui.picker.header.column" = { underline.style = "line" }
|
||||||
|
|
||||||
|
# cursor/selection
|
||||||
|
"ui.cursor" = { fg = "p2", bg = "p11" }
|
||||||
|
"ui.cursor.insert" = { fg = "p2", bg = "keyword" }
|
||||||
|
"ui.cursor.select" = { fg = "p2", bg = "p12" }
|
||||||
|
"ui.cursor.match" = { fg = "p12", modifiers = ["bold"] }
|
||||||
|
"ui.cursor.primary" = { fg = "p2", bg = "p11", modifiers = ["bold"] }
|
||||||
|
"ui.cursor.primary.insert" = { fg = "p2", bg = "keyword", modifiers = ["bold"] }
|
||||||
|
"ui.cursor.primary.select" = { fg = "p2", bg = "p12", modifiers = ["bold"] }
|
||||||
|
"ui.selection" = { bg = "p4" }
|
||||||
|
"ui.selection.primary" = { bg = "p5" }
|
||||||
|
"ui.cursorline.primary" = { bg = "p3" }
|
||||||
|
"ui.cursorcolumn.primary" = { bg = "p3" }
|
||||||
|
|
||||||
|
# line numbers / diff
|
||||||
|
"ui.linenr" = { fg = "p7" }
|
||||||
|
"ui.linenr.selected" = { fg = "p11" }
|
||||||
|
diff = { fg = "p8" }
|
||||||
|
|
||||||
|
# bufferline/statusline
|
||||||
|
"ui.bufferline" = { fg = "p11", bg = "p4" }
|
||||||
|
"ui.bufferline.active" = { fg = "p2", bg = "p11" }
|
||||||
|
"ui.statusline" = { fg = "p11", bg = "p4" }
|
||||||
|
"ui.statusline.inactive" = { fg = "p11", bg = "p2" }
|
||||||
|
"ui.statusline.normal" = { fg = "p2", bg = "p11" }
|
||||||
|
"ui.statusline.insert" = { fg = "p2", bg = "keyword" }
|
||||||
|
"ui.statusline.select" = { fg = "p2", bg = "p12" }
|
||||||
|
"ui.statusline.separator" = { fg = "p7" }
|
||||||
|
|
||||||
|
# virtual
|
||||||
|
"ui.virtual" = { fg = "p6" }
|
||||||
|
"ui.virtual.ruler" = { bg = "p3" }
|
||||||
|
"ui.virtual.inlay-hint" = { fg = "p7", underline.style = "dotted" }
|
||||||
|
"ui.virtual.jump-label" = { fg = "p12", modifiers = [
|
||||||
|
"bold",
|
||||||
|
], underline = { style = "curl", color = "info" } }
|
||||||
|
|
||||||
|
# diagnostics
|
||||||
|
error = { fg = "error", modifiers = ["bold"] }
|
||||||
|
warning = { fg = "warning", modifiers = ["bold"] }
|
||||||
|
info = { fg = "info", modifiers = ["bold"] }
|
||||||
|
hint = { fg = "info", modifiers = ["bold"] }
|
||||||
|
"diagnostic.error" = { fg = "error", modifiers = ["bold"] }
|
||||||
|
"diagnostic.warning" = { fg = "warning", modifiers = ["bold"] }
|
||||||
|
"diagnostic.info" = { fg = "info", modifiers = ["bold"] }
|
||||||
|
"diagnostic.hint" = { fg = "info", modifiers = ["bold"] }
|
||||||
|
# "diagnostic.unnecessary" = {}
|
||||||
|
# "diagnostic.deprecated" = {}
|
||||||
|
|
||||||
|
# code
|
||||||
|
comment = { fg = "info" }
|
||||||
|
keyword = { fg = "keyword" }
|
||||||
|
operator = { fg = "keyword" }
|
||||||
|
string = { fg = "string" }
|
||||||
|
constant = { fg = "constant" }
|
||||||
|
"string.special.symbol" = { fg = "constant" }
|
||||||
|
variable = { fg = "p10" }
|
||||||
|
namespace = { fg = "p10" }
|
||||||
|
punctuation = { fg = "p9" }
|
||||||
|
"punctuation.delimiter" = { fg = "p8" }
|
||||||
|
function = { fg = "p11" }
|
||||||
|
attribute = { fg = "p10" }
|
||||||
|
tag = { fg = "keyword" }
|
||||||
|
label = { fg = "p12" }
|
||||||
|
constructor = { fg = "p12" }
|
||||||
|
type = { fg = "p12" }
|
||||||
|
|
||||||
|
# markup
|
||||||
|
"markup.bold" = { modifiers = ["bold"] }
|
||||||
|
"markup.italic" = { modifiers = ["italic"] }
|
||||||
|
"markup.strikethrough" = { modifiers = ["crossed_out"] }
|
||||||
|
"markup.heading" = { fg = "p12", modifiers = ["bold"] }
|
||||||
|
"markup.heading.marker" = { fg = "p8" }
|
||||||
|
"markup.list" = { fg = "p8" }
|
||||||
|
"markup.link.url" = { underline.style = "line" }
|
||||||
|
"markup.link.label" = { underline.style = "dotted" }
|
||||||
|
# "markup.link.text" = {}
|
||||||
|
"markup.quote" = { fg = "p10" }
|
||||||
|
# "markup.raw" = {}
|
||||||
|
|
||||||
|
[palette] # https://www.radix-ui.com/colors
|
||||||
|
|
||||||
|
# grayDark
|
||||||
|
p1 = "#111111"
|
||||||
|
p2 = "#191919"
|
||||||
|
p3 = "#222222"
|
||||||
|
p4 = "#2a2a2a"
|
||||||
|
p5 = "#313131"
|
||||||
|
p6 = "#3a3a3a"
|
||||||
|
p7 = "#484848"
|
||||||
|
p8 = "#606060"
|
||||||
|
p9 = "#6e6e6e"
|
||||||
|
p10 = "#7b7b7b"
|
||||||
|
p11 = "#b4b4b4"
|
||||||
|
p12 = "#eeeeee"
|
||||||
|
|
||||||
|
error = "#ec5d5e" # redDark-10
|
||||||
|
warning = "#ff801f" # orangeDark-10
|
||||||
|
info = "#3b9eff" # blueDark-10
|
||||||
|
|
||||||
|
string = "#33b074" # greenDark-10
|
||||||
|
constant = "#9a5cd0" # purpleDark-10
|
||||||
|
keyword = "#ae8c7e" # bronzeDark-10
|
31
runtime/themes/yo_berry.toml
Normal file
31
runtime/themes/yo_berry.toml
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# Author: Michael McClintock <michael.mcclintock@hey.com>
|
||||||
|
# License: MIT
|
||||||
|
|
||||||
|
# Yo - Themes for Helix inspired by Zenbones & Alabaster with Radix Colors.
|
||||||
|
# https://github.com/mrmcc3/yo-theme-helix
|
||||||
|
|
||||||
|
inherits = "yo"
|
||||||
|
|
||||||
|
[palette]
|
||||||
|
|
||||||
|
# mauveDark
|
||||||
|
p1 = "#121113"
|
||||||
|
p2 = "#1a191b"
|
||||||
|
p3 = "#232225"
|
||||||
|
p4 = "#2b292d"
|
||||||
|
p5 = "#323035"
|
||||||
|
p6 = "#3c393f"
|
||||||
|
p7 = "#49474e"
|
||||||
|
p8 = "#625f69"
|
||||||
|
p9 = "#6f6d78"
|
||||||
|
p10 = "#7c7a85"
|
||||||
|
p11 = "#b5b2bc"
|
||||||
|
p12 = "#eeeef0"
|
||||||
|
|
||||||
|
error = "#ee518a" # crimsonDark-10
|
||||||
|
warning = "#ffff57" # yellowDark-10
|
||||||
|
info = "#3b9eff" # blueDark-10
|
||||||
|
|
||||||
|
string = "#0eb39e" # teal-10
|
||||||
|
constant = "#b658c4" # plum-10
|
||||||
|
keyword = "#9eb1ff" # indigo-11
|
34
runtime/themes/yo_light.toml
Normal file
34
runtime/themes/yo_light.toml
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# Author: Michael McClintock <michael.mcclintock@hey.com>
|
||||||
|
# License: MIT
|
||||||
|
|
||||||
|
# Yo - Themes for Helix inspired by Zenbones & Alabaster with Radix Colors.
|
||||||
|
# https://github.com/mrmcc3/yo-theme-helix
|
||||||
|
|
||||||
|
inherits = "yo"
|
||||||
|
|
||||||
|
"ui.virtual.inlay-hint" = { fg = "p8", underline.style = "dotted" }
|
||||||
|
"markup.quote" = { fg = "p9" }
|
||||||
|
|
||||||
|
[palette]
|
||||||
|
|
||||||
|
# gray
|
||||||
|
p1 = "#fcfcfc"
|
||||||
|
p2 = "#f9f9f9"
|
||||||
|
p3 = "#f0f0f0"
|
||||||
|
p4 = "#e8e8e8"
|
||||||
|
p5 = "#e0e0e0"
|
||||||
|
p6 = "#d9d9d9"
|
||||||
|
p7 = "#cecece"
|
||||||
|
p8 = "#bbbbbb"
|
||||||
|
p9 = "#8d8d8d"
|
||||||
|
p10 = "#838383"
|
||||||
|
p11 = "#646464"
|
||||||
|
p12 = "#202020"
|
||||||
|
|
||||||
|
error = "#dc3e42" # red-10
|
||||||
|
warning = "#ef5f00" # orange-10
|
||||||
|
info = "#0588f0" # blue-10
|
||||||
|
|
||||||
|
string = "#2b9a66" # green-10
|
||||||
|
constant = "#8347b9" # purple-10
|
||||||
|
keyword = "#957468" # bronze-10
|
@ -1223,7 +1223,7 @@ letters! that is not good grammar. you can fix this.
|
|||||||
to the matching ). You can do the same on the line below: for example
|
to the matching ). You can do the same on the line below: for example
|
||||||
move to ], and press mm to jump to [ .
|
move to ], and press mm to jump to [ .
|
||||||
|
|
||||||
--> you can (jump between matching parenthesis)
|
--> you can (jump between matching parentheses)
|
||||||
--> or between matching [ square brackets ]
|
--> or between matching [ square brackets ]
|
||||||
--> now { you know the drill: this works with brackets too }
|
--> now { you know the drill: this works with brackets too }
|
||||||
|
|
||||||
@ -1238,19 +1238,19 @@ letters! that is not good grammar. you can fix this.
|
|||||||
pair of brackets or other delimiters. In the lines below:
|
pair of brackets or other delimiters. In the lines below:
|
||||||
|
|
||||||
- move to the --> line, put your cursor in normal mode at any
|
- move to the --> line, put your cursor in normal mode at any
|
||||||
location between the parenthesis, for example at 'x', and press
|
location between the parentheses, for example at 'x', and press
|
||||||
mi( or mi) to select the whole content inside the parenthesis
|
mi( or mi) to select the whole content inside the parentheses
|
||||||
(parenthesis excluded). As usual, you can then do anything you want
|
(parentheses excluded). As usual, you can then do anything you want
|
||||||
with the selection (for example, press c to change it)
|
with the selection (for example, press c to change it)
|
||||||
|
|
||||||
--> outside and (inside x parenthesis) - and outside again
|
--> outside and (inside x parentheses) - and outside again
|
||||||
|
|
||||||
Test below that you can do the same with [], or {}, or with
|
Test below that you can do the same with [], or {}, or with
|
||||||
nested combinations of these (this will act on the immediately
|
nested combinations of these (this will act on the immediately
|
||||||
surrounding matching pair). This also works with "" and similar
|
surrounding matching pair). This also works with "" and similar
|
||||||
|
|
||||||
--> test [ with square brackets ] !
|
--> test [ with square brackets ] !
|
||||||
--> try ( with nested [ pairs of ( parenthesis) and "brackets" ])
|
--> try ( with nested [ pairs of ( parentheses) and "brackets" ])
|
||||||
|
|
||||||
=================================================================
|
=================================================================
|
||||||
= 12.3 USING MATCH MODE SELECT AROUND =
|
= 12.3 USING MATCH MODE SELECT AROUND =
|
||||||
@ -1284,7 +1284,7 @@ letters! that is not good grammar. you can fix this.
|
|||||||
move in normal mode the cursor to the start of select, then enter
|
move in normal mode the cursor to the start of select, then enter
|
||||||
selection mode with v , then select the 4 next words with 4e ),
|
selection mode with v , then select the 4 next words with 4e ),
|
||||||
* ii) press ms( or ms) to surround the selection with a pair of
|
* ii) press ms( or ms) to surround the selection with a pair of
|
||||||
parenthesis.
|
parentheses.
|
||||||
|
|
||||||
--> so, select all of this, and surround it with ()
|
--> so, select all of this, and surround it with ()
|
||||||
|
|
||||||
@ -1304,9 +1304,9 @@ letters! that is not good grammar. you can fix this.
|
|||||||
command. On the line below, move the cursor anywhere
|
command. On the line below, move the cursor anywhere
|
||||||
within the pair of (), for example to the 'x', then from there,
|
within the pair of (), for example to the 'x', then from there,
|
||||||
in normal mode, press md( or md) to delete the surrounding
|
in normal mode, press md( or md) to delete the surrounding
|
||||||
pair of parenthesis.
|
pair of parentheses.
|
||||||
|
|
||||||
--> delete (the x pair of parenthesis) from within!
|
--> delete (the x pair of parentheses) from within!
|
||||||
|
|
||||||
You can naturally delete other kinds of surroundings:
|
You can naturally delete other kinds of surroundings:
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user