Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Kalle Carlbark 2025-01-03 16:57:23 +01:00
commit 1904e7e669
No known key found for this signature in database
26 changed files with 152 additions and 129 deletions

12
Cargo.lock generated
View file

@ -136,9 +136,9 @@ checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53"
[[package]]
name = "cc"
version = "1.2.5"
version = "1.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c31a0499c1dc64f458ad13872de75c0eb7e3fdb0e67964610c914b034fc5956e"
checksum = "8d6dbb628b8f8555f86d0323c2eb39e3ec81901f4b83e091db8a6a76d316a333"
dependencies = [
"shlex",
]
@ -2249,18 +2249,18 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "serde"
version = "1.0.216"
version = "1.0.217"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e"
checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.216"
version = "1.0.217"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e"
checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
dependencies = [
"proc-macro2",
"quote",

View file

@ -34,7 +34,7 @@ below.
2. Create a new directory for the language with the path
`runtime/queries/<name>/`.
3. Refer to the
[tree-sitter website](https://tree-sitter.github.io/tree-sitter/syntax-highlighting#queries)
[tree-sitter website](https://tree-sitter.github.io/tree-sitter/3-syntax-highlighting.html#highlights)
for more information on writing queries.
4. A list of highlight captures can be found [on the themes page](https://docs.helix-editor.com/themes.html#scopes).

View file

@ -57,4 +57,4 @@ second argument (a string).
- `#any-of?` (standard):
The first argument (a capture) must be one of the other arguments (strings).
[upstream-docs]: http://tree-sitter.github.io/tree-sitter/syntax-highlighting#language-injection
[upstream-docs]: https://tree-sitter.github.io/tree-sitter/3-syntax-highlighting.html#language-injection

View file

@ -44,6 +44,6 @@ in its `textobjects.scm` file, function navigation should also work automaticall
`function.movement` should be defined only if the node captured by `function.around`
doesn't make sense in a navigation context.
[tree-sitter-queries]: https://tree-sitter.github.io/tree-sitter/using-parsers#query-syntax
[tree-sitter-captures]: https://tree-sitter.github.io/tree-sitter/using-parsers#capturing-nodes
[tree-sitter-queries]: https://tree-sitter.github.io/tree-sitter/using-parsers/queries/1-syntax.html
[tree-sitter-captures]: https://tree-sitter.github.io/tree-sitter/using-parsers/queries/2-operators.html#capturing-nodes
[textobject-examples]: https://github.com/search?q=repo%3Ahelix-editor%2Fhelix+path%3A%2A%2A/textobjects.scm&type=Code&ref=advsearch&l=&l=

View file

@ -241,4 +241,4 @@ use-grammars = { except = [ "yaml", "json" ] }
When omitted, all grammars are fetched and built.
[treesitter-language-injection]: https://tree-sitter.github.io/tree-sitter/syntax-highlighting#language-injection
[treesitter-language-injection]: https://tree-sitter.github.io/tree-sitter/3-syntax-highlighting.html#language-injection

View file

@ -136,7 +136,7 @@ The following is a list of scopes available to use for styling:
#### Syntax highlighting
These keys match [tree-sitter scopes](https://tree-sitter.github.io/tree-sitter/syntax-highlighting#theme).
These keys match [tree-sitter scopes](https://tree-sitter.github.io/tree-sitter/3-syntax-highlighting.html#highlights).
When determining styling for a highlight, the longest matching theme key will be used. For example, if the highlight is `function.builtin.static`, the key `function.builtin` will be used instead of `function`.

View file

@ -25,7 +25,7 @@ Inspired by [Kakoune](http://kakoune.org/), Helix follows the `selection → act
## Multiple selections
Also inspired by Kakoune, multiple selections are a core mode of interaction in Helix. For example, the standard way of replacing multiple instance of a word is to first select all instances (so there is one selection per instance) and then use the change action (`c`) to edit them all at the same time.
Also inspired by Kakoune, multiple selections are a core mode of interaction in Helix. For example, the standard way of replacing multiple instances of a word is to first select all instances (so there is one selection per instance) and then use the change action (`c`) to edit them all at the same time.
## Motions

View file

@ -2670,12 +2670,20 @@ fn node_is_visible(node: &Node) -> bool {
node.is_missing() || (node.is_named() && node.language().node_kind_is_visible(node.kind_id()))
}
fn format_anonymous_node_kind(kind: &str) -> Cow<str> {
if kind.contains('"') {
Cow::Owned(kind.replace('"', "\\\""))
} else {
Cow::Borrowed(kind)
}
}
pub fn pretty_print_tree<W: fmt::Write>(fmt: &mut W, node: Node) -> fmt::Result {
if node.child_count() == 0 {
if node_is_visible(&node) {
write!(fmt, "({})", node.kind())
} else {
write!(fmt, "\"{}\"", node.kind())
write!(fmt, "\"{}\"", format_anonymous_node_kind(node.kind()))
}
} else {
pretty_print_tree_impl(fmt, &mut node.walk(), 0)
@ -2700,7 +2708,7 @@ fn pretty_print_tree_impl<W: fmt::Write>(
write!(fmt, "({}", node.kind())?;
} else {
write!(fmt, " \"{}\"", node.kind())?;
write!(fmt, " \"{}\"", format_anonymous_node_kind(node.kind()))?;
}
// Handle children.
@ -2977,8 +2985,8 @@ mod test {
" (macro_invocation\n",
" macro: (identifier) \"!\"\n",
" (token_tree \"(\"\n",
" (string_literal \"\"\"\n",
" (string_content) \"\"\") \")\")) \";\") \"}\"))",
" (string_literal \"\\\"\"\n",
" (string_content) \"\\\"\") \")\")) \";\") \"}\"))",
),
0,
source.len(),

View file

@ -22,7 +22,7 @@ license = "MIT"
[dependencies]
bitflags = "2.6.0"
serde = { version = "1.0.216", features = ["derive"] }
serde = { version = "1.0.217", features = ["derive"] }
serde_json = "1.0.134"
serde_repr = "0.1"
url = {version = "2.5.4", features = ["serde"]}

View file

@ -104,10 +104,37 @@ impl std::error::Error for Error {}
#[serde(untagged)]
pub enum Id {
Null,
Num(u64),
Num(#[serde(deserialize_with = "deserialize_jsonrpc_id_num")] u64),
Str(String),
}
fn deserialize_jsonrpc_id_num<'de, D>(deserializer: D) -> Result<u64, D::Error>
where
D: serde::Deserializer<'de>,
{
let num = serde_json::Number::deserialize(deserializer)?;
if let Some(val) = num.as_u64() {
return Ok(val);
};
// Accept floats as long as they represent positive whole numbers.
// The JSONRPC spec says "Numbers SHOULD NOT contain fractional parts" so we should try to
// accept them if possible. The JavaScript type system lumps integers and floats together so
// some languages may serialize integer IDs as floats with a zeroed fractional part.
// See <https://github.com/helix-editor/helix/issues/12367>.
if let Some(val) = num
.as_f64()
.filter(|f| f.is_sign_positive() && f.fract() == 0.0)
{
return Ok(val as u64);
}
Err(de::Error::custom(
"number must be integer or float representing a whole number in valid u64 range",
))
}
impl std::fmt::Display for Id {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
@ -375,6 +402,22 @@ fn serialize_skip_none_params() {
assert_eq!(serialized, r#"{"jsonrpc":"2.0","method":"exit"}"#);
}
#[test]
fn id_deserialize() {
use serde_json;
let id = r#"8"#;
let deserialized: Id = serde_json::from_str(id).unwrap();
assert_eq!(deserialized, Id::Num(8));
let id = r#"4.0"#;
let deserialized: Id = serde_json::from_str(id).unwrap();
assert_eq!(deserialized, Id::Num(4));
let id = r#"0.01"#;
assert!(serde_json::from_str::<Id>(id).is_err());
}
#[test]
fn success_output_deserialize() {
use serde_json;

View file

@ -518,15 +518,16 @@ pub fn dap_variables(cx: &mut Context) {
Some(thread_frame) => thread_frame,
None => {
cx.editor
.set_error("Failed to get stack frame for thread: {thread_id}");
.set_error(format!("Failed to get stack frame for thread: {thread_id}"));
return;
}
};
let stack_frame = match thread_frame.get(frame) {
Some(stack_frame) => stack_frame,
None => {
cx.editor
.set_error("Failed to get stack frame for thread {thread_id} and frame {frame}.");
cx.editor.set_error(format!(
"Failed to get stack frame for thread {thread_id} and frame {frame}."
));
return;
}
};

View file

@ -1,6 +1,6 @@
use crate::config::{Config, ConfigLoadError};
use crossterm::{
style::{Color, Print, Stylize},
style::{Color, StyledContent, Stylize},
tty::IsTty,
};
use helix_core::config::{default_lang_config, user_lang_config};
@ -164,25 +164,20 @@ pub fn languages_all() -> std::io::Result<()> {
let column_width = terminal_cols as usize / headings.len();
let is_terminal = std::io::stdout().is_tty();
let column = |item: &str, color: Color| {
let mut data = format!(
"{:width$}",
item.get(..column_width - 2)
let fit = |s: &str| -> StyledContent<String> {
format!(
"{:column_width$}",
s.get(..column_width - 2)
.map(|s| format!("{}", s))
.unwrap_or_else(|| item.to_string()),
width = column_width,
);
if is_terminal {
data = data.stylize().with(color).to_string();
}
// We can't directly use println!() because of
// https://github.com/crossterm-rs/crossterm/issues/589
let _ = crossterm::execute!(std::io::stdout(), Print(data));
.unwrap_or_else(|| s.to_string())
)
.stylize()
};
let color = |s: StyledContent<String>, c: Color| if is_terminal { s.with(c) } else { s };
let bold = |s: StyledContent<String>| if is_terminal { s.bold() } else { s };
for heading in headings {
column(heading, Color::White);
write!(stdout, "{}", bold(fit(heading)))?;
}
writeln!(stdout)?;
@ -192,14 +187,14 @@ pub fn languages_all() -> std::io::Result<()> {
let check_binary = |cmd: Option<&str>| match cmd {
Some(cmd) => match helix_stdx::env::which(cmd) {
Ok(_) => column(&format!("{}", cmd), Color::Green),
Err(_) => column(&format!("{}", cmd), Color::Red),
Ok(_) => color(fit(&format!("{}", cmd)), Color::Green),
Err(_) => color(fit(&format!("{}", cmd)), Color::Red),
},
None => column("None", Color::Yellow),
None => color(fit("None"), Color::Yellow),
};
for lang in &syn_loader_conf.language {
column(&lang.language_id, Color::Reset);
write!(stdout, "{}", fit(&lang.language_id))?;
let mut cmds = lang.language_servers.iter().filter_map(|ls| {
syn_loader_conf
@ -207,28 +202,28 @@ pub fn languages_all() -> std::io::Result<()> {
.get(&ls.name)
.map(|config| config.command.as_str())
});
check_binary(cmds.next());
write!(stdout, "{}", check_binary(cmds.next()))?;
let dap = lang.debugger.as_ref().map(|dap| dap.command.as_str());
check_binary(dap);
write!(stdout, "{}", check_binary(dap))?;
let formatter = lang
.formatter
.as_ref()
.map(|formatter| formatter.command.as_str());
check_binary(formatter);
write!(stdout, "{}", check_binary(formatter))?;
for ts_feat in TsFeature::all() {
match load_runtime_file(&lang.language_id, ts_feat.runtime_filename()).is_ok() {
true => column("", Color::Green),
false => column("", Color::Red),
true => write!(stdout, "{}", color(fit(""), Color::Green))?,
false => write!(stdout, "{}", color(fit(""), Color::Red))?,
}
}
writeln!(stdout)?;
for cmd in cmds {
column("", Color::Reset);
write!(stdout, "{}", fit(""))?;
check_binary(Some(cmd));
writeln!(stdout)?;
}

View file

@ -59,12 +59,6 @@ pub enum InsertEvent {
RequestCompletion,
}
impl Default for EditorView {
fn default() -> Self {
Self::new(Keymaps::default())
}
}
impl EditorView {
pub fn new(keymaps: Keymaps) -> Self {
Self {

View file

@ -340,16 +340,17 @@ source = { git = "https://github.com/Beaglefoot/tree-sitter-awk", rev = "a799bc5
[[language]]
name = "protobuf"
scope = "source.proto"
injection-regex = "protobuf"
injection-regex = "proto"
file-types = ["proto"]
language-servers = [ "bufls", "pbkit" ]
comment-token = "//"
block-comment-tokens = { start = "/*", end = "*/" }
indent = { tab-width = 2, unit = " " }
grammar = "proto"
[[grammar]]
name = "protobuf"
source = { git = "https://github.com/yusdacra/tree-sitter-protobuf", rev = "19c211a01434d9f03efff99f85e19f967591b175"}
name = "proto"
source = { git = "https://github.com/sdoerner/tree-sitter-proto", rev = "778ab6ed18a7fcf82c83805a87d63376c51e80bc"}
[[language]]
name = "textproto"
@ -882,7 +883,7 @@ name = "python"
scope = "source.python"
injection-regex = "py(thon)?"
file-types = ["py", "pyi", "py3", "pyw", "ptl", "rpy", "cpy", "ipy", "pyt", { glob = ".python_history" }, { glob = ".pythonstartup" }, { glob = ".pythonrc" }, { glob = "SConstruct" }, { glob = "SConscript" }]
shebangs = ["python"]
shebangs = ["python", "uv"]
roots = ["pyproject.toml", "setup.py", "poetry.lock", "pyrightconfig.json"]
comment-token = "#"
language-servers = ["ruff", "jedi", "pylsp"]
@ -3303,6 +3304,7 @@ injection-regex = "nunjucks"
file-types = ["njk"]
indent = { tab-width = 2, unit = " " }
grammar = "jinja2"
block-comment-tokens = { start = "{#", end = "#}" }
[[language]]
name = "jinja"
@ -3311,6 +3313,7 @@ injection-regex = "jinja"
file-types = ["jinja", "jinja2", "j2"]
indent = { tab-width = 2, unit = " " }
grammar = "jinja2"
block-comment-tokens = { start = "{#", end = "#}" }
[[grammar]]
name = "jinja2"
@ -3607,7 +3610,7 @@ source = { git = "https://github.com/mtoohey31/tree-sitter-ld", rev = "0e9695ae0
name = "hyprlang"
scope = "source.hyprlang"
roots = ["hyprland.conf"]
file-types = [ { glob = "hyprland.conf" }, { glob = "hyprpaper.conf" }, { glob = "hypridle.conf" }, { glob = "hyprlock.conf" } ]
file-types = [ { glob = "hypr/*.conf" }]
comment-token = "#"
grammar = "hyprlang"
language-servers = ["hyprls"]
@ -4011,7 +4014,7 @@ indent = { tab-width = 4, unit = " " }
[[grammar]]
name = "vento"
source = { git = "https://github.com/ventojs/tree-sitter-vento", rev = "3321077d7446c1b3b017c294fd56ce028ed817fe" }
source = { git = "https://github.com/ventojs/tree-sitter-vento", rev = "3b32474bc29584ea214e4e84b47102408263fe0e" }
[[language]]
name = "nginx"

View file

@ -1,9 +1,3 @@
;; highlight queries.
;; See the syntax at https://tree-sitter.github.io/tree-sitter/using-parsers#pattern-matching-with-queries
;; See also https://github.com/nvim-treesitter/nvim-treesitter/blob/master/CONTRIBUTING.md#parser-configurations
;; for a list of recommended @ tags, though not all of them have matching
;; highlights in neovim.
[
"abort"
"abs"

View file

@ -1,6 +1,3 @@
;; Better highlighting by referencing to the definition, for variable references.
;; See https://tree-sitter.github.io/tree-sitter/syntax-highlighting#local-variables
(compilation) @local.scope
(package_declaration) @local.scope
(package_body) @local.scope

View file

@ -1,7 +1,5 @@
; tree-sitter-awk v0.5.1
; https://tree-sitter.github.io/tree-sitter/using-parsers#pattern-matching-with-queries
; Order matters
[

View file

@ -1,5 +1,6 @@
[
"syntax"
"edition"
"package"
"option"
"import"
@ -7,44 +8,45 @@
"rpc"
"returns"
"message"
"map"
"enum"
"oneof"
"repeated"
"optional"
"required"
"reserved"
"to"
"stream"
"extend"
"optional"
] @keyword
[
(keyType)
(key_type)
(type)
(message_or_enum_type)
] @type.builtin
[
(mapName)
(enumName)
(messageName)
(extendName)
(serviceName)
(rpcName)
(enum_name)
(message_name)
(service_name)
(rpc_name)
] @type
[
(fieldName)
(optionName)
(field_name)
(option_name)
] @variable.other.member
(enumVariantName) @type.enum.variant
(enum_variant_name) @type.enum.variant
(fullIdent) @namespace
(full_ident) @namespace
(intLit) @constant.numeric.integer
(floatLit) @constant.numeric.float
(boolLit) @constant.builtin.boolean
(strLit) @string
(int_lit) @constant.numeric.integer
(float_lit) @constant.numeric.float
(bool) @constant.builtin.boolean
(string) @string
(constant) @constant
(block_lit) @constant
(comment) @comment
@ -55,12 +57,8 @@
"]"
"{"
"}"
] @punctuation.bracket
] @punctuation.bracket
[
"="
] @operator
"=" @operator
[
";"
] @punctuation.delimiter
";" @punctuation.delimiter

View file

@ -1,10 +1,10 @@
[
(messageBody)
(enumBody)
(oneofBody)
(serviceBody)
(rpcBody)
(msgLit)
(message_body)
(enum_body)
(oneof_body)
(service_body)
(rpc_body)
(block_lit)
] @indent
"}" @outdent

View file

@ -1,9 +1,9 @@
(message (messageBody) @class.inside) @class.around
(enum (enumBody) @class.inside) @class.around
(service (serviceBody) @class.inside) @class.around
(message (message_body) @class.inside) @class.around
(enum (enum_body) @class.inside) @class.around
(service (service_body) @class.inside) @class.around
(rpc (enumMessageType) @parameter.inside) @function.inside
(rpc (enumMessageType) @parameter.around) @function.around
(rpc (message_or_enum_type) @parameter.inside) @function.inside
(rpc (message_or_enum_type) @parameter.around) @function.around
(comment) @comment.inside
(comment)+ @comment.around

View file

@ -1,5 +1,3 @@
; See: https://tree-sitter.github.io/tree-sitter/syntax-highlighting#local-variables
; Scopes @local.scope
; -------------------------

View file

@ -11,11 +11,6 @@
"_" @constant
[
"@"
"#"
] @punctuation.special
":" @punctuation.delimiter
[
@ -27,8 +22,6 @@
"." @operator
(predicate_type) @punctuation.special
(quantifier) @operator
(comment) @comment
@ -41,16 +34,16 @@
name: (identifier) @variable.other.member)
(named_node
name: (identifier) @variable)
name: (identifier) @tag)
(predicate
name: (identifier) @function)
((predicate
"#" @function.builtin
name: (identifier) @function.builtin @_name
type: (predicate_type) @function.builtin)
(#any-of? @_name "eq" "match" "any-of" "not-any-of" "is" "is-not" "not-same-line" "not-kind-eq" "set" "select-adjacent" "strip"))
(predicate name: (identifier) @error)
(anonymous_node
(string) @string)
(capture
(identifier) @type)
(capture) @label
(escape_sequence) @constant.character.escape

View file

@ -5,6 +5,6 @@
name: (identifier) @_name
parameters:
(parameters
(string) @injection.content))
(string (string_content) @injection.content)))
(#any-of? @_name "match" "not-match")
(#set! injection.language "regex"))

View file

@ -115,6 +115,7 @@
"ui.menu" = { fg = "overlay2", bg = "surface0" }
"ui.menu.selected" = { fg = "text", bg = "surface1", modifiers = ["bold"] }
"diagnostic.unnecessary" = { modifiers = ["dim"] }
"diagnostic.error" = { underline = { color = "red", style = "curl" } }
"diagnostic.warning" = { underline = { color = "yellow", style = "curl" } }
"diagnostic.info" = { underline = { color = "sky", style = "curl" } }

View file

@ -109,9 +109,10 @@ special = "sky"
"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.text.directory" = "sky"
"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" }

View file

@ -5,7 +5,6 @@ use crate::DynError;
use helix_term::commands::MappableCommand;
use helix_term::commands::TYPABLE_COMMAND_LIST;
use helix_term::health::TsFeature;
use helix_term::ui::EditorView;
use helix_view::document::Mode;
use std::collections::HashSet;
@ -56,7 +55,7 @@ pub fn typable_commands() -> Result<String, DynError> {
pub fn static_commands() -> Result<String, DynError> {
let mut md = String::new();
let keymap = EditorView::default().keymaps.map();
let keymap = helix_term::keymap::default();
let keymaps = [
("normal", keymap[&Mode::Normal].reverse_map()),
("select", keymap[&Mode::Select].reverse_map()),