diff --git a/Cargo.lock b/Cargo.lock index c33e0720e..7ec3332ef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1356,6 +1356,7 @@ dependencies = [ "helix-event", "helix-loader", "helix-lsp", + "helix-parsec", "helix-stdx", "helix-tui", "helix-vcs", diff --git a/helix-term/Cargo.toml b/helix-term/Cargo.toml index c66aa0621..4d2bee853 100644 --- a/helix-term/Cargo.toml +++ b/helix-term/Cargo.toml @@ -31,16 +31,32 @@ helix-lsp = { path = "../helix-lsp" } helix-dap = { path = "../helix-dap" } helix-vcs = { path = "../helix-vcs" } helix-loader = { path = "../helix-loader" } +helix-parsec = { path = "../helix-parsec" } anyhow = "1" once_cell = "1.19" -tokio = { version = "1", features = ["rt", "rt-multi-thread", "io-util", "io-std", "time", "process", "macros", "fs", "parking_lot"] } -tui = { path = "../helix-tui", package = "helix-tui", default-features = false, features = ["crossterm"] } -crossterm = { version = "0.28", features = ["event-stream"] } +tokio = { version = "1", features = [ + "rt", + "rt-multi-thread", + "io-util", + "io-std", + "time", + "process", + "macros", + "fs", + "parking_lot", +] } +tui = { path = "../helix-tui", package = "helix-tui", default-features = false, features = [ + "crossterm", +] } +crossterm = { version = "0.27", features = ["event-stream"] } signal-hook = "0.3" tokio-stream = "0.1" -futures-util = { version = "0.3", features = ["std", "async-await"], default-features = false } +futures-util = { version = "0.3", features = [ + "std", + "async-await", +], default-features = false } arc-swap = { version = "1.7.1" } termini = "1" @@ -53,14 +69,13 @@ log = "0.4" nucleo.workspace = true ignore = "0.4" # markdown doc rendering -pulldown-cmark = { version = "0.12", default-features = false } +pulldown-cmark = { version = "0.11", default-features = false } # file type detection content_inspector = "0.2.4" -thiserror = "1.0" # opening URLs -open = "5.3.0" -url = "2.5.2" +open = "5.1.3" +url = "2.5.0" # config toml = "0.8" @@ -69,15 +84,15 @@ serde_json = "1.0" serde = { version = "1.0", features = ["derive"] } # ripgrep for global search -grep-regex = "0.1.13" -grep-searcher = "0.1.14" +grep-regex = "0.1.12" +grep-searcher = "0.1.13" -[target.'cfg(not(windows))'.dependencies] # https://github.com/vorner/signal-hook/issues/100 +[target.'cfg(not(windows))'.dependencies] # https://github.com/vorner/signal-hook/issues/100 signal-hook-tokio = { version = "0.3", features = ["futures-v0_3"] } -libc = "0.2.158" +libc = "0.2.155" [target.'cfg(target_os = "macos")'.dependencies] -crossterm = { version = "0.28", features = ["event-stream", "use-dev-tty", "libc"] } +crossterm = { version = "0.27", features = ["event-stream", "use-dev-tty"] } [build-dependencies] helix-loader = { path = "../helix-loader" } @@ -85,5 +100,4 @@ helix-loader = { path = "../helix-loader" } [dev-dependencies] smallvec = "1.13" indoc = "2.0.5" -tempfile = "3.12.0" -same-file = "1.0.1" +tempfile = "3.10.1" diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 8866ff55d..c3d3cf249 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -5,6 +5,7 @@ pub(crate) mod typed; pub use dap::*; use futures_util::FutureExt; use helix_event::status; +use helix_parsec::{seq, take_until, Parser}; use helix_stdx::{ path::expand_tilde, rope::{self, RopeSliceExt}, @@ -44,9 +45,10 @@ use helix_view::{ info::Info, input::KeyEvent, keyboard::KeyCode, + register::RegisterValues, theme::Style, tree, - view::View, + view::{self, View}, Document, DocumentId, Editor, ViewId, }; @@ -6124,30 +6126,63 @@ fn extend_to_word(cx: &mut Context) { jump_to_word(cx, Movement::Extend) } +fn read_from_register(editor: &mut Editor, reg: char) -> Option { + editor.registers.read(reg, editor) +} + pub fn goto_mark(cx: &mut Context) { let register_name = cx.register.unwrap_or('^').clone(); - let register_content = cx.editor.registers.read(register_name, cx.editor); - let res = match register_content { - Some(values) => values - .into_iter() - .next() - .map(|c| c.into_owned()) - .map(|s| { - let mut split_iter = s.split(":").into_iter(); - let doc_id = split_iter.next().unwrap(); - let range_tupel = split_iter.next().unwrap(); - log::debug!("doc id: {:?}", &doc_id); - log::debug!("range_tuple: {:?}", &range_tupel); - }) - .ok_or(format!( - "Register {} did not contain anything", - register_name - )), - None => Err(format!( - "Register {} did not contain anything", - register_name - )), - }; + let registers_vals = read_from_register(&mut cx.editor, register_name); + let blurb = registers_vals + .unwrap() + .into_iter() + .next() + .map(|c| c.into_owned()); + // let register_content = editor.registers.read(register_name, editor); + // let reg_str = match values { + // Some(values) => + // .ok_or(format!( + // "Register {} did not contain anything", + // register_name + // )), + // None => Err(format!( + // "Register {} did not contain anything", + // register_name + // )), + // }; + match blurb { + Some(s) => { + let parser = seq!( + take_until(|c| c == ':'), + ":(", + take_until(|c| c == ','), + ",", + take_until(|c| c == ')'), + ")" + ); + let (_tail, (doc_id_str, _, anchor_str, _, head_str, _)) = parser.parse(&s).unwrap(); + let anchor = anchor_str.parse().unwrap(); + let head = head_str.parse().unwrap(); + let doc_id: DocumentId = doc_id_str.try_into().unwrap(); + let range = Range { + anchor, + head, + old_visual_position: None, + }; + cx.editor.switch(doc_id, Action::Replace); + let (view, doc) = current!(cx.editor); + let (min_idx, max_idx) = if anchor < head { + (anchor, head) + } else { + (head, anchor) + }; + let new_range = range.put_cursor(doc.text().slice(..), min_idx, false); + let new_range = new_range.put_cursor(doc.text().slice(..), max_idx, true); + doc.set_selection(view.id, new_range.into()); + } + None => (), + // Err(e) => log::error!("{}", e), + } // let picker = Picker::new(items, (), |cx, meta, action| { // cx.editor.switch(meta.id, action); // }) diff --git a/helix-view/src/lib.rs b/helix-view/src/lib.rs index d54b49ef5..a18da2517 100644 --- a/helix-view/src/lib.rs +++ b/helix-view/src/lib.rs @@ -18,7 +18,7 @@ pub mod theme; pub mod tree; pub mod view; -use std::num::NonZeroUsize; +use std::num::{NonZeroUsize, ParseIntError}; // uses NonZeroUsize so Option use a byte rather than two #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] @@ -31,6 +31,13 @@ impl Default for DocumentId { } } +impl TryFrom<&str> for DocumentId { + type Error = ParseIntError; + + fn try_from(value: &str) -> Result { + Ok(Self(value.parse::()?)) + } +} impl std::fmt::Display for DocumentId { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_fmt(format_args!("{}", self.0))