Merge branch 'helix-editor:master' into master

pull/10391/head
Vadim 7 months ago committed by GitHub
commit b792676400
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

69
Cargo.lock generated

@ -538,9 +538,9 @@ checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e"
[[package]] [[package]]
name = "gix" name = "gix"
version = "0.61.0" version = "0.62.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4e0e59a44bf00de058ee98d6ecf3c9ed8f8842c1da642258ae4120d41ded8f7" checksum = "5631c64fb4cd48eee767bf98a3cbc5c9318ef3bb71074d4c099a2371510282b6"
dependencies = [ dependencies = [
"gix-actor", "gix-actor",
"gix-attributes", "gix-attributes",
@ -663,9 +663,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-config" name = "gix-config"
version = "0.36.0" version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62129c75e4b6229fe15fb9838cdc00c655e87105b651e4edd7c183fc5288b5d1" checksum = "7580e05996e893347ad04e1eaceb92e1c0e6a3ffe517171af99bf6b6df0ca6e5"
dependencies = [ dependencies = [
"bstr", "bstr",
"gix-config-value", "gix-config-value",
@ -709,9 +709,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-diff" name = "gix-diff"
version = "0.42.0" version = "0.43.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78e605593c2ef74980a534ade0909c7dc57cca72baa30cbb67d2dda621f99ac4" checksum = "a5fbc24115b957346cd23fb0f47d830eb799c46c89cdcf2f5acc9bf2938c2d01"
dependencies = [ dependencies = [
"bstr", "bstr",
"gix-command", "gix-command",
@ -729,9 +729,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-dir" name = "gix-dir"
version = "0.3.0" version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3413ccd29130900c17574678aee640e4847909acae9febf6424dc77b782c6d32" checksum = "d6943a1f213ad7a060a0548ece229be53f3c2151534b126446ce3533eaf5f14c"
dependencies = [ dependencies = [
"bstr", "bstr",
"gix-discover", "gix-discover",
@ -784,9 +784,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-filter" name = "gix-filter"
version = "0.11.0" version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd71bf3e64d8fb5d5635d4166ca5a36fe56b292ffff06eab1d93ea47fd5beb89" checksum = "5c0d1f01af62bfd2fb3dd291acc2b29d4ab3e96ad52a679174626508ce98ef12"
dependencies = [ dependencies = [
"bstr", "bstr",
"encoding_rs", "encoding_rs",
@ -805,9 +805,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-fs" name = "gix-fs"
version = "0.10.1" version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "634b8a743b0aae03c1a74ee0ea24e8c5136895efac64ce52b3ea106e1c6f0613" checksum = "e2184c40e7910529677831c8b481acf788ffd92427ed21fad65b6aa637e631b8"
dependencies = [ dependencies = [
"gix-features", "gix-features",
"gix-utils", "gix-utils",
@ -861,9 +861,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-index" name = "gix-index"
version = "0.31.1" version = "0.32.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "549621f13d9ccf325a7de45506a3266af0d08f915181c5687abb5e8669bfd2e6" checksum = "3383122cf18655ef4c097c0b935bba5eb56983947959aaf3b0ceb1949d4dd371"
dependencies = [ dependencies = [
"bitflags 2.5.0", "bitflags 2.5.0",
"bstr", "bstr",
@ -929,9 +929,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-odb" name = "gix-odb"
version = "0.59.0" version = "0.60.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81b55378c719693380f66d9dd21ce46721eed2981d8789fc698ec1ada6fa176e" checksum = "e8bbb43d2fefdc4701ffdf9224844d05b136ae1b9a73c2f90710c8dd27a93503"
dependencies = [ dependencies = [
"arc-swap", "arc-swap",
"gix-date", "gix-date",
@ -949,9 +949,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-pack" name = "gix-pack"
version = "0.49.0" version = "0.50.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6391aeaa030ad64aba346a9f5c69bb1c4e5c6fb4411705b03b40b49d8614ec30" checksum = "b58bad27c7677fa6b587aab3a1aca0b6c97373bd371a0a4290677c838c9bcaf1"
dependencies = [ dependencies = [
"clru", "clru",
"gix-chunk", "gix-chunk",
@ -969,9 +969,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-packetline-blocking" name = "gix-packetline-blocking"
version = "0.17.3" version = "0.17.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca8ef6dd3ea50e26f3bf572e90c034d033c804d340cd1eb386392f184a9ba2f7" checksum = "c31d42378a3d284732e4d589979930d0d253360eccf7ec7a80332e5ccb77e14a"
dependencies = [ dependencies = [
"bstr", "bstr",
"faster-hex", "faster-hex",
@ -994,9 +994,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-pathspec" name = "gix-pathspec"
version = "0.7.2" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a96ed0e71ce9084a471fddfa74e842576a7cbf02fe8bd50388017ac461aed97" checksum = "d479789f3abd10f68a709454ce04cd68b54092ee882c8622ae3aa1bb9bf8496c"
dependencies = [ dependencies = [
"bitflags 2.5.0", "bitflags 2.5.0",
"bstr", "bstr",
@ -1099,9 +1099,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-status" name = "gix-status"
version = "0.8.0" version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca216db89947eca709f69ec5851aa76f9628e7c7aab7aa5a927d0c619d046bf2" checksum = "50c413bfd2952e4ee92e48438dac3c696f3555e586a34d184a427f6bedd1e4f9"
dependencies = [ dependencies = [
"bstr", "bstr",
"filetime", "filetime",
@ -1150,16 +1150,17 @@ dependencies = [
[[package]] [[package]]
name = "gix-trace" name = "gix-trace"
version = "0.1.8" version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b838b2db8f62c9447d483a4c28d251b67fee32741a82cb4d35e9eb4e9fdc5ab" checksum = "f924267408915fddcd558e3f37295cc7d6a3e50f8bd8b606cee0808c3915157e"
[[package]] [[package]]
name = "gix-traverse" name = "gix-traverse"
version = "0.38.0" version = "0.39.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95aef84bc777025403a09788b1e4815c06a19332e9e5d87a955e1ed7da9bf0cf" checksum = "f4029ec209b0cc480d209da3837a42c63801dd8548f09c1f4502c60accb62aeb"
dependencies = [ dependencies = [
"bitflags 2.5.0",
"gix-commitgraph", "gix-commitgraph",
"gix-date", "gix-date",
"gix-hash", "gix-hash",
@ -1172,9 +1173,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-url" name = "gix-url"
version = "0.27.2" version = "0.27.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f0b24f3ecc79a5a53539de9c2e99425d0ef23feacdcf3faac983aa9a2f26849" checksum = "0db829ebdca6180fbe32be7aed393591df6db4a72dbbc0b8369162390954d1cf"
dependencies = [ dependencies = [
"bstr", "bstr",
"gix-features", "gix-features",
@ -1186,9 +1187,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-utils" name = "gix-utils"
version = "0.1.11" version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0066432d4c277f9877f091279a597ea5331f68ca410efc874f0bdfb1cd348f92" checksum = "35192df7fd0fa112263bad8021e2df7167df4cc2a6e6d15892e1e55621d3d4dc"
dependencies = [ dependencies = [
"bstr", "bstr",
"fastrand", "fastrand",
@ -1207,9 +1208,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-worktree" name = "gix-worktree"
version = "0.32.0" version = "0.33.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe78e03af9eec168eb187e05463a981c57f0a915f64b1788685a776bd2ef969c" checksum = "359a87dfef695b5f91abb9a424c947edca82768f34acfc269659f66174a510b4"
dependencies = [ dependencies = [
"bstr", "bstr",
"gix-attributes", "gix-attributes",

@ -29,6 +29,7 @@
"namespace" = "magenta" "namespace" = "magenta"
"ui.help" = { fg = "white", bg = "black" } "ui.help" = { fg = "white", bg = "black" }
"ui.virtual.jump-label" = { fg = "blue", modifiers = ["bold", "underlined"] } "ui.virtual.jump-label" = { fg = "blue", modifiers = ["bold", "underlined"] }
"ui.virtual.ruler" = { bg = "black" }
"markup.heading" = "blue" "markup.heading" = "blue"
"markup.list" = "red" "markup.list" = "red"

@ -122,6 +122,7 @@
| mermaid | ✓ | | | | | mermaid | ✓ | | | |
| meson | ✓ | | ✓ | | | meson | ✓ | | ✓ | |
| mint | | | | `mint` | | mint | | | | `mint` |
| move | ✓ | | | |
| msbuild | ✓ | | ✓ | | | msbuild | ✓ | | ✓ | |
| nasm | ✓ | ✓ | | | | nasm | ✓ | ✓ | | |
| nickel | ✓ | | ✓ | `nls` | | nickel | ✓ | | ✓ | `nls` |
@ -197,7 +198,7 @@
| tsx | ✓ | ✓ | ✓ | `typescript-language-server` | | tsx | ✓ | ✓ | ✓ | `typescript-language-server` |
| twig | ✓ | | | | | twig | ✓ | | | |
| typescript | ✓ | ✓ | ✓ | `typescript-language-server` | | typescript | ✓ | ✓ | ✓ | `typescript-language-server` |
| typst | ✓ | | | `typst-lsp` | | typst | ✓ | | | `tinymist`, `typst-lsp` |
| ungrammar | ✓ | | | | | ungrammar | ✓ | | | |
| unison | ✓ | | ✓ | | | unison | ✓ | | ✓ | |
| uxntal | ✓ | | | | | uxntal | ✓ | | | |
@ -215,6 +216,7 @@
| wren | ✓ | ✓ | ✓ | | | wren | ✓ | ✓ | ✓ | |
| xit | ✓ | | | | | xit | ✓ | | | |
| xml | ✓ | | ✓ | | | xml | ✓ | | ✓ | |
| xtc | ✓ | | | |
| yaml | ✓ | | ✓ | `yaml-language-server`, `ansible-language-server` | | yaml | ✓ | | ✓ | `yaml-language-server`, `ansible-language-server` |
| yuck | ✓ | | | | | yuck | ✓ | | | |
| zig | ✓ | ✓ | ✓ | `zls` | | zig | ✓ | ✓ | ✓ | `zls` |

@ -87,3 +87,4 @@
| `:redraw` | Clear and re-render the whole UI | | `:redraw` | Clear and re-render the whole UI |
| `:move` | Move the current buffer and its corresponding file to a different path | | `:move` | Move the current buffer and its corresponding file to a different path |
| `:yank-diagnostic` | Yank diagnostic(s) under primary cursor to register, or clipboard by default | | `:yank-diagnostic` | Yank diagnostic(s) under primary cursor to register, or clipboard by default |
| `:read`, `:r` | Load a file into buffer |

@ -24,6 +24,8 @@
> 💡 Mappings marked (**TS**) require a tree-sitter grammar for the file type. > 💡 Mappings marked (**TS**) require a tree-sitter grammar for the file type.
> ⚠️ Some terminals' default key mappings conflict with Helix's. If any of the mappings described on this page do not work as expected, check your terminal's mappings to ensure they do not conflict. See the (wiki)[https://github.com/helix-editor/helix/wiki/Terminal-Support] for known conflicts.
## Normal mode ## Normal mode
Normal mode is the default mode when you launch helix. You can return to it from other modes by pressing the `Escape` key. Normal mode is the default mode when you launch helix. You can return to it from other modes by pressing the `Escape` key.

@ -2765,10 +2765,10 @@ mod test {
) )
}; };
test("quantified_nodes", 1..36); test("quantified_nodes", 1..37);
// NOTE: Enable after implementing proper node group capturing // NOTE: Enable after implementing proper node group capturing
// test("quantified_nodes_grouped", 1..36); // test("quantified_nodes_grouped", 1..37);
// test("multiple_nodes_grouped", 1..36); // test("multiple_nodes_grouped", 1..37);
} }
#[test] #[test]
@ -2939,7 +2939,7 @@ mod test {
#[test] #[test]
fn test_pretty_print() { fn test_pretty_print() {
let source = r#"/// Hello"#; let source = r#"// Hello"#;
assert_pretty_print("rust", source, "(line_comment)", 0, source.len()); assert_pretty_print("rust", source, "(line_comment)", 0, source.len());
// A large tree should be indented with fields: // A large tree should be indented with fields:
@ -2958,7 +2958,8 @@ mod test {
" (macro_invocation\n", " (macro_invocation\n",
" macro: (identifier)\n", " macro: (identifier)\n",
" (token_tree\n", " (token_tree\n",
" (string_literal))))))", " (string_literal\n",
" (string_content)))))))",
), ),
0, 0,
source.len(), source.len(),

@ -799,28 +799,29 @@ fn goto_line_start(cx: &mut Context) {
} }
fn goto_next_buffer(cx: &mut Context) { fn goto_next_buffer(cx: &mut Context) {
goto_buffer(cx.editor, Direction::Forward); goto_buffer(cx.editor, Direction::Forward, cx.count());
} }
fn goto_previous_buffer(cx: &mut Context) { fn goto_previous_buffer(cx: &mut Context) {
goto_buffer(cx.editor, Direction::Backward); goto_buffer(cx.editor, Direction::Backward, cx.count());
} }
fn goto_buffer(editor: &mut Editor, direction: Direction) { fn goto_buffer(editor: &mut Editor, direction: Direction, count: usize) {
let current = view!(editor).doc; let current = view!(editor).doc;
let id = match direction { let id = match direction {
Direction::Forward => { Direction::Forward => {
let iter = editor.documents.keys(); let iter = editor.documents.keys();
let mut iter = iter.skip_while(|id| *id != &current); // skip 'count' times past current buffer
iter.next(); // skip current item iter.cycle().skip_while(|id| *id != &current).nth(count)
iter.next().or_else(|| editor.documents.keys().next())
} }
Direction::Backward => { Direction::Backward => {
let iter = editor.documents.keys(); let iter = editor.documents.keys();
let mut iter = iter.rev().skip_while(|id| *id != &current); // skip 'count' times past current buffer
iter.next(); // skip current item iter.rev()
iter.next().or_else(|| editor.documents.keys().next_back()) .cycle()
.skip_while(|id| *id != &current)
.nth(count)
} }
} }
.unwrap(); .unwrap();
@ -5435,6 +5436,7 @@ fn select_textobject(cx: &mut Context, objtype: textobject::TextObject) {
("T", "Test (tree-sitter)"), ("T", "Test (tree-sitter)"),
("e", "Data structure entry (tree-sitter)"), ("e", "Data structure entry (tree-sitter)"),
("m", "Closest surrounding pair"), ("m", "Closest surrounding pair"),
("g", "Change"),
(" ", "... or any character acting as a pair"), (" ", "... or any character acting as a pair"),
]; ];

@ -1,4 +1,5 @@
use std::fmt::Write; use std::fmt::Write;
use std::io::BufReader;
use std::ops::Deref; use std::ops::Deref;
use crate::job::Job; use crate::job::Job;
@ -8,7 +9,7 @@ use super::*;
use helix_core::fuzzy::fuzzy_match; use helix_core::fuzzy::fuzzy_match;
use helix_core::indent::MAX_INDENT; use helix_core::indent::MAX_INDENT;
use helix_core::{line_ending, shellwords::Shellwords}; use helix_core::{line_ending, shellwords::Shellwords};
use helix_view::document::DEFAULT_LANGUAGE_NAME; use helix_view::document::{read_to_string, DEFAULT_LANGUAGE_NAME};
use helix_view::editor::{CloseError, ConfigEvent}; use helix_view::editor::{CloseError, ConfigEvent};
use serde_json::Value; use serde_json::Value;
use ui::completers::{self, Completer}; use ui::completers::{self, Completer};
@ -309,7 +310,7 @@ fn buffer_next(
return Ok(()); return Ok(());
} }
goto_buffer(cx.editor, Direction::Forward); goto_buffer(cx.editor, Direction::Forward, 1);
Ok(()) Ok(())
} }
@ -322,7 +323,7 @@ fn buffer_previous(
return Ok(()); return Ok(());
} }
goto_buffer(cx.editor, Direction::Backward); goto_buffer(cx.editor, Direction::Backward, 1);
Ok(()) Ok(())
} }
@ -2454,6 +2455,39 @@ fn yank_diagnostic(
Ok(()) Ok(())
} }
fn read(cx: &mut compositor::Context, args: &[Cow<str>], event: PromptEvent) -> anyhow::Result<()> {
if event != PromptEvent::Validate {
return Ok(());
}
let scrolloff = cx.editor.config().scrolloff;
let (view, doc) = current!(cx.editor);
ensure!(!args.is_empty(), "file name is expected");
ensure!(args.len() == 1, "only the file name is expected");
let filename = args.get(0).unwrap();
let path = PathBuf::from(filename.to_string());
ensure!(
path.exists() && path.is_file(),
"path is not a file: {:?}",
path
);
let file = std::fs::File::open(path).map_err(|err| anyhow!("error opening file: {}", err))?;
let mut reader = BufReader::new(file);
let (contents, _, _) = read_to_string(&mut reader, Some(doc.encoding()))
.map_err(|err| anyhow!("error reading file: {}", err))?;
let contents = Tendril::from(contents);
let selection = doc.selection(view.id);
let transaction = Transaction::insert(doc.text(), selection, contents);
doc.apply(&transaction, view.id);
doc.append_changes_to_history(view);
view.ensure_cursor_in_view(doc, scrolloff);
Ok(())
}
pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[
TypableCommand { TypableCommand {
name: "quit", name: "quit",
@ -3068,6 +3102,13 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[
fun: yank_diagnostic, fun: yank_diagnostic,
signature: CommandSignature::all(completers::register), signature: CommandSignature::all(completers::register),
}, },
TypableCommand {
name: "read",
aliases: &["r"],
doc: "Load a file into buffer",
fun: read,
signature: CommandSignature::positional(&[completers::filename]),
},
]; ];
pub static TYPABLE_COMMAND_MAP: Lazy<HashMap<&'static str, &'static TypableCommand>> = pub static TYPABLE_COMMAND_MAP: Lazy<HashMap<&'static str, &'static TypableCommand>> =

@ -5,7 +5,7 @@ use helix_core::syntax::LanguageServerFeature;
use helix_event::{ use helix_event::{
cancelable_future, cancelation, register_hook, send_blocking, CancelRx, CancelTx, cancelable_future, cancelation, register_hook, send_blocking, CancelRx, CancelTx,
}; };
use helix_lsp::lsp; use helix_lsp::lsp::{self, SignatureInformation};
use helix_stdx::rope::RopeSliceExt; use helix_stdx::rope::RopeSliceExt;
use helix_view::document::Mode; use helix_view::document::Mode;
use helix_view::events::{DocumentDidChange, SelectionDidChange}; use helix_view::events::{DocumentDidChange, SelectionDidChange};
@ -18,7 +18,7 @@ use crate::commands::Open;
use crate::compositor::Compositor; use crate::compositor::Compositor;
use crate::events::{OnModeSwitch, PostInsertChar}; use crate::events::{OnModeSwitch, PostInsertChar};
use crate::handlers::Handlers; use crate::handlers::Handlers;
use crate::ui::lsp::SignatureHelp; use crate::ui::lsp::{Signature, SignatureHelp};
use crate::ui::Popup; use crate::ui::Popup;
use crate::{job, ui}; use crate::{job, ui};
@ -82,6 +82,7 @@ impl helix_event::AsyncHook for SignatureHelpHandler {
} }
} }
self.state = if open { State::Open } else { State::Closed }; self.state = if open { State::Open } else { State::Closed };
return timeout; return timeout;
} }
} }
@ -138,6 +139,31 @@ pub fn request_signature_help(
}); });
} }
fn active_param_range(
signature: &SignatureInformation,
response_active_parameter: Option<u32>,
) -> Option<(usize, usize)> {
let param_idx = signature
.active_parameter
.or(response_active_parameter)
.unwrap_or(0) as usize;
let param = signature.parameters.as_ref()?.get(param_idx)?;
match &param.label {
lsp::ParameterLabel::Simple(string) => {
let start = signature.label.find(string.as_str())?;
Some((start, start + string.len()))
}
lsp::ParameterLabel::LabelOffsets([start, end]) => {
// LS sends offsets based on utf-16 based string representation
// but highlighting in helix is done using byte offset.
use helix_core::str_utils::char_to_byte_idx;
let from = char_to_byte_idx(&signature.label, *start as usize);
let to = char_to_byte_idx(&signature.label, *end as usize);
Some((from, to))
}
}
}
pub fn show_signature_help( pub fn show_signature_help(
editor: &mut Editor, editor: &mut Editor,
compositor: &mut Compositor, compositor: &mut Compositor,
@ -184,54 +210,50 @@ pub fn show_signature_help(
let doc = doc!(editor); let doc = doc!(editor);
let language = doc.language_name().unwrap_or(""); let language = doc.language_name().unwrap_or("");
let signature = match response if response.signatures.is_empty() {
return;
}
let signatures: Vec<Signature> = response
.signatures .signatures
.get(response.active_signature.unwrap_or(0) as usize) .into_iter()
{ .map(|s| {
Some(s) => s, let active_param_range = active_param_range(&s, response.active_parameter);
None => return,
}; let signature_doc = if config.lsp.display_signature_help_docs {
let mut contents = SignatureHelp::new( s.documentation.map(|doc| match doc {
signature.label.clone(), lsp::Documentation::String(s) => s,
lsp::Documentation::MarkupContent(markup) => markup.value,
})
} else {
None
};
Signature {
signature: s.label,
signature_doc,
active_param_range,
}
})
.collect();
let old_popup = compositor.find_id::<Popup<SignatureHelp>>(SignatureHelp::ID);
let mut active_signature = old_popup
.as_ref()
.map(|popup| popup.contents().active_signature())
.unwrap_or_else(|| response.active_signature.unwrap_or_default() as usize);
if active_signature >= signatures.len() {
active_signature = signatures.len() - 1;
}
let contents = SignatureHelp::new(
language.to_string(), language.to_string(),
Arc::clone(&editor.syn_loader), Arc::clone(&editor.syn_loader),
active_signature,
signatures,
); );
let signature_doc = if config.lsp.display_signature_help_docs {
signature.documentation.as_ref().map(|doc| match doc {
lsp::Documentation::String(s) => s.clone(),
lsp::Documentation::MarkupContent(markup) => markup.value.clone(),
})
} else {
None
};
contents.set_signature_doc(signature_doc);
let active_param_range = || -> Option<(usize, usize)> {
let param_idx = signature
.active_parameter
.or(response.active_parameter)
.unwrap_or(0) as usize;
let param = signature.parameters.as_ref()?.get(param_idx)?;
match &param.label {
lsp::ParameterLabel::Simple(string) => {
let start = signature.label.find(string.as_str())?;
Some((start, start + string.len()))
}
lsp::ParameterLabel::LabelOffsets([start, end]) => {
// LS sends offsets based on utf-16 based string representation
// but highlighting in helix is done using byte offset.
use helix_core::str_utils::char_to_byte_idx;
let from = char_to_byte_idx(&signature.label, *start as usize);
let to = char_to_byte_idx(&signature.label, *end as usize);
Some((from, to))
}
}
};
contents.set_active_param_range(active_param_range());
let old_popup = compositor.find_id::<Popup<SignatureHelp>>(SignatureHelp::ID);
let mut popup = Popup::new(SignatureHelp::ID, contents) let mut popup = Popup::new(SignatureHelp::ID, contents)
.position(old_popup.and_then(|p| p.get_position())) .position(old_popup.and_then(|p| p.get_position()))
.position_bias(Open::Above) .position_bias(Open::Above)

@ -3,60 +3,95 @@ use std::sync::Arc;
use arc_swap::ArcSwap; use arc_swap::ArcSwap;
use helix_core::syntax; use helix_core::syntax;
use helix_view::graphics::{Margin, Rect, Style}; use helix_view::graphics::{Margin, Rect, Style};
use helix_view::input::Event;
use tui::buffer::Buffer; use tui::buffer::Buffer;
use tui::layout::Alignment;
use tui::text::Text;
use tui::widgets::{BorderType, Paragraph, Widget, Wrap}; use tui::widgets::{BorderType, Paragraph, Widget, Wrap};
use crate::compositor::{Component, Compositor, Context}; use crate::compositor::{Component, Compositor, Context, EventResult};
use crate::alt;
use crate::ui::Markdown; use crate::ui::Markdown;
use super::Popup; use super::Popup;
pub struct SignatureHelp { pub struct Signature {
signature: String, pub signature: String,
signature_doc: Option<String>, pub signature_doc: Option<String>,
/// Part of signature text /// Part of signature text
active_param_range: Option<(usize, usize)>, pub active_param_range: Option<(usize, usize)>,
}
pub struct SignatureHelp {
language: String, language: String,
config_loader: Arc<ArcSwap<syntax::Loader>>, config_loader: Arc<ArcSwap<syntax::Loader>>,
active_signature: usize,
signatures: Vec<Signature>,
} }
impl SignatureHelp { impl SignatureHelp {
pub const ID: &'static str = "signature-help"; pub const ID: &'static str = "signature-help";
pub fn new( pub fn new(
signature: String,
language: String, language: String,
config_loader: Arc<ArcSwap<syntax::Loader>>, config_loader: Arc<ArcSwap<syntax::Loader>>,
active_signature: usize,
signatures: Vec<Signature>,
) -> Self { ) -> Self {
Self { Self {
signature,
signature_doc: None,
active_param_range: None,
language, language,
config_loader, config_loader,
active_signature,
signatures,
} }
} }
pub fn set_signature_doc(&mut self, signature_doc: Option<String>) { pub fn active_signature(&self) -> usize {
self.signature_doc = signature_doc; self.active_signature
}
pub fn set_active_param_range(&mut self, offset: Option<(usize, usize)>) {
self.active_param_range = offset;
} }
pub fn visible_popup(compositor: &mut Compositor) -> Option<&mut Popup<Self>> { pub fn visible_popup(compositor: &mut Compositor) -> Option<&mut Popup<Self>> {
compositor.find_id::<Popup<Self>>(Self::ID) compositor.find_id::<Popup<Self>>(Self::ID)
} }
fn signature_index(&self) -> String {
format!("({}/{})", self.active_signature + 1, self.signatures.len())
}
} }
impl Component for SignatureHelp { impl Component for SignatureHelp {
fn handle_event(&mut self, event: &Event, _cx: &mut Context) -> EventResult {
let Event::Key(event) = event else {
return EventResult::Ignored(None);
};
if self.signatures.len() <= 1 {
return EventResult::Ignored(None);
}
match event {
alt!('p') => {
self.active_signature = self
.active_signature
.checked_sub(1)
.unwrap_or(self.signatures.len() - 1);
EventResult::Consumed(None)
}
alt!('n') => {
self.active_signature = (self.active_signature + 1) % self.signatures.len();
EventResult::Consumed(None)
}
_ => EventResult::Ignored(None),
}
}
fn render(&mut self, area: Rect, surface: &mut Buffer, cx: &mut Context) { fn render(&mut self, area: Rect, surface: &mut Buffer, cx: &mut Context) {
let margin = Margin::horizontal(1); let margin = Margin::horizontal(1);
let active_param_span = self.active_param_range.map(|(start, end)| { let signature = &self.signatures[self.active_signature];
let active_param_span = signature.active_param_range.map(|(start, end)| {
vec![( vec![(
cx.editor cx.editor
.theme .theme
@ -66,21 +101,29 @@ impl Component for SignatureHelp {
)] )]
}); });
let sig = &self.signatures[self.active_signature];
let sig_text = crate::ui::markdown::highlighted_code_block( let sig_text = crate::ui::markdown::highlighted_code_block(
&self.signature, sig.signature.as_str(),
&self.language, &self.language,
Some(&cx.editor.theme), Some(&cx.editor.theme),
Arc::clone(&self.config_loader), Arc::clone(&self.config_loader),
active_param_span, active_param_span,
); );
if self.signatures.len() > 1 {
let signature_index = self.signature_index();
let text = Text::from(signature_index);
let paragraph = Paragraph::new(&text).alignment(Alignment::Right);
paragraph.render(area.clip_top(1).with_height(1).clip_right(1), surface);
}
let (_, sig_text_height) = crate::ui::text::required_size(&sig_text, area.width); let (_, sig_text_height) = crate::ui::text::required_size(&sig_text, area.width);
let sig_text_area = area.clip_top(1).with_height(sig_text_height); let sig_text_area = area.clip_top(1).with_height(sig_text_height);
let sig_text_area = sig_text_area.inner(&margin).intersection(surface.area); let sig_text_area = sig_text_area.inner(&margin).intersection(surface.area);
let sig_text_para = Paragraph::new(&sig_text).wrap(Wrap { trim: false }); let sig_text_para = Paragraph::new(&sig_text).wrap(Wrap { trim: false });
sig_text_para.render(sig_text_area, surface); sig_text_para.render(sig_text_area, surface);
if self.signature_doc.is_none() { if sig.signature_doc.is_none() {
return; return;
} }
@ -92,7 +135,7 @@ impl Component for SignatureHelp {
} }
} }
let sig_doc = match &self.signature_doc { let sig_doc = match &sig.signature_doc {
None => return, None => return,
Some(doc) => Markdown::new(doc.clone(), Arc::clone(&self.config_loader)), Some(doc) => Markdown::new(doc.clone(), Arc::clone(&self.config_loader)),
}; };
@ -110,13 +153,15 @@ impl Component for SignatureHelp {
const PADDING: u16 = 2; const PADDING: u16 = 2;
const SEPARATOR_HEIGHT: u16 = 1; const SEPARATOR_HEIGHT: u16 = 1;
let sig = &self.signatures[self.active_signature];
if PADDING >= viewport.1 || PADDING >= viewport.0 { if PADDING >= viewport.1 || PADDING >= viewport.0 {
return None; return None;
} }
let max_text_width = (viewport.0 - PADDING).min(120); let max_text_width = (viewport.0 - PADDING).min(120);
let signature_text = crate::ui::markdown::highlighted_code_block( let signature_text = crate::ui::markdown::highlighted_code_block(
&self.signature, sig.signature.as_str(),
&self.language, &self.language,
None, None,
Arc::clone(&self.config_loader), Arc::clone(&self.config_loader),
@ -125,7 +170,7 @@ impl Component for SignatureHelp {
let (sig_width, sig_height) = let (sig_width, sig_height) =
crate::ui::text::required_size(&signature_text, max_text_width); crate::ui::text::required_size(&signature_text, max_text_width);
let (width, height) = match self.signature_doc { let (width, height) = match sig.signature_doc {
Some(ref doc) => { Some(ref doc) => {
let doc_md = Markdown::new(doc.clone(), Arc::clone(&self.config_loader)); let doc_md = Markdown::new(doc.clone(), Arc::clone(&self.config_loader));
let doc_text = doc_md.parse(None); let doc_text = doc_md.parse(None);
@ -139,6 +184,12 @@ impl Component for SignatureHelp {
None => (sig_width, sig_height), None => (sig_width, sig_height),
}; };
Some((width + PADDING, height + PADDING)) let sig_index_width = if self.signatures.len() > 1 {
self.signature_index().len() + 1
} else {
0
};
Some((width + PADDING + sig_index_width as u16, height + PADDING))
} }
} }

@ -640,3 +640,27 @@ async fn test_join_selections_space() -> anyhow::Result<()> {
Ok(()) Ok(())
} }
#[tokio::test(flavor = "multi_thread")]
async fn test_read_file() -> anyhow::Result<()> {
let mut file = tempfile::NamedTempFile::new()?;
let contents_to_read = "some contents";
let output_file = helpers::temp_file_with_contents(contents_to_read)?;
test_key_sequence(
&mut helpers::AppBuilder::new()
.with_file(file.path(), None)
.build()?,
Some(&format!(":r {:?}<ret><esc>:w<ret>", output_file.path())),
Some(&|app| {
assert!(!app.editor.is_err(), "error: {:?}", app.editor.get_status());
}),
false,
)
.await?;
let expected_contents = LineFeedHandling::Native.apply(contents_to_read);
helpers::assert_file_has_content(&mut file, &expected_contents)?;
Ok(())
}

@ -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.61.0", features = ["attributes", "status"], default-features = false, optional = true } gix = { version = "0.62.0", features = ["attributes", "status"], default-features = false, optional = true }
imara-diff = "0.1.5" imara-diff = "0.1.5"
anyhow = "1" anyhow = "1"

@ -102,6 +102,7 @@ yaml-language-server = { command = "yaml-language-server", args = ["--stdio"] }
zls = { command = "zls" } zls = { command = "zls" }
blueprint-compiler = { command = "blueprint-compiler", args = ["lsp"] } blueprint-compiler = { command = "blueprint-compiler", args = ["lsp"] }
typst-lsp = { command = "typst-lsp" } typst-lsp = { command = "typst-lsp" }
tinymist = { command = "tinymist" }
pkgbuild-language-server = { command = "pkgbuild-language-server" } pkgbuild-language-server = { command = "pkgbuild-language-server" }
helm_ls = { command = "helm_ls", args = ["serve"] } helm_ls = { command = "helm_ls", args = ["serve"] }
ember-language-server = { command = "ember-language-server", args = ["--stdio"] } ember-language-server = { command = "ember-language-server", args = ["--stdio"] }
@ -201,6 +202,7 @@ scope = "source.rust"
injection-regex = "rust" injection-regex = "rust"
file-types = ["rs"] file-types = ["rs"]
roots = ["Cargo.toml", "Cargo.lock"] roots = ["Cargo.toml", "Cargo.lock"]
shebangs = ["rust-script", "cargo"]
auto-format = true auto-format = true
comment-tokens = ["//", "///", "//!"] comment-tokens = ["//", "///", "//!"]
block-comment-tokens = [ block-comment-tokens = [
@ -250,7 +252,7 @@ args = { attachCommands = [ "platform select remote-gdb-server", "platform conne
[[grammar]] [[grammar]]
name = "rust" name = "rust"
source = { git = "https://github.com/tree-sitter/tree-sitter-rust", rev = "0431a2c60828731f27491ee9fdefe25e250ce9c9" } source = { git = "https://github.com/tree-sitter/tree-sitter-rust", rev = "473634230435c18033384bebaa6d6a17c2523281" }
[[language]] [[language]]
name = "sway" name = "sway"
@ -2052,6 +2054,29 @@ block-comment-tokens = { start = "/*", end = "*/" }
indent = { tab-width = 4, unit = "\t" } indent = { tab-width = 4, unit = "\t" }
formatter = { command = "odinfmt", args = [ "-stdin", "true" ] } formatter = { command = "odinfmt", args = [ "-stdin", "true" ] }
[language.debugger]
name = "lldb-dap"
transport = "stdio"
command = "lldb-dap"
[[language.debugger.templates]]
name = "binary"
request = "launch"
completion = [ { name = "binary", completion = "filename" } ]
args = { console = "internalConsole", program = "{0}" }
[[language.debugger.templates]]
name = "attach"
request = "attach"
completion = [ "pid" ]
args = { console = "internalConsole", pid = "{0}" }
[[language.debugger.templates]]
name = "gdbserver attach"
request = "attach"
completion = [ { name = "lldb connect url", default = "connect://localhost:3333" }, { name = "file", completion = "filename" }, "pid" ]
args = { console = "internalConsole", attachCommands = [ "platform select remote-gdb-server", "platform connect {0}", "file {1}", "attach {2}" ] }
[[grammar]] [[grammar]]
name = "odin" name = "odin"
source = { git = "https://github.com/ap29600/tree-sitter-odin", rev = "b219207e49ffca2952529d33e94ed63b1b75c4f1" } source = { git = "https://github.com/ap29600/tree-sitter-odin", rev = "b219207e49ffca2952529d33e94ed63b1b75c4f1" }
@ -3071,7 +3096,7 @@ scope = "source.typst"
injection-regex = "typst" injection-regex = "typst"
file-types = ["typst", "typ"] file-types = ["typst", "typ"]
comment-token = "//" comment-token = "//"
language-servers = ["typst-lsp"] language-servers = ["tinymist", "typst-lsp"]
indent = { tab-width = 2, unit = " " } indent = { tab-width = 2, unit = " " }
[language.auto-pairs] [language.auto-pairs]
@ -3083,7 +3108,7 @@ indent = { tab-width = 2, unit = " " }
[[grammar]] [[grammar]]
name = "typst" name = "typst"
source = { git = "https://github.com/uben0/tree-sitter-typst", rev = "ecf8596336857adfcd5f7cbb3b2aa11a67badc37" } source = { git = "https://github.com/uben0/tree-sitter-typst", rev = "13863ddcbaa7b68ee6221cea2e3143415e64aea4" }
[[language]] [[language]]
name = "nunjucks" name = "nunjucks"
@ -3366,7 +3391,7 @@ source = { git = "https://github.com/mtoohey31/tree-sitter-ld", rev = "0e9695ae0
name = "hyprlang" name = "hyprlang"
scope = "source.hyprlang" scope = "source.hyprlang"
roots = ["hyprland.conf"] roots = ["hyprland.conf"]
file-types = [ { glob = "hyprland.conf"} ] file-types = [ { glob = "hyprland.conf" }, { glob = "hyprpaper.conf" }, { glob = "hypridle.conf" }, { glob = "hyprlock.conf" } ]
comment-token = "#" comment-token = "#"
grammar = "hyprlang" grammar = "hyprlang"
@ -3478,7 +3503,7 @@ language-servers = ["earthlyls"]
[[grammar]] [[grammar]]
name = "earthfile" name = "earthfile"
source = { git = "https://github.com/glehmann/tree-sitter-earthfile", rev = "2a6ab191f5f962562e495a818aa4e7f45f8a556a" } source = { git = "https://github.com/glehmann/tree-sitter-earthfile", rev = "a079e6c472eeedd6b9a1e03ca0b6c82cd6a112a4" }
[[language]] [[language]]
name = "adl" name = "adl"
@ -3508,3 +3533,28 @@ comment-token = "#"
[[grammar]] [[grammar]]
name = "ldif" name = "ldif"
source = { git = "https://github.com/kepet19/tree-sitter-ldif", rev = "0a917207f65ba3e3acfa9cda16142ee39c4c1aaa" } source = { git = "https://github.com/kepet19/tree-sitter-ldif", rev = "0a917207f65ba3e3acfa9cda16142ee39c4c1aaa" }
[[language]]
name = "xtc"
scope = "source.xtc"
# Accept Xena Traffic Configuration, Xena Port Configuration and Xena OpenAutomation
file-types = [ "xtc", "xpc", "xoa" ]
comment-token = ";"
[[grammar]]
name = "xtc"
source = { git = "https://github.com/Alexis-Lapierre/tree-sitter-xtc", rev = "7bc11b736250c45e25cfb0215db2f8393779957e" }
[[language]]
name = "move"
scope = "source.move"
injection-regex = "move"
roots = ["Move.toml"]
file-types = ["move"]
comment-token = "//"
indent = { tab-width = 4, unit = " " }
language-servers = []
[[grammar]]
name = "move"
source = { git = "https://github.com/tzakian/tree-sitter-move", rev = "8bc0d1692caa8763fef54d48068238d9bf3c0264" }

@ -1,42 +1,48 @@
(string_array "," @punctuation.delimiter) (string_array "," @punctuation.delimiter)
(string_array ["[" "]"] @punctuation.bracket) (string_array ["[" "]"] @punctuation.bracket)
(arg_command "ARG" @keyword) [
(build_command "BUILD" @keyword) "ARG"
(cache_command "CACHE" @keyword) "AS LOCAL"
(cmd_command "CMD" @keyword) "BUILD"
(copy_command "COPY" @keyword) "CACHE"
(do_command "DO" @keyword) "CMD"
(entrypoint_command "ENTRYPOINT" @keyword) "COPY"
(env_command "ENV" @keyword) "DO"
(expose_command "EXPOSE" @keyword) "ENTRYPOINT"
(from_command "FROM" @keyword) "ENV"
(from_dockerfile_command "FROM DOCKERFILE" @keyword) "EXPOSE"
(function_command "FUNCTION" @keyword) "FROM DOCKERFILE"
(git_clone_command "GIT CLONE" @keyword) "FROM"
(host_command "HOST" @keyword) "FUNCTION"
(import_command "IMPORT" @keyword) "GIT CLONE"
(label_command "LABEL" @keyword) "HOST"
(let_command "LET" @keyword) "IMPORT"
(project_command "PROJECT" @keyword) "LABEL"
(run_command "RUN" @keyword) "LET"
(save_artifact_command ["SAVE ARTIFACT" "AS LOCAL"] @keyword) "PROJECT"
(save_image_command "SAVE IMAGE" @keyword) "RUN"
(set_command "SET" @keyword) "SAVE ARTIFACT"
(user_command "USER" @keyword) "SAVE IMAGE"
(version_command "VERSION" @keyword) "SET"
(volume_command "VOLUME" @keyword) "USER"
(with_docker_command "WITH DOCKER" @keyword) "VERSION"
(workdir_command "WORKDIR" @keyword) "VOLUME"
"WORKDIR"
] @keyword
(for_command ["FOR" "IN" "END"] @keyword.control.repeat) (for_command ["FOR" "IN" "END"] @keyword.control.repeat)
(if_command ["IF" "END"] @keyword.control.conditional) (if_command ["IF" "END"] @keyword.control.conditional)
(elif_block ["ELSE IF"] @keyword.control.conditional) (elif_block ["ELSE IF"] @keyword.control.conditional)
(else_block ["ELSE"] @keyword.control.conditional) (else_block ["ELSE"] @keyword.control.conditional)
(import_command ["IMPORT" "AS"] @keyword.control.import) (import_command ["IMPORT" "AS"] @keyword.control.import)
(try_command ["TRY" "FINALLY" "END"] @keyword.control.exception) (try_command ["TRY" "FINALLY" "END"] @keyword.control.exception)
(wait_command ["WAIT" "END"] @keyword.control)
(wait_command ["WAIT" "END"] @keyword.control)
(with_docker_command ["WITH DOCKER" "END"] @keyword.control)
[ [
(comment) (comment)
@ -65,10 +71,4 @@
(build_arg) @variable (build_arg) @variable
(options (_) @variable.parameter) (options (_) @variable.parameter)
(options (_ "=" @operator)) "=" @operator
(build_arg "=" @operator)
(arg_command "=" @operator)
(env_command "=" @operator)
(label "=" @operator)
(set_command "=" @operator)
(let_command "=" @operator)

@ -0,0 +1,157 @@
(ability) @keyword
; ---
; Primitives
; ---
(address_literal) @constant
(bool_literal) @constant.builtin.boolean
(num_literal) @constant.numeric
[
(hex_string_literal)
(byte_string_literal)
] @string
; TODO: vector_literal
[
(line_comment)
(block_comment)
] @comment
(annotation) @function.macro
(borrow_expression "&" @keyword.storage.modifier.ref)
(borrow_expression "&mut" @keyword.storage.modifier.mut)
(constant_identifier) @constant
((identifier) @constant
(#match? @constant "^[A-Z][A-Z\\d_]*$"))
(function_identifier) @function
(struct_identifier) @type
(pack_expression
access: (module_access
member: (identifier) @type))
(apply_type
(module_access
member: (identifier) @type))
(field_identifier) @variable.other.member
; -------
; Functions
; -------
(call_expression
access: (module_access
member: (identifier) @function))
(macro_call_expression
access: (macro_module_access
access: (module_access
member: [(identifier) @function.macro])
"!" @function.macro))
; -------
; Paths
; -------
(module_identifier) @namespace
; -------
; Operators
; -------
[
"*"
"="
"!"
] @operator
(binary_operator) @operator
; ---
; Punctuation
; ---
[
"::"
"."
";"
","
] @punctuation.delimiter
[
"("
")"
"["
"]"
"{"
"}"
] @punctuation.bracket
[
"abort"
; "acquires"
"as"
"break"
"const"
"continue"
"copy"
"else"
"false"
"friend"
"fun"
"has"
"if"
; "invariant"
"let"
"loop"
"module"
"move"
"native"
"public"
"return"
; "script"
"spec"
"struct"
"true"
"use"
"while"
"entry"
; "aborts_if"
; "aborts_with"
"address"
"apply"
"assume"
; "axiom"
; "choose"
"decreases"
; "emits"
"ensures"
"except"
; "forall"
"global"
"include"
"internal"
"local"
; "min"
; "modifies"
"mut"
"phantom"
"post"
"pragma"
; "requires"
; "Self"
"schema"
"succeeds_if"
"to"
; "update"
"where"
"with"
] @keyword
(primitive_type) @type.buildin
(identifier) @variable

@ -51,7 +51,7 @@
(lifetime (lifetime
"'" @label "'" @label
(identifier) @label) (identifier) @label)
(loop_label (label
"'" @label "'" @label
(identifier) @label) (identifier) @label)

@ -1,6 +1,11 @@
; Special identifiers ; Special identifiers
;-------------------- ;--------------------
(tag_name) @tag
(attribute_name) @variable.other.member
(erroneous_end_tag_name) @error
(comment) @comment
; TODO: ; TODO:
((element (start_tag (tag_name) @_tag) (text) @markup.heading) ((element (start_tag (tag_name) @_tag) (text) @markup.heading)
(#match? @_tag "^(h[0-9]|title)$")) (#match? @_tag "^(h[0-9]|title)$"))
@ -28,11 +33,6 @@
(quoted_attribute_value (attribute_value) @markup.link.url)) (quoted_attribute_value (attribute_value) @markup.link.url))
(#match? @_attr "^(href|src)$")) (#match? @_attr "^(href|src)$"))
(tag_name) @tag
(attribute_name) @variable.other.member
(erroneous_end_tag_name) @error
(comment) @comment
[ [
(attribute_value) (attribute_value)
(quoted_attribute_value) (quoted_attribute_value)

@ -21,6 +21,7 @@
; OPERATOR ; OPERATOR
(in ["in" "not"] @keyword.operator) (in ["in" "not"] @keyword.operator)
(context "context" @keyword.control)
(and "and" @keyword.operator) (and "and" @keyword.operator)
(or "or" @keyword.operator) (or "or" @keyword.operator)
(not "not" @keyword.operator) (not "not" @keyword.operator)
@ -45,12 +46,9 @@
(string) @string (string) @string
(content ["[" "]"] @operator) (content ["[" "]"] @operator)
(bool) @constant.builtin.boolean (bool) @constant.builtin.boolean
(builtin) @constant.builtin
(none) @constant.builtin (none) @constant.builtin
(auto) @constant.builtin (auto) @constant.builtin
(ident) @variable (ident) @variable
(call
item: (builtin) @function.builtin)
; MARKUP ; MARKUP
(item "-" @markup.list) (item "-" @markup.list)

@ -0,0 +1,27 @@
(parameter) @keyword
(change_port) @function.special
(template) @variable
[
(hex_argument)
(ipv4_argument)
] @attribute
(numeric_argument) @constant.numeric
(index) @tag
(string_literal_argument) @string
(string_argument) @constant.character
(comment) @comment
(port_comment) @label
[
("[")
("]")
] @punctuation.bracket

@ -3,6 +3,7 @@
"ui.background" = { bg = "base00" } "ui.background" = { bg = "base00" }
"ui.virtual.whitespace" = "base03" "ui.virtual.whitespace" = "base03"
"ui.virtual.jump-label" = { fg = "blue", modifiers = ["bold", "underlined"] } "ui.virtual.jump-label" = { fg = "blue", modifiers = ["bold", "underlined"] }
"ui.virtual.ruler" = { bg = "base01" }
"ui.menu" = { fg = "base05", bg = "base01" } "ui.menu" = { fg = "base05", bg = "base01" }
"ui.menu.selected" = { fg = "base01", bg = "base04" } "ui.menu.selected" = { fg = "base01", bg = "base04" }
"ui.linenr" = { fg = "base03", bg = "base01" } "ui.linenr" = { fg = "base03", bg = "base01" }

@ -14,6 +14,7 @@
"ui.cursor.primary" = { fg = "base05", modifiers = ["reversed"] } "ui.cursor.primary" = { fg = "base05", modifiers = ["reversed"] }
"ui.virtual.whitespace" = "base03" "ui.virtual.whitespace" = "base03"
"ui.virtual.jump-label" = { fg = "blue", modifiers = ["bold", "underlined"] } "ui.virtual.jump-label" = { fg = "blue", modifiers = ["bold", "underlined"] }
"ui.virtual.ruler" = { bg = "base01" }
"ui.text" = "base05" "ui.text" = "base05"
"operator" = "base05" "operator" = "base05"
"ui.text.focus" = "base05" "ui.text.focus" = "base05"

@ -15,6 +15,7 @@
"ui.cursor.primary" = { fg = "light-gray", modifiers = ["reversed"] } "ui.cursor.primary" = { fg = "light-gray", modifiers = ["reversed"] }
"ui.virtual.whitespace" = "light-gray" "ui.virtual.whitespace" = "light-gray"
"ui.virtual.jump-label" = { fg = "blue", modifiers = ["bold", "underlined"] } "ui.virtual.jump-label" = { fg = "blue", modifiers = ["bold", "underlined"] }
"ui.virtual.ruler" = { bg = "black" }
"variable" = "light-red" "variable" = "light-red"
"constant.numeric" = "yellow" "constant.numeric" = "yellow"
"constant" = "yellow" "constant" = "yellow"

@ -4,15 +4,19 @@ constant = "purple"
"constant.numeric" = "orange" "constant.numeric" = "orange"
"constant.builtin" = "orange" "constant.builtin" = "orange"
variable = "red" variable = "red"
attribute = "brown"
comment = "light-gray" comment = "light-gray"
special = "purple" special = "purple"
"punctuation" = "red"
"punctuation.bracket" = "purple" "punctuation.bracket" = "purple"
"punctuation.delimiter" = "white"
keyword = "purple" keyword = "purple"
function = "blue" function = "blue"
label = "orange" label = "orange"
type = "orange" type = "orange"
constructor = "orange" constructor = "orange"
namespace = "orange" namespace = "orange"
tag = "red"
# User Interface # User Interface
"ui.background" = { bg = "bg", fg = "gray" } "ui.background" = { bg = "bg", fg = "gray" }
@ -29,6 +33,7 @@ namespace = "orange"
"ui.selection" = { bg = "selection" } "ui.selection" = { bg = "selection" }
"ui.virtual.indent-guide" = { fg = "gray" } "ui.virtual.indent-guide" = { fg = "gray" }
"ui.virtual.whitespace" = { fg = "light-gray" } "ui.virtual.whitespace" = { fg = "light-gray" }
"ui.virtual.ruler" = { bg ="dark-bg" }
"ui.statusline" = { bg = "dark-bg", fg = "light-gray" } "ui.statusline" = { bg = "dark-bg", fg = "light-gray" }
"ui.popup" = { bg = "dark-bg", fg = "orange" } "ui.popup" = { bg = "dark-bg", fg = "orange" }
"ui.help" = { bg = "dark-bg", fg = "orange" } "ui.help" = { bg = "dark-bg", fg = "orange" }
@ -79,6 +84,7 @@ pink = "#EE64AE"
selection = "#353747" selection = "#353747"
green = "#27D796" green = "#27D796"
orange = "#FAB795" orange = "#FAB795"
brown = "#F09383"
purple = "#B877DB" purple = "#B877DB"
red = "#E95678" red = "#E95678"
blue = "#25B2BC" blue = "#25B2BC"

@ -8,7 +8,7 @@
## User interface ## User interface
"ui.selection" = { bg = "waveBlue2" } "ui.selection" = { bg = "waveBlue2" }
"ui.selection.primary" = { bg = "sumiInk5" } "ui.selection.primary" = { bg = "waveBlue2" }
"ui.background" = { fg = "fujiWhite", bg = "sumiInk1" } "ui.background" = { fg = "fujiWhite", bg = "sumiInk1" }
"ui.linenr" = { fg = "sumiInk4" } "ui.linenr" = { fg = "sumiInk4" }
@ -123,7 +123,6 @@ sumiInk1 = "#1F1F28" # default background
sumiInk2 = "#2A2A37" # lighter background, e.g. colorcolumns, folds sumiInk2 = "#2A2A37" # lighter background, e.g. colorcolumns, folds
sumiInk3 = "#363646" # lighter background, e.g. cursorline sumiInk3 = "#363646" # lighter background, e.g. cursorline
sumiInk4 = "#54546D" # darker foreground, e.g. linenumbers, fold column sumiInk4 = "#54546D" # darker foreground, e.g. linenumbers, fold column
sumiInk5 = "#363646" # current selection
waveBlue1 = "#223249" # popup background, visual selection background waveBlue1 = "#223249" # popup background, visual selection background
waveBlue2 = "#2D4F67" # popup selection background, search background waveBlue2 = "#2D4F67" # popup selection background, search background
winterGreen = "#2B3328" # diff add background winterGreen = "#2B3328" # diff add background

@ -79,6 +79,7 @@
"ui.text.focus" = { fg = "fg" } "ui.text.focus" = { fg = "fg" }
"ui.virtual" = { fg = "gray02" } "ui.virtual" = { fg = "gray02" }
"ui.virtual.ruler" = { bg ="gray02" }
"ui.virtual.indent-guide" = { fg = "gray02" } "ui.virtual.indent-guide" = { fg = "gray02" }
"ui.virtual.inlay-hint" = { fg = "gray04" } "ui.virtual.inlay-hint" = { fg = "gray04" }

@ -58,6 +58,7 @@ string = { fg = "brightMint" }
"ui.text.inactive" = "darkerGray" "ui.text.inactive" = "darkerGray"
"ui.virtual" = { fg = "darkerGray.b0" } "ui.virtual" = { fg = "darkerGray.b0" }
"ui.virtual.indent-guide" = "#303442" "ui.virtual.indent-guide" = "#303442"
"ui.virtual.ruler" = { bg ="selection" }
"ui.selection" = { bg = "focus" } "ui.selection" = { bg = "focus" }
"ui.selection.primary" = { bg = "selection" } "ui.selection.primary" = { bg = "selection" }

@ -90,7 +90,7 @@
"ui.selection.primary" = { bg = "base015" } "ui.selection.primary" = { bg = "base015" }
"ui.virtual.indent-guide" = { fg = "base02" } "ui.virtual.indent-guide" = { fg = "base02" }
"ui.virtual.ruler" = { fg = "red" } "ui.virtual.ruler" = { bg = "base02" }
# normal模式的光标 # normal模式的光标
"ui.cursor" = {fg = "base02", bg = "cyan"} "ui.cursor" = {fg = "base02", bg = "cyan"}

@ -91,9 +91,6 @@
# 影响 picker列表选中, 快捷键帮助窗口文本 # 影响 picker列表选中, 快捷键帮助窗口文本
# Affects picker list selection, shortcut key help window text # Affects picker list selection, shortcut key help window text
"ui.text.focus" = { fg = "blue", modifiers = ["bold"]} "ui.text.focus" = { fg = "blue", modifiers = ["bold"]}
# file picker中 预览的当前选中项
# In file picker, the currently selected item of the preview
"ui.highlight" = { fg = "red", modifiers = ["bold", "italic", "underlined"] }
# 主光标/selection # 主光标/selection
# main cursor/selection # main cursor/selection
@ -107,7 +104,7 @@
"ui.selection.primary" = { bg = "base015" } "ui.selection.primary" = { bg = "base015" }
"ui.virtual.indent-guide" = { fg = "base02" } "ui.virtual.indent-guide" = { fg = "base02" }
"ui.virtual.ruler" = { fg = "red" } "ui.virtual.ruler" = { bg = "base02" }
# normal模式的光标 # normal模式的光标
# normal mode cursor # normal mode cursor

@ -67,6 +67,7 @@
"ui.statusline.select" = { bg = "blue", fg = "bg2" } "ui.statusline.select" = { bg = "blue", fg = "bg2" }
"ui.virtual.wrap" = { fg = "grey0" } "ui.virtual.wrap" = { fg = "grey0" }
"ui.virtual.inlay-hint" = { fg = "grey1" } "ui.virtual.inlay-hint" = { fg = "grey1" }
"ui.virtual.ruler" = { bg = "bg2"}
"hint" = "blue" "hint" = "blue"
"info" = "aqua" "info" = "aqua"

@ -1,7 +1,10 @@
"ui.background" = { bg = "black" } "ui.background" = { bg = "black" }
"ui.bufferline" = { bg = "black" }
"ui.bufferline.active" = { fg = "light-magenta", bg = "dark-magenta" }
"ui.cursor" = { fg = "green", modifiers = ["reversed"] } "ui.cursor" = { fg = "green", modifiers = ["reversed"] }
"ui.cursor.match" = { fg = "light-cyan", bg = "dark-cyan" } "ui.cursor.match" = { fg = "light-cyan", bg = "dark-cyan" }
"ui.cursor.primary" = { fg = "light-green", modifiers = ["reversed"] } "ui.cursor.primary" = { fg = "light-green", modifiers = ["reversed"] }
"ui.cursorline.primary" = { bg = "gray" }
"ui.menu" = { bg = "dark-white" } "ui.menu" = { bg = "dark-white" }
"ui.menu.selected" = { fg = "yellow" } "ui.menu.selected" = { fg = "yellow" }
"ui.popup" = { bg = "dark-white" } "ui.popup" = { bg = "dark-white" }
@ -15,6 +18,7 @@
"ui.text.focus" = { fg = "yellow" } "ui.text.focus" = { fg = "yellow" }
"ui.virtual.wrap" = { fg = "dark-blue" } "ui.virtual.wrap" = { fg = "dark-blue" }
"ui.virtual.indent-guide" = { fg = "dark-blue" } "ui.virtual.indent-guide" = { fg = "dark-blue" }
"ui.virtual.ruler" = { bg = "dark-white" }
"ui.window" = { bg = "dark-white" } "ui.window" = { bg = "dark-white" }
"diagnostic.error" = { bg = "dark-red" } "diagnostic.error" = { bg = "dark-red" }
@ -50,6 +54,7 @@
black = "#000000" black = "#000000"
red = "#ed5f74" red = "#ed5f74"
green = "#1ea672" green = "#1ea672"
gray = "#111111"
yellow = "#d97917" yellow = "#d97917"
blue = "#688ef1" blue = "#688ef1"
magenta = "#c96ed0" magenta = "#c96ed0"

@ -539,7 +539,7 @@
will now affect both cursors. will now affect both cursors.
3. Use Insert mode to correct the lines. The two cursors will 3. Use Insert mode to correct the lines. The two cursors will
fix both lines simultaneously. fix both lines simultaneously.
4. Type , to remove the second cursor. 4. Type , to remove the first cursor.
--> Fix th two nes at same ime. --> Fix th two nes at same ime.
--> -->

@ -40,7 +40,7 @@ label = "honey"
"diff.minus" = "#f22c86" "diff.minus" = "#f22c86"
"diff.delta" = "#6f44f0" "diff.delta" = "#6f44f0"
# TODO: diferentiate doc comment # TODO: differentiate doc comment
# concat (ERROR) @error.syntax and "MISSING ;" selectors for errors # concat (ERROR) @error.syntax and "MISSING ;" selectors for errors
"ui.background" = { bg = "midnight" } "ui.background" = { bg = "midnight" }
@ -56,6 +56,7 @@ label = "honey"
"ui.text.focus" = { fg = "white" } "ui.text.focus" = { fg = "white" }
"ui.text.inactive" = "sirocco" "ui.text.inactive" = "sirocco"
"ui.virtual" = { fg = "comet" } "ui.virtual" = { fg = "comet" }
"ui.virtual.ruler" = { bg = "revolver" }
"ui.virtual.jump-label" = { fg = "apricot", modifiers = ["bold"] } "ui.virtual.jump-label" = { fg = "apricot", modifiers = ["bold"] }
"ui.virtual.indent-guide" = { fg = "comet" } "ui.virtual.indent-guide" = { fg = "comet" }

Loading…
Cancel
Save