Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ path = "src/yls.rs"
crate-type = ["cdylib"]

[dependencies]
zed_extension_api = "0.3.0"
zed_extension_api = "0.7.0"
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,12 @@ Yara language extension for Zed.
Example (using the `Ayu Mirage` theme):
![Yara syntax highlighting in Zed](example.png)

Before installing this extension, install the [Yara Language
Server](https://avast.github.io/yls/) and ensure that it is on your PATH.
Before installing this extension, install a YARA Language Server and ensure that it is on your PATH.

This extension supports:
1. **Official YARA-X LSP (Recommended):** Install `yara-x-ls` from the [VirusTotal/yara-x](https://github.com/VirusTotal/yara-x) repository:
```bash
cargo install --git https://github.com/VirusTotal/yara-x yara-x-ls --locked
```
This installs the `yr-ls` binary.
2. **YLS (Legacy):** Install the [Yara Language Server](https://avast.github.io/yls/) (`yls` binary).
8 changes: 4 additions & 4 deletions extension.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ description = "Yara syntax highlighting for Zed."
repository = "https://github.com/egibs/yara.zed"

[grammars.yara]
repository = "https://github.com/egibs/tree-sitter-yara.git"
commit = "eb3ede203275c38000177f72ec0f9965312806ef"
repository = "https://github.com/celstur/tree-sitter-yara.git"
commit = "b49d980b2e111e0b09a6a8bae18b3fa2b6cf4797"

[language_servers.yls]
name = "yls"
[language_servers.yr-ls]
name = "yr-ls"
languages = ["Yara"]
5 changes: 5 additions & 0 deletions languages/yara/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@ name = "Yara"
grammar = "yara"
path_suffixes = ["yar", "yara"]
line_comments = ["//"]
block_comment = ["/*", "*/"]
brackets = [
{ start = "{", end = "}", close = true, newline = true },
{ start = "[", end = "]", close = true, newline = true },
{ start = "(", end = ")", close = true, newline = true },
{ start = "\"", end = "\"", close = true, newline = false, not_in = [
"string",
] },
{ start = "'", end = "'", close = true, newline = false, not_in = [
"string",
] },
]
5 changes: 5 additions & 0 deletions languages/yara/folds.scm
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
(rule_definition) @fold
(meta_section) @fold
(strings_section) @fold
(condition_section) @fold
(comment) @fold
181 changes: 95 additions & 86 deletions languages/yara/highlights.scm
Original file line number Diff line number Diff line change
@@ -1,137 +1,146 @@
; Comments
(comment) @comment

; Keywords
; Preprocessor / Top-level Keywords
[
"global"
"import"
"private"
] @constant.builtin
"include"
] @keyword.control

[
"rule"
] @function
"private"
"global"
] @keyword.modifier

"rule" @keyword

; Sections (Emacs warning face)
[
"meta"
"strings"
"condition"
] @property
] @keyword.control

; Operators
[
"matches"
"contains"
"icontains"
"imatches"
"startswith"
"istartswith"
"endswith"
"iendswith"
"and"
"or"
"not"
"=="
"!="
"<"
">"
">="
"<="
"of"
"for"
"all"
"any"
"none"
"in"
] @string.special
; Rule details
(rule_definition
name: (identifier) @function)

; String modifiers
[
"wide"
"ascii"
"nocase"
"fullword"
"xor"
"base64"
"base64wide"
] @keyword.modifier
(tag) @tag

; Numbers and sizes
(integer_literal) @constant.numeric
(size_unit) @constant.numeric
; Meta definition keys
(meta_definition
key: (identifier) @property)

; Strings
; Variables and String Identifiers
(string_identifier) @variable

; Literals
(integer_decimal_positive) @constant.numeric
(integer_zero) @constant.numeric
(integer_hexadecimal) @constant.numeric
(size_unit) @constant.numeric
(double_quoted_string) @string
(single_quoted_string) @string
(escape_sequence) @string.escape
(text_string) @text.literal
(text_string) @string

; Hex strings
[
"true"
"false"
] @constant.boolean

; Hex Strings
(hex_string) @string.special
(hex_seq) @string.special
(hex_byte) @constant.numeric
(hex_wildcard) @constant.builtin
(hex_jump) @constant.numeric

; Regular expressions
(regex_string) @string.regexp
(pattern) @string.regexp
(regular_expression) @string.regexp

; Boolean literals
; Control structures and keywords
[
"true"
"false"
] @constant.boolean
"for"
"in"
"of"
] @keyword.control

; Keywords and special identifiers
[
"them"
"all"
"any"
"none"
] @keyword.operator

"them"
] @keyword.control

; String identifiers
"$" @string.special.symbol
(identifier) @string
(string_identifier) @string.special.symbol
; String modifiers
[
"wide"
"ascii"
"nocase"
"fullword"
"xor"
"base64"
"base64wide"
] @keyword.modifier

; Built-ins
[
(filesize_keyword)
(entrypoint_keyword)
] @constant.builtin

; Tags
(tag_list
[(identifier) (tag)] @tag)
; Modules and Functions (e.g. pe.import_rva)
(module_identifier) @type
(module_var_or_func name: (identifier) @function)

; Built-in functions & types matching Emacs
((identifier) @function.builtin
(#match? @function.builtin "^(int(8|16|32)(be)?|uint(8|16|32)(be)?|math\\.[a-z_]+)$"))

; General identifiers (fallback)
(identifier) @variable

; Operators
[
"and"
"or"
"not"
"defined"
"matches"
"contains"
"icontains"
"startswith"
"istartswith"
"endswith"
"iendswith"
"iequals"
] @keyword.operator

; Punctuation and delimiters
[
"="
"=="
"!="
"<"
">"
">="
"<="
"+"
"-"
"*"
"\\"
"%"
".."
"|"
] @operator

; Punctuation & Delimiters
[
":"
"{"
"}"
"["
"]"
"("
")"
"#"
"@"
".."
"|"
","
"!"
"/"
"\""
"'"
"*"
] @string.special.symbol

; Rule names
(rule_definition
name: (identifier) @string.special)

; Meta definitions
(meta_definition
key: (identifier) @string.special)
] @punctuation.delimiter
4 changes: 4 additions & 0 deletions languages/yara/indents.scm
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
(rule_body) @indent
(meta_section) @indent
(strings_section) @indent
(condition_section) @indent
16 changes: 16 additions & 0 deletions languages/yara/outline.scm
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
(rule_definition
name: (identifier) @name) @item

(meta_section
"meta" @name) @item

(meta_definition
key: (identifier) @name) @item

(strings_section
"strings" @name) @item

(string_identifier) @name @item

(condition_section
"condition" @name) @item
26 changes: 19 additions & 7 deletions src/yls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,26 @@ impl Extension for YaraExtension {
_language_server_id: &zed_extension_api::LanguageServerId,
_worktree: &zed_extension_api::Worktree,
) -> zed_extension_api::Result<zed_extension_api::Command> {
match _worktree.which("yls") {
Some(path) => Ok(zed_extension_api::process::Command {
command: path,
args: vec!["-v".into()],
env: vec![],
}),
None => Err("Unable to find yls from worktree.".into()),
let server_name = _language_server_id.as_ref();
if server_name == "yr-ls" {
if let Some(path) = _worktree.which("yr-ls") {
return Ok(zed_extension_api::process::Command {
command: path,
args: vec![],
env: vec![],
});
}
if let Some(path) = _worktree.which("yls") {
return Ok(zed_extension_api::process::Command {
command: path,
args: vec!["-v".into()],
env: vec![],
});
}
return Err("Unable to find yr-ls or yls from worktree.".into());
}

Err(format!("Unknown language server: {}", server_name).into())
}
}

Expand Down