mirror of
https://github.com/helix-editor/helix.git
synced 2024-11-22 09:26:19 +04:00
Merge branch 'helix-editor:master' into pull-diagnostics
This commit is contained in:
commit
5311f4ab58
2
.github/workflows/cachix.yml
vendored
2
.github/workflows/cachix.yml
vendored
@ -14,7 +14,7 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install nix
|
||||
uses: cachix/install-nix-action@v29
|
||||
uses: cachix/install-nix-action@v30
|
||||
|
||||
- name: Authenticate with Cachix
|
||||
uses: cachix/cachix-action@v15
|
||||
|
47
Cargo.lock
generated
47
Cargo.lock
generated
@ -68,9 +68,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.89"
|
||||
version = "1.0.90"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6"
|
||||
checksum = "37bf3594c4c988a53154954629820791dde498571819ae4ca50ca811e060cc95"
|
||||
|
||||
[[package]]
|
||||
name = "arc-swap"
|
||||
@ -136,9 +136,9 @@ checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.1.23"
|
||||
version = "1.1.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3bbb537bb4a30b90362caddba8f360c0a56bc13d3a5570028e7197204cb54a17"
|
||||
checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f"
|
||||
dependencies = [
|
||||
"shlex",
|
||||
]
|
||||
@ -355,9 +355,9 @@ checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6"
|
||||
|
||||
[[package]]
|
||||
name = "fern"
|
||||
version = "0.6.2"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9f0c14694cbd524c8720dd69b0e3179344f04ebb5f90f2e4a440c6ea3b2f1ee"
|
||||
checksum = "69ff9c9d5fb3e6da8ac2f77ab76fe7e8087d512ce095200f8f29ac5b656cf6dc"
|
||||
dependencies = [
|
||||
"log",
|
||||
]
|
||||
@ -412,15 +412,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.30"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
|
||||
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.30"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
|
||||
checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
@ -429,15 +429,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.30"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
|
||||
checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.30"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
|
||||
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
@ -1609,9 +1609,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.159"
|
||||
version = "0.2.161"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5"
|
||||
checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
@ -1753,12 +1753,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.20.1"
|
||||
version = "1.20.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1"
|
||||
dependencies = [
|
||||
"portable-atomic",
|
||||
]
|
||||
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
|
||||
|
||||
[[package]]
|
||||
name = "open"
|
||||
@ -1841,9 +1838,9 @@ checksum = "744a264d26b88a6a7e37cbad97953fa233b94d585236310bcbc88474b4092d79"
|
||||
|
||||
[[package]]
|
||||
name = "pulldown-cmark"
|
||||
version = "0.12.1"
|
||||
version = "0.12.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "666f0f59e259aea2d72e6012290c09877a780935cc3c18b1ceded41f3890d59c"
|
||||
checksum = "f86ba2052aebccc42cbbb3ed234b8b13ce76f75c3551a303cb2bcffcff12bb14"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"memchr",
|
||||
@ -2029,9 +2026,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.128"
|
||||
version = "1.0.132"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8"
|
||||
checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
|
@ -47,7 +47,7 @@ # Installation
|
||||
|
||||
[Installation documentation](https://docs.helix-editor.com/install.html).
|
||||
|
||||
[![Packaging status](https://repology.org/badge/vertical-allrepos/helix.svg?exclude_unsupported=1)](https://repology.org/project/helix/versions)
|
||||
[![Packaging status](https://repology.org/badge/vertical-allrepos/helix-editor.svg?exclude_unsupported=1)](https://repology.org/project/helix-editor/versions)
|
||||
|
||||
# Contributing
|
||||
|
||||
|
@ -29,6 +29,7 @@
|
||||
| crystal | ✓ | ✓ | | `crystalline` |
|
||||
| css | ✓ | | ✓ | `vscode-css-language-server` |
|
||||
| cue | ✓ | | | `cuelsp` |
|
||||
| cylc | ✓ | ✓ | ✓ | |
|
||||
| d | ✓ | ✓ | ✓ | `serve-d` |
|
||||
| dart | ✓ | ✓ | ✓ | `dart` |
|
||||
| dbml | ✓ | | | |
|
||||
@ -39,6 +40,7 @@
|
||||
| dockerfile | ✓ | ✓ | | `docker-langserver` |
|
||||
| dot | ✓ | | | `dot-language-server` |
|
||||
| dtd | ✓ | | | |
|
||||
| dune | ✓ | | | |
|
||||
| earthfile | ✓ | ✓ | ✓ | `earthlyls` |
|
||||
| edoc | ✓ | | | |
|
||||
| eex | ✓ | | | |
|
||||
@ -68,7 +70,7 @@
|
||||
| gjs | ✓ | ✓ | ✓ | `typescript-language-server`, `vscode-eslint-language-server`, `ember-language-server` |
|
||||
| gleam | ✓ | ✓ | | `gleam` |
|
||||
| glimmer | ✓ | | | `ember-language-server` |
|
||||
| glsl | ✓ | ✓ | ✓ | |
|
||||
| glsl | ✓ | ✓ | ✓ | `glsl_analyzer` |
|
||||
| gn | ✓ | | | |
|
||||
| go | ✓ | ✓ | ✓ | `gopls`, `golangci-lint-langserver` |
|
||||
| godot-resource | ✓ | ✓ | | |
|
||||
@ -185,6 +187,7 @@
|
||||
| smali | ✓ | | ✓ | |
|
||||
| smithy | ✓ | | | `cs` |
|
||||
| sml | ✓ | | | |
|
||||
| snakemake | ✓ | | ✓ | `pylsp` |
|
||||
| solidity | ✓ | ✓ | | `solc` |
|
||||
| spicedb | ✓ | | | |
|
||||
| sql | ✓ | ✓ | | |
|
||||
|
@ -17,7 +17,7 @@ ## Package managers
|
||||
- [Chocolatey](#chocolatey)
|
||||
- [MSYS2](#msys2)
|
||||
|
||||
[![Packaging status](https://repology.org/badge/vertical-allrepos/helix.svg)](https://repology.org/project/helix/versions)
|
||||
[![Packaging status](https://repology.org/badge/vertical-allrepos/helix-editor.svg)](https://repology.org/project/helix-editor/versions)
|
||||
|
||||
## Linux
|
||||
|
||||
|
@ -283,7 +283,6 @@ #### Interface
|
||||
| `ui.debug.active` | Indicator for the line at which debugging execution is paused at, found in the gutter |
|
||||
| `ui.gutter` | Gutter |
|
||||
| `ui.gutter.selected` | Gutter for the line the cursor is on |
|
||||
| `ui.highlight.frameline` | Line at which debugging execution is paused at |
|
||||
| `ui.linenr` | Line numbers |
|
||||
| `ui.linenr.selected` | Line number for the line the cursor is on |
|
||||
| `ui.statusline` | Statusline |
|
||||
@ -297,7 +296,7 @@ #### Interface
|
||||
| `ui.bufferline.background` | Style for bufferline background |
|
||||
| `ui.popup` | Documentation popups (e.g. Space + k) |
|
||||
| `ui.popup.info` | Prompt for multiple key options |
|
||||
| `ui.picker.header` | Header row area in pickers with multiple columns |
|
||||
| `ui.picker.header` | Header row area in pickers with multiple columns |
|
||||
| `ui.picker.header.column` | Column names in pickers with multiple columns |
|
||||
| `ui.picker.header.column.active` | The column name in pickers with multiple columns where the cursor is entering into. |
|
||||
| `ui.window` | Borderlines separating splits |
|
||||
@ -320,6 +319,7 @@ #### Interface
|
||||
| `ui.selection` | For selections in the editing area |
|
||||
| `ui.selection.primary` | |
|
||||
| `ui.highlight` | Highlighted lines in the picker preview |
|
||||
| `ui.highlight.frameline` | Line at which debugging execution is paused at |
|
||||
| `ui.cursorline.primary` | The line of the primary cursor ([if cursorline is enabled][editor-section]) |
|
||||
| `ui.cursorline.secondary` | The lines of any other cursors ([if cursorline is enabled][editor-section]) |
|
||||
| `ui.cursorcolumn.primary` | The column of the primary cursor ([if cursorcolumn is enabled][editor-section]) |
|
||||
|
32
flake.lock
32
flake.lock
@ -1,17 +1,12 @@
|
||||
{
|
||||
"nodes": {
|
||||
"crane": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1709610799,
|
||||
"narHash": "sha256-5jfLQx0U9hXbi2skYMGodDJkIgffrjIOgMRjZqms2QE=",
|
||||
"lastModified": 1727974419,
|
||||
"narHash": "sha256-WD0//20h+2/yPGkO88d2nYbb23WMWYvnRyDQ9Dx4UHg=",
|
||||
"owner": "ipetkov",
|
||||
"repo": "crane",
|
||||
"rev": "81c393c776d5379c030607866afef6406ca1be57",
|
||||
"rev": "37e4f9f0976cb9281cd3f0c70081e5e0ecaee93f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -25,11 +20,11 @@
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1709126324,
|
||||
"narHash": "sha256-q6EQdSeUZOG26WelxqkmR7kArjgWCdw5sfJVHPH/7j8=",
|
||||
"lastModified": 1726560853,
|
||||
"narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "d465f4819400de7c8d874d50b982301f28a84605",
|
||||
"rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -40,11 +35,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1709479366,
|
||||
"narHash": "sha256-n6F0n8UV6lnTZbYPl1A9q1BS0p4hduAv1mGAP17CVd0=",
|
||||
"lastModified": 1728018373,
|
||||
"narHash": "sha256-NOiTvBbRLIOe5F6RbHaAh6++BNjsb149fGZd1T4+KBg=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "b8697e57f10292a6165a20f03d2f42920dfaf973",
|
||||
"rev": "bc947f541ae55e999ffdb4013441347d83b00feb",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -64,19 +59,16 @@
|
||||
},
|
||||
"rust-overlay": {
|
||||
"inputs": {
|
||||
"flake-utils": [
|
||||
"flake-utils"
|
||||
],
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1709604635,
|
||||
"narHash": "sha256-le4fwmWmjGRYWwkho0Gr7mnnZndOOe4XGbLw68OvF40=",
|
||||
"lastModified": 1728268235,
|
||||
"narHash": "sha256-lJMFnMO4maJuNO6PQ5fZesrTmglze3UFTTBuKGwR1Nw=",
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"rev": "e86c0fb5d3a22a5f30d7f64ecad88643fe26449d",
|
||||
"rev": "25685cc2c7054efc31351c172ae77b21814f2d42",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
10
flake.nix
10
flake.nix
@ -6,15 +6,9 @@
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
rust-overlay = {
|
||||
url = "github:oxalica/rust-overlay";
|
||||
inputs = {
|
||||
nixpkgs.follows = "nixpkgs";
|
||||
flake-utils.follows = "flake-utils";
|
||||
};
|
||||
};
|
||||
crane = {
|
||||
url = "github:ipetkov/crane";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
crane.url = "github:ipetkov/crane";
|
||||
};
|
||||
|
||||
outputs = {
|
||||
@ -114,7 +108,7 @@
|
||||
if pkgs.stdenv.isLinux
|
||||
then pkgs.stdenv
|
||||
else pkgs.clangStdenv;
|
||||
rustFlagsEnv = pkgs.lib.optionalString stdenv.isLinux "-C link-arg=-fuse-ld=lld -C target-cpu=native -Clink-arg=-Wl,--no-rosegment";
|
||||
rustFlagsEnv = pkgs.lib.optionalString stdenv.isLinux "-C link-arg=-fuse-ld=lld -C target-cpu=native -Clink-arg=-Wl,--no-rosegment --cfg tokio_unstable";
|
||||
rustToolchain = pkgs.pkgsBuildHost.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml;
|
||||
craneLibMSRV = (crane.mkLib pkgs).overrideToolchain rustToolchain;
|
||||
craneLibStable = (crane.mkLib pkgs).overrideToolchain pkgs.pkgsBuildHost.rust-bin.stable.latest.default;
|
||||
|
@ -9,6 +9,24 @@
|
||||
use helix_stdx::rope::RopeSliceExt;
|
||||
use std::borrow::Cow;
|
||||
|
||||
pub const DEFAULT_COMMENT_TOKEN: &str = "//";
|
||||
|
||||
/// Returns the longest matching comment token of the given line (if it exists).
|
||||
pub fn get_comment_token<'a, S: AsRef<str>>(
|
||||
text: RopeSlice,
|
||||
tokens: &'a [S],
|
||||
line_num: usize,
|
||||
) -> Option<&'a str> {
|
||||
let line = text.line(line_num);
|
||||
let start = line.first_non_whitespace_char()?;
|
||||
|
||||
tokens
|
||||
.iter()
|
||||
.map(AsRef::as_ref)
|
||||
.filter(|token| line.slice(start..).starts_with(token))
|
||||
.max_by_key(|token| token.len())
|
||||
}
|
||||
|
||||
/// Given text, a comment token, and a set of line indices, returns the following:
|
||||
/// - Whether the given lines should be considered commented
|
||||
/// - If any of the lines are uncommented, all lines are considered as such.
|
||||
@ -28,21 +46,20 @@ fn find_line_comment(
|
||||
let mut min = usize::MAX; // minimum col for first_non_whitespace_char
|
||||
let mut margin = 1;
|
||||
let token_len = token.chars().count();
|
||||
|
||||
for line in lines {
|
||||
let line_slice = text.line(line);
|
||||
if let Some(pos) = line_slice.first_non_whitespace_char() {
|
||||
let len = line_slice.len_chars();
|
||||
|
||||
if pos < min {
|
||||
min = pos;
|
||||
}
|
||||
min = std::cmp::min(min, pos);
|
||||
|
||||
// line can be shorter than pos + token len
|
||||
let fragment = Cow::from(line_slice.slice(pos..std::cmp::min(pos + token.len(), len)));
|
||||
|
||||
// as soon as one of the non-blank lines doesn't have a comment, the whole block is
|
||||
// considered uncommented.
|
||||
if fragment != token {
|
||||
// as soon as one of the non-blank lines doesn't have a comment, the whole block is
|
||||
// considered uncommented.
|
||||
commented = false;
|
||||
}
|
||||
|
||||
@ -56,6 +73,7 @@ fn find_line_comment(
|
||||
to_change.push(line);
|
||||
}
|
||||
}
|
||||
|
||||
(commented, to_change, min, margin)
|
||||
}
|
||||
|
||||
@ -63,7 +81,7 @@ fn find_line_comment(
|
||||
pub fn toggle_line_comments(doc: &Rope, selection: &Selection, token: Option<&str>) -> Transaction {
|
||||
let text = doc.slice(..);
|
||||
|
||||
let token = token.unwrap_or("//");
|
||||
let token = token.unwrap_or(DEFAULT_COMMENT_TOKEN);
|
||||
let comment = Tendril::from(format!("{} ", token));
|
||||
|
||||
let mut lines: Vec<usize> = Vec::with_capacity(selection.len());
|
||||
@ -317,56 +335,87 @@ pub fn split_lines_of_selection(text: RopeSlice, selection: &Selection) -> Selec
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_find_line_comment() {
|
||||
// four lines, two space indented, except for line 1 which is blank.
|
||||
let mut doc = Rope::from(" 1\n\n 2\n 3");
|
||||
// select whole document
|
||||
let mut selection = Selection::single(0, doc.len_chars() - 1);
|
||||
mod find_line_comment {
|
||||
use super::*;
|
||||
|
||||
let text = doc.slice(..);
|
||||
#[test]
|
||||
fn not_commented() {
|
||||
// four lines, two space indented, except for line 1 which is blank.
|
||||
let doc = Rope::from(" 1\n\n 2\n 3");
|
||||
|
||||
let res = find_line_comment("//", text, 0..3);
|
||||
// (commented = true, to_change = [line 0, line 2], min = col 2, margin = 0)
|
||||
assert_eq!(res, (false, vec![0, 2], 2, 0));
|
||||
let text = doc.slice(..);
|
||||
|
||||
// comment
|
||||
let transaction = toggle_line_comments(&doc, &selection, None);
|
||||
transaction.apply(&mut doc);
|
||||
selection = selection.map(transaction.changes());
|
||||
let res = find_line_comment("//", text, 0..3);
|
||||
// (commented = false, to_change = [line 0, line 2], min = col 2, margin = 0)
|
||||
assert_eq!(res, (false, vec![0, 2], 2, 0));
|
||||
}
|
||||
|
||||
assert_eq!(doc, " // 1\n\n // 2\n // 3");
|
||||
#[test]
|
||||
fn is_commented() {
|
||||
// three lines where the second line is empty.
|
||||
let doc = Rope::from("// hello\n\n// there");
|
||||
|
||||
// uncomment
|
||||
let transaction = toggle_line_comments(&doc, &selection, None);
|
||||
transaction.apply(&mut doc);
|
||||
selection = selection.map(transaction.changes());
|
||||
assert_eq!(doc, " 1\n\n 2\n 3");
|
||||
assert!(selection.len() == 1); // to ignore the selection unused warning
|
||||
let res = find_line_comment("//", doc.slice(..), 0..3);
|
||||
|
||||
// 0 margin comments
|
||||
doc = Rope::from(" //1\n\n //2\n //3");
|
||||
// reset the selection.
|
||||
selection = Selection::single(0, doc.len_chars() - 1);
|
||||
// (commented = true, to_change = [line 0, line 2], min = col 0, margin = 1)
|
||||
assert_eq!(res, (true, vec![0, 2], 0, 1));
|
||||
}
|
||||
}
|
||||
|
||||
let transaction = toggle_line_comments(&doc, &selection, None);
|
||||
transaction.apply(&mut doc);
|
||||
selection = selection.map(transaction.changes());
|
||||
assert_eq!(doc, " 1\n\n 2\n 3");
|
||||
assert!(selection.len() == 1); // to ignore the selection unused warning
|
||||
// TODO: account for uncommenting with uneven comment indentation
|
||||
mod toggle_line_comment {
|
||||
use super::*;
|
||||
|
||||
// 0 margin comments, with no space
|
||||
doc = Rope::from("//");
|
||||
// reset the selection.
|
||||
selection = Selection::single(0, doc.len_chars() - 1);
|
||||
#[test]
|
||||
fn comment() {
|
||||
// four lines, two space indented, except for line 1 which is blank.
|
||||
let mut doc = Rope::from(" 1\n\n 2\n 3");
|
||||
// select whole document
|
||||
let selection = Selection::single(0, doc.len_chars() - 1);
|
||||
|
||||
let transaction = toggle_line_comments(&doc, &selection, None);
|
||||
transaction.apply(&mut doc);
|
||||
selection = selection.map(transaction.changes());
|
||||
assert_eq!(doc, "");
|
||||
assert!(selection.len() == 1); // to ignore the selection unused warning
|
||||
let transaction = toggle_line_comments(&doc, &selection, None);
|
||||
transaction.apply(&mut doc);
|
||||
|
||||
// TODO: account for uncommenting with uneven comment indentation
|
||||
assert_eq!(doc, " // 1\n\n // 2\n // 3");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn uncomment() {
|
||||
let mut doc = Rope::from(" // 1\n\n // 2\n // 3");
|
||||
let mut selection = Selection::single(0, doc.len_chars() - 1);
|
||||
|
||||
let transaction = toggle_line_comments(&doc, &selection, None);
|
||||
transaction.apply(&mut doc);
|
||||
selection = selection.map(transaction.changes());
|
||||
|
||||
assert_eq!(doc, " 1\n\n 2\n 3");
|
||||
assert!(selection.len() == 1); // to ignore the selection unused warning
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn uncomment_0_margin_comments() {
|
||||
let mut doc = Rope::from(" //1\n\n //2\n //3");
|
||||
let mut selection = Selection::single(0, doc.len_chars() - 1);
|
||||
|
||||
let transaction = toggle_line_comments(&doc, &selection, None);
|
||||
transaction.apply(&mut doc);
|
||||
selection = selection.map(transaction.changes());
|
||||
|
||||
assert_eq!(doc, " 1\n\n 2\n 3");
|
||||
assert!(selection.len() == 1); // to ignore the selection unused warning
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn uncomment_0_margin_comments_with_no_space() {
|
||||
let mut doc = Rope::from("//");
|
||||
let mut selection = Selection::single(0, doc.len_chars() - 1);
|
||||
|
||||
let transaction = toggle_line_comments(&doc, &selection, None);
|
||||
transaction.apply(&mut doc);
|
||||
selection = selection.map(transaction.changes());
|
||||
assert_eq!(doc, "");
|
||||
assert!(selection.len() == 1); // to ignore the selection unused warning
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -413,4 +462,32 @@ fn test_find_block_comments() {
|
||||
transaction.apply(&mut doc);
|
||||
assert_eq!(doc, "");
|
||||
}
|
||||
|
||||
/// Test, if `get_comment_tokens` works, even if the content of the file includes chars, whose
|
||||
/// byte size unequal the amount of chars
|
||||
#[test]
|
||||
fn test_get_comment_with_char_boundaries() {
|
||||
let rope = Rope::from("··");
|
||||
let tokens = ["//", "///"];
|
||||
|
||||
assert_eq!(
|
||||
super::get_comment_token(rope.slice(..), tokens.as_slice(), 0),
|
||||
None
|
||||
);
|
||||
}
|
||||
|
||||
/// Test for `get_comment_token`.
|
||||
///
|
||||
/// Assuming the comment tokens are stored as `["///", "//"]`, `get_comment_token` should still
|
||||
/// return `///` instead of `//` if the user is in a doc-comment section.
|
||||
#[test]
|
||||
fn test_use_longest_comment() {
|
||||
let text = Rope::from(" /// amogus");
|
||||
let tokens = ["///", "//"];
|
||||
|
||||
assert_eq!(
|
||||
super::get_comment_token(text.slice(..), tokens.as_slice(), 0),
|
||||
Some("///")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -24,4 +24,4 @@ tokio = { version = "1", features = ["rt", "rt-multi-thread", "io-util", "io-std
|
||||
thiserror.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
fern = "0.6"
|
||||
fern = "0.7"
|
||||
|
@ -23,7 +23,7 @@ once_cell = "1.20"
|
||||
|
||||
anyhow = "1"
|
||||
log = "0.4"
|
||||
futures-executor = "0.3.28"
|
||||
futures-executor = "0.3.31"
|
||||
|
||||
[features]
|
||||
integration_test = []
|
||||
|
@ -23,7 +23,7 @@ license = "MIT"
|
||||
[dependencies]
|
||||
bitflags = "2.6.0"
|
||||
serde = { version = "1.0.209", features = ["derive"] }
|
||||
serde_json = "1.0.127"
|
||||
serde_json = "1.0.132"
|
||||
serde_repr = "0.1"
|
||||
url = {version = "2.0.0", features = ["serde"]}
|
||||
|
||||
|
@ -45,7 +45,7 @@ arc-swap = { version = "1.7.1" }
|
||||
termini = "1"
|
||||
|
||||
# Logging
|
||||
fern = "0.6"
|
||||
fern = "0.7"
|
||||
chrono = { version = "0.4", default-features = false, features = ["clock"] }
|
||||
log = "0.4"
|
||||
|
||||
@ -74,7 +74,7 @@ grep-searcher = "0.1.14"
|
||||
|
||||
[target.'cfg(not(windows))'.dependencies] # https://github.com/vorner/signal-hook/issues/100
|
||||
signal-hook-tokio = { version = "0.3", features = ["futures-v0_3"] }
|
||||
libc = "0.2.159"
|
||||
libc = "0.2.161"
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
crossterm = { version = "0.28", features = ["event-stream", "use-dev-tty", "libc"] }
|
||||
|
@ -22,8 +22,8 @@
|
||||
encoding, find_workspace,
|
||||
graphemes::{self, next_grapheme_boundary, RevRopeGraphemes},
|
||||
history::UndoKind,
|
||||
increment, indent,
|
||||
indent::IndentStyle,
|
||||
increment,
|
||||
indent::{self, IndentStyle},
|
||||
line_ending::{get_line_ending_of_str, line_end_char_index},
|
||||
match_brackets,
|
||||
movement::{self, move_vertically_visual, Direction},
|
||||
@ -3471,31 +3471,51 @@ fn open(cx: &mut Context, open: Open) {
|
||||
)
|
||||
};
|
||||
|
||||
let indent = indent::indent_for_newline(
|
||||
doc.language_config(),
|
||||
doc.syntax(),
|
||||
&doc.config.load().indent_heuristic,
|
||||
&doc.indent_style,
|
||||
doc.tab_width(),
|
||||
text,
|
||||
line_num,
|
||||
line_end_index,
|
||||
cursor_line,
|
||||
);
|
||||
let continue_comment_token = doc
|
||||
.language_config()
|
||||
.and_then(|config| config.comment_tokens.as_ref())
|
||||
.and_then(|tokens| comment::get_comment_token(text, tokens, cursor_line));
|
||||
|
||||
let line = text.line(cursor_line);
|
||||
let indent = match line.first_non_whitespace_char() {
|
||||
Some(pos) if continue_comment_token.is_some() => line.slice(..pos).to_string(),
|
||||
_ => indent::indent_for_newline(
|
||||
doc.language_config(),
|
||||
doc.syntax(),
|
||||
&doc.config.load().indent_heuristic,
|
||||
&doc.indent_style,
|
||||
doc.tab_width(),
|
||||
text,
|
||||
line_num,
|
||||
line_end_index,
|
||||
cursor_line,
|
||||
),
|
||||
};
|
||||
|
||||
let indent_len = indent.len();
|
||||
let mut text = String::with_capacity(1 + indent_len);
|
||||
text.push_str(doc.line_ending.as_str());
|
||||
text.push_str(&indent);
|
||||
|
||||
if let Some(token) = continue_comment_token {
|
||||
text.push_str(token);
|
||||
text.push(' ');
|
||||
}
|
||||
|
||||
let text = text.repeat(count);
|
||||
|
||||
// calculate new selection ranges
|
||||
let pos = offs + line_end_index + line_end_offset_width;
|
||||
let comment_len = continue_comment_token
|
||||
.map(|token| token.len() + 1) // `+ 1` for the extra space added
|
||||
.unwrap_or_default();
|
||||
for i in 0..count {
|
||||
// pos -> beginning of reference line,
|
||||
// + (i * (1+indent_len)) -> beginning of i'th line from pos
|
||||
// + indent_len -> -> indent for i'th line
|
||||
ranges.push(Range::point(pos + (i * (1 + indent_len)) + indent_len));
|
||||
// + (i * (1+indent_len + comment_len)) -> beginning of i'th line from pos (possibly including comment token)
|
||||
// + indent_len + comment_len -> -> indent for i'th line
|
||||
ranges.push(Range::point(
|
||||
pos + (i * (1 + indent_len + comment_len)) + indent_len + comment_len,
|
||||
));
|
||||
}
|
||||
|
||||
offs += text.chars().count();
|
||||
@ -3933,6 +3953,11 @@ pub fn insert_newline(cx: &mut Context) {
|
||||
|
||||
let mut new_text = String::new();
|
||||
|
||||
let continue_comment_token = doc
|
||||
.language_config()
|
||||
.and_then(|config| config.comment_tokens.as_ref())
|
||||
.and_then(|tokens| comment::get_comment_token(text, tokens, current_line));
|
||||
|
||||
// If the current line is all whitespace, insert a line ending at the beginning of
|
||||
// the current line. This makes the current line empty and the new line contain the
|
||||
// indentation of the old line.
|
||||
@ -3942,17 +3967,22 @@ pub fn insert_newline(cx: &mut Context) {
|
||||
|
||||
(line_start, line_start, new_text.chars().count())
|
||||
} else {
|
||||
let indent = indent::indent_for_newline(
|
||||
doc.language_config(),
|
||||
doc.syntax(),
|
||||
&doc.config.load().indent_heuristic,
|
||||
&doc.indent_style,
|
||||
doc.tab_width(),
|
||||
text,
|
||||
current_line,
|
||||
pos,
|
||||
current_line,
|
||||
);
|
||||
let line = text.line(current_line);
|
||||
|
||||
let indent = match line.first_non_whitespace_char() {
|
||||
Some(pos) if continue_comment_token.is_some() => line.slice(..pos).to_string(),
|
||||
_ => indent::indent_for_newline(
|
||||
doc.language_config(),
|
||||
doc.syntax(),
|
||||
&doc.config.load().indent_heuristic,
|
||||
&doc.indent_style,
|
||||
doc.tab_width(),
|
||||
text,
|
||||
current_line,
|
||||
pos,
|
||||
current_line,
|
||||
),
|
||||
};
|
||||
|
||||
// If we are between pairs (such as brackets), we want to
|
||||
// insert an additional line which is indented one level
|
||||
@ -3962,19 +3992,30 @@ pub fn insert_newline(cx: &mut Context) {
|
||||
.and_then(|pairs| pairs.get(prev))
|
||||
.map_or(false, |pair| pair.open == prev && pair.close == curr);
|
||||
|
||||
let local_offs = if on_auto_pair {
|
||||
let local_offs = if let Some(token) = continue_comment_token {
|
||||
new_text.push_str(doc.line_ending.as_str());
|
||||
new_text.push_str(&indent);
|
||||
new_text.push_str(token);
|
||||
new_text.push(' ');
|
||||
new_text.chars().count()
|
||||
} else if on_auto_pair {
|
||||
// line where the cursor will be
|
||||
let inner_indent = indent.clone() + doc.indent_style.as_str();
|
||||
new_text.reserve_exact(2 + indent.len() + inner_indent.len());
|
||||
new_text.push_str(doc.line_ending.as_str());
|
||||
new_text.push_str(&inner_indent);
|
||||
|
||||
// line where the matching pair will be
|
||||
let local_offs = new_text.chars().count();
|
||||
new_text.push_str(doc.line_ending.as_str());
|
||||
new_text.push_str(&indent);
|
||||
|
||||
local_offs
|
||||
} else {
|
||||
new_text.reserve_exact(1 + indent.len());
|
||||
new_text.push_str(doc.line_ending.as_str());
|
||||
new_text.push_str(&indent);
|
||||
|
||||
new_text.chars().count()
|
||||
};
|
||||
|
||||
|
@ -41,6 +41,7 @@ forth-lsp = { command = "forth-lsp" }
|
||||
fortls = { command = "fortls", args = ["--lowercase_intrinsics"] }
|
||||
fsharp-ls = { command = "fsautocomplete", config = { AutomaticWorkspaceInit = true } }
|
||||
gleam = { command = "gleam", args = ["lsp"] }
|
||||
glsl_analyzer = { command = "glsl_analyzer" }
|
||||
graphql-language-service = { command = "graphql-lsp", args = ["server", "-m", "stream"] }
|
||||
haskell-language-server = { command = "haskell-language-server-wrapper", args = ["--lsp"] }
|
||||
idris2-lsp = { command = "idris2-lsp" }
|
||||
@ -448,7 +449,6 @@ file-types = [
|
||||
{ glob = "composer.lock" },
|
||||
{ glob = ".watchmanconfig" },
|
||||
"avsc",
|
||||
{ glob = ".prettierrc" },
|
||||
"ldtk",
|
||||
"ldtkl",
|
||||
]
|
||||
@ -1243,6 +1243,23 @@ indent = { tab-width = 2, unit = " " }
|
||||
name = "ocaml-interface"
|
||||
source = { git = "https://github.com/tree-sitter/tree-sitter-ocaml", rev = "9965d208337d88bbf1a38ad0b0fe49e5f5ec9677", subpath = "interface" }
|
||||
|
||||
[[language]]
|
||||
name = "dune"
|
||||
scope = "source.dune"
|
||||
roots = ["dune-project"]
|
||||
file-types = [{ glob = "dune-project" }, { glob = "dune" }]
|
||||
comment-token = ";"
|
||||
indent = { tab-width = 1, unit = " " }
|
||||
grammar = "scheme"
|
||||
auto-format = true
|
||||
formatter = { command = "dune", args = ["format-dune-file"] }
|
||||
|
||||
[language.auto-pairs]
|
||||
'(' = ')'
|
||||
'{' = '}'
|
||||
'[' = ']'
|
||||
'"' = '"'
|
||||
|
||||
[[language]]
|
||||
name = "lua"
|
||||
injection-regex = "lua"
|
||||
@ -1288,7 +1305,7 @@ source = { git = "https://github.com/ikatyang/tree-sitter-vue", rev = "91fe27547
|
||||
[[language]]
|
||||
name = "yaml"
|
||||
scope = "source.yaml"
|
||||
file-types = ["yml", "yaml"]
|
||||
file-types = ["yml", "yaml", { glob = ".prettierrc" }]
|
||||
comment-token = "#"
|
||||
indent = { tab-width = 2, unit = " " }
|
||||
language-servers = [ "yaml-language-server", "ansible-language-server" ]
|
||||
@ -1435,6 +1452,7 @@ file-types = ["glsl", "vert", "tesc", "tese", "geom", "frag", "comp" ]
|
||||
comment-token = "//"
|
||||
block-comment-tokens = { start = "/*", end = "*/" }
|
||||
indent = { tab-width = 4, unit = " " }
|
||||
language-servers = [ "glsl_analyzer" ]
|
||||
injection-regex = "glsl"
|
||||
|
||||
[[grammar]]
|
||||
@ -2465,6 +2483,12 @@ injection-regex = "sml"
|
||||
file-types = ["sml"]
|
||||
block-comment-tokens = { start = "(*", end = "*)" }
|
||||
|
||||
[language.auto-pairs]
|
||||
'(' = ')'
|
||||
'{' = '}'
|
||||
'[' = ']'
|
||||
'"' = '"'
|
||||
|
||||
[[grammar]]
|
||||
name = "sml"
|
||||
source = { git = "https://github.com/Giorbo/tree-sitter-sml", rev = "bd4055d5554614520d4a0706b34dc0c317c6b608" }
|
||||
@ -3115,7 +3139,7 @@ indent = { tab-width = 4, unit = " " }
|
||||
|
||||
[[grammar]]
|
||||
name = "just"
|
||||
source = { git = "https://github.com/poliorcetics/tree-sitter-just", rev = "f58a8fd869035ac4653081401e6c2030251240ab" }
|
||||
source = { git = "https://github.com/poliorcetics/tree-sitter-just", rev = "6e28fa6cba511c694247cd802d1c3b14f8d34dbb" }
|
||||
|
||||
[[language]]
|
||||
name = "gn"
|
||||
@ -3247,7 +3271,7 @@ text-width = 72
|
||||
|
||||
[[grammar]]
|
||||
name = "jjdescription"
|
||||
source = { git = "https://github.com/kareigu/tree-sitter-jjdescription", rev = "2ddec6cad07b366aee276a608e1daa2c29d3caf2" }
|
||||
source = { git = "https://github.com/kareigu/tree-sitter-jjdescription", rev = "23dd3dd18ee29bdd761642511aa314215801afd8" }
|
||||
|
||||
[[language]]
|
||||
name = "jq"
|
||||
@ -3810,3 +3834,28 @@ language-servers = ["circom-lsp"]
|
||||
[[grammar]]
|
||||
name = "circom"
|
||||
source = { git = "https://github.com/Decurity/tree-sitter-circom", rev = "02150524228b1e6afef96949f2d6b7cc0aaf999e" }
|
||||
|
||||
[[language]]
|
||||
name = "snakemake"
|
||||
scope = "source.snakemake"
|
||||
roots = ["Snakefile", "config.yaml", "environment.yaml", "workflow/"]
|
||||
file-types = ["smk", "Snakefile"]
|
||||
comment-tokens = ["#", "##"]
|
||||
indent = { tab-width = 2, unit = " " }
|
||||
language-servers = ["pylsp" ]
|
||||
|
||||
[[grammar]]
|
||||
name = "snakemake"
|
||||
source = { git = "https://github.com/osthomas/tree-sitter-snakemake", rev = "e909815acdbe37e69440261ebb1091ed52e1dec6" }
|
||||
|
||||
[[language]]
|
||||
name = "cylc"
|
||||
scope = "source.cylc"
|
||||
injection-regex = "cylc"
|
||||
file-types = ["cylc", { glob = "suite.rc" }]
|
||||
comment-tokens = "#"
|
||||
indent = { tab-width = 4, unit = " " }
|
||||
|
||||
[[grammar]]
|
||||
name = "cylc"
|
||||
source = { git = "https://github.com/elliotfontaine/tree-sitter-cylc", rev = "30dd40d9bf23912e4aefa93eeb4c7090bda3d0f6" }
|
||||
|
100
runtime/queries/cylc/highlights.scm
Normal file
100
runtime/queries/cylc/highlights.scm
Normal file
@ -0,0 +1,100 @@
|
||||
(ERROR) @markup.bold
|
||||
|
||||
[
|
||||
(jinja2_expression)
|
||||
(jinja2_statement)
|
||||
(jinja2_comment)
|
||||
(jinja2_shebang)
|
||||
] @special
|
||||
|
||||
(include_statement
|
||||
directive: _ @keyword.directive
|
||||
path: _ @string.special.path)
|
||||
|
||||
(comment) @comment.line
|
||||
|
||||
(graph_section
|
||||
name: _? @label)
|
||||
|
||||
(task_section
|
||||
name: (_
|
||||
(task_name) @namespace))
|
||||
|
||||
(top_section
|
||||
brackets_open: _ @punctuation.bracket
|
||||
name: _? @label
|
||||
brackets_close: _ @punctuation.bracket)
|
||||
|
||||
(sub_section_1
|
||||
brackets_open: _ @punctuation.bracket
|
||||
name: _? @label
|
||||
brackets_close: _ @punctuation.bracket)
|
||||
|
||||
(sub_section_2
|
||||
brackets_open: _ @punctuation.bracket
|
||||
name: _? @label
|
||||
brackets_close: _ @punctuation.bracket)
|
||||
|
||||
(runtime_section
|
||||
brackets_open: _ @punctuation.bracket
|
||||
name: _? @label
|
||||
brackets_close: _ @punctuation.bracket)
|
||||
|
||||
(graph_setting
|
||||
key: (_) @constant.numeric.integer
|
||||
operator: (_)? @operator)
|
||||
|
||||
(quoted_graph_string
|
||||
quotes_open: _ @string
|
||||
quotes_close: _ @string)
|
||||
|
||||
(multiline_graph_string
|
||||
quotes_open: _ @string
|
||||
quotes_close: _ @string)
|
||||
|
||||
[
|
||||
(graph_logical)
|
||||
(graph_arrow)
|
||||
(graph_parenthesis)
|
||||
] @operator
|
||||
|
||||
(intercycle_annotation
|
||||
(recurrence) @constant.numeric.integer)
|
||||
|
||||
(graph_task
|
||||
xtrigger: _? @operator
|
||||
suicide: _? @operator
|
||||
name: _ @namespace)
|
||||
|
||||
(task_parameter
|
||||
"<" @tag
|
||||
name: (_)? @special
|
||||
","? @tag
|
||||
"="? @tag
|
||||
selection: (_)? @special
|
||||
">" @tag)
|
||||
|
||||
(intercycle_annotation
|
||||
"[" @tag
|
||||
(recurrence)? @constant.numeric.integer
|
||||
"]" @tag)
|
||||
|
||||
(task_output
|
||||
":" @tag
|
||||
(nametag) @variable.other)
|
||||
|
||||
(task_output
|
||||
"?"? @tag)
|
||||
|
||||
(setting
|
||||
key: (key) @variable
|
||||
operator: (_)? @operator
|
||||
value: [
|
||||
(unquoted_string) @string
|
||||
(quoted_string) @string
|
||||
(multiline_string) @string
|
||||
(boolean) @constant.builtin.boolean
|
||||
(integer) @constant.numeric.integer
|
||||
]?)
|
||||
|
||||
(datetime) @constant.numeric.float
|
19
runtime/queries/cylc/indents.scm
Normal file
19
runtime/queries/cylc/indents.scm
Normal file
@ -0,0 +1,19 @@
|
||||
[
|
||||
(top_section)
|
||||
(sub_section_1)
|
||||
(sub_section_2)
|
||||
(graph_section)
|
||||
(runtime_section)
|
||||
(task_section)
|
||||
] @indent
|
||||
|
||||
[
|
||||
(top_section)
|
||||
(sub_section_1)
|
||||
(sub_section_2)
|
||||
(graph_section)
|
||||
(runtime_section)
|
||||
(task_section)
|
||||
] @extend
|
||||
|
||||
(line_continuation) @indent.always
|
20
runtime/queries/cylc/injections.scm
Normal file
20
runtime/queries/cylc/injections.scm
Normal file
@ -0,0 +1,20 @@
|
||||
((setting
|
||||
key: (key) @key
|
||||
(#match? @key "^script$|-script$|^script-")
|
||||
value: (_
|
||||
(string_content) @injection.content))
|
||||
(#set! "injection.language" "bash"))
|
||||
|
||||
; Requires no spacing around "=" in environment settings for proper highlighting.
|
||||
; Could be improved if Tree-sitter allowed to specify the target node of the injected
|
||||
; language, instead of always using the root node.
|
||||
; See this proposal:
|
||||
; https://github.com/tree-sitter/tree-sitter/issues/3625
|
||||
((task_section
|
||||
(sub_section_2
|
||||
name: (_) @section_name
|
||||
(#eq? @section_name "environment")
|
||||
(setting) @injection.content))
|
||||
(#set! "injection.language" "bash")
|
||||
(#set! injection.combined)
|
||||
(#set! injection.include-children))
|
23
runtime/queries/cylc/textobjects.scm
Normal file
23
runtime/queries/cylc/textobjects.scm
Normal file
@ -0,0 +1,23 @@
|
||||
(comment) @comment.inside
|
||||
|
||||
(comment)+ @comment.around
|
||||
|
||||
(_
|
||||
brackets_open: _
|
||||
name: _?
|
||||
brackets_close: _
|
||||
_* @class.inside) @class.around
|
||||
|
||||
(setting
|
||||
value: _? @function.inside) @function.around
|
||||
|
||||
(graph_setting
|
||||
value: _? @function.inside) @function.around
|
||||
|
||||
(graph_string_content
|
||||
(graph_task) @entry.inside)
|
||||
|
||||
(task_parameter
|
||||
((_) @parameter.inside
|
||||
.
|
||||
","? @parameter.around) @parameter.around)
|
1
runtime/queries/dune/highlights.scm
Normal file
1
runtime/queries/dune/highlights.scm
Normal file
@ -0,0 +1 @@
|
||||
; inherits: scheme
|
20
runtime/queries/snakemake/LICENSE
Executable file
20
runtime/queries/snakemake/LICENSE
Executable file
@ -0,0 +1,20 @@
|
||||
Copyright (c) 2016 Max Brunsfeld
|
||||
Copyright (c) 2023 Oliver Thomas
|
||||
|
||||
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.
|
8
runtime/queries/snakemake/folds.scm
Executable file
8
runtime/queries/snakemake/folds.scm
Executable file
@ -0,0 +1,8 @@
|
||||
; inherits: python
|
||||
|
||||
[
|
||||
(rule_definition)
|
||||
(rule_inheritance)
|
||||
(module_definition)
|
||||
(checkpoint_definition)
|
||||
] @fold
|
76
runtime/queries/snakemake/highlights.scm
Executable file
76
runtime/queries/snakemake/highlights.scm
Executable file
@ -0,0 +1,76 @@
|
||||
; inherits: python
|
||||
|
||||
; Compound directives
|
||||
[
|
||||
"rule"
|
||||
"checkpoint"
|
||||
"module"
|
||||
] @keyword
|
||||
|
||||
; Top level directives (eg. configfile, include)
|
||||
(module
|
||||
(directive
|
||||
name: _ @keyword))
|
||||
|
||||
; Subordinate directives (eg. input, output)
|
||||
((_)
|
||||
body: (_
|
||||
(directive
|
||||
name: _ @label)))
|
||||
|
||||
; rule/module/checkpoint names
|
||||
(rule_definition
|
||||
name: (identifier) @type)
|
||||
|
||||
(module_definition
|
||||
name: (identifier) @type)
|
||||
|
||||
(checkpoint_definition
|
||||
name: (identifier) @type)
|
||||
|
||||
; Rule imports
|
||||
(rule_import
|
||||
"use" @keyword.import
|
||||
"rule" @keyword.import
|
||||
"from" @keyword.import
|
||||
"exclude"? @keyword.import
|
||||
"as"? @keyword.import
|
||||
"with"? @keyword.import)
|
||||
|
||||
; Rule inheritance
|
||||
(rule_inheritance
|
||||
"use" @keyword
|
||||
"rule" @keyword
|
||||
"with" @keyword)
|
||||
|
||||
; Wildcard names
|
||||
(wildcard (identifier) @variable)
|
||||
(wildcard (flag) @variable.parameter.builtin)
|
||||
|
||||
; builtin variables
|
||||
((identifier) @variable.builtin
|
||||
(#any-of? @variable.builtin "checkpoints" "config" "gather" "rules" "scatter" "workflow"))
|
||||
|
||||
; References to directive labels in wildcard interpolations
|
||||
; the #any-of? queries are moved above the #has-ancestor? queries to
|
||||
; short-circuit the potentially expensive tree traversal, if possible
|
||||
; see:
|
||||
; https://github.com/nvim-treesitter/nvim-treesitter/pull/4302#issuecomment-1685789790
|
||||
; directive labels in wildcard context
|
||||
((wildcard
|
||||
(identifier) @label)
|
||||
(#any-of? @label "input" "log" "output" "params" "resources" "threads" "wildcards"))
|
||||
|
||||
((wildcard
|
||||
(attribute
|
||||
object: (identifier) @label))
|
||||
(#any-of? @label "input" "log" "output" "params" "resources" "threads" "wildcards"))
|
||||
|
||||
((wildcard
|
||||
(subscript
|
||||
value: (identifier) @label))
|
||||
(#any-of? @label "input" "log" "output" "params" "resources" "threads" "wildcards"))
|
||||
|
||||
; directive labels in block context (eg. within 'run:')
|
||||
((identifier) @label
|
||||
(#any-of? @label "input" "log" "output" "params" "resources" "threads" "wildcards"))
|
27
runtime/queries/snakemake/indents.scm
Executable file
27
runtime/queries/snakemake/indents.scm
Executable file
@ -0,0 +1,27 @@
|
||||
; inherits: python
|
||||
|
||||
|
||||
[
|
||||
(rule_definition)
|
||||
(checkpoint_definition)
|
||||
(rule_inheritance)
|
||||
(module_definition)
|
||||
] @indent
|
||||
|
||||
[
|
||||
(rule_definition)
|
||||
(checkpoint_definition)
|
||||
(rule_inheritance)
|
||||
(module_definition)
|
||||
] @extend
|
||||
|
||||
|
||||
(directive) @indent
|
||||
(directive) @extend
|
||||
|
||||
(rule_import
|
||||
"with"
|
||||
":") @indent
|
||||
(rule_import
|
||||
"with"
|
||||
":") @extend
|
5
runtime/queries/snakemake/injections.scm
Executable file
5
runtime/queries/snakemake/injections.scm
Executable file
@ -0,0 +1,5 @@
|
||||
; inherits: python
|
||||
|
||||
(wildcard
|
||||
(constraint) @injection.content
|
||||
(#set! injection.language "regex"))
|
1
runtime/queries/snakemake/locals.scm
Executable file
1
runtime/queries/snakemake/locals.scm
Executable file
@ -0,0 +1 @@
|
||||
; inherits: python
|
Loading…
Reference in New Issue
Block a user