From 8cc20a47b013111c3aadbb7d94a682c7e875f4af Mon Sep 17 00:00:00 2001 From: makemeunsee Date: Thu, 26 Oct 2023 20:59:24 +0200 Subject: [PATCH 01/46] helix-core compiles to wasm32 --- Cargo.lock | 34 +++++++++++++++++++++++++++++----- Cargo.toml | 6 ++---- helix-core/Cargo.toml | 14 ++++++++++---- helix-core/src/path.rs | 5 ++++- helix-core/src/syntax.rs | 4 ++-- helix-loader/Cargo.toml | 10 +++++----- helix-loader/src/grammar.rs | 5 +++++ helix-loader/src/lib.rs | 12 ++++++++++++ helix-term/build.rs | 1 + helix-term/src/main.rs | 1 + 10 files changed, 71 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3a88401ed3fa..0579d42d837d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -152,6 +152,26 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +[[package]] +name = "c2rust-bitfields" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb34f0c0ace43530b2df7f18bc69ee0c4082158aa451ece29602f8c841e73764" +dependencies = [ + "c2rust-bitfields-derive", +] + +[[package]] +name = "c2rust-bitfields-derive" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dd1601a7b828ab874d890e5a895563ca8ad485bdd3d2a359f148c8b72537241" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "cassowary" version = "0.3.0" @@ -569,8 +589,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] @@ -1136,7 +1158,7 @@ dependencies = [ "smartstring", "textwrap", "toml", - "tree-sitter", + "tree-sitter-c2rust", "unicode-general-category", "unicode-segmentation", "unicode-width", @@ -1180,7 +1202,7 @@ dependencies = [ "tempfile", "threadpool", "toml", - "tree-sitter", + "tree-sitter-c2rust", "which", ] @@ -2258,11 +2280,13 @@ dependencies = [ ] [[package]] -name = "tree-sitter" +name = "tree-sitter-c2rust" version = "0.20.10" -source = "git+https://github.com/tree-sitter/tree-sitter?rev=ab09ae20d640711174b8da8a654f6b3dec93da1a#ab09ae20d640711174b8da8a654f6b3dec93da1a" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee40a4d9cf5a30c199935f346887588239daceae4d1418d81b789276fffb8d91" dependencies = [ - "cc", + "c2rust-bitfields", + "once_cell", "regex", ] diff --git a/Cargo.toml b/Cargo.toml index 8ffe0fa7ac84..2d08978b1352 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,9 +13,7 @@ members = [ "xtask", ] -default-members = [ - "helix-term" -] +default-members = ["helix-term"] [profile.release] lto = "thin" @@ -35,5 +33,5 @@ package.helix-tui.opt-level = 2 package.helix-term.opt-level = 2 [workspace.dependencies] -tree-sitter = { version = "0.20", git = "https://github.com/tree-sitter/tree-sitter", rev = "ab09ae20d640711174b8da8a654f6b3dec93da1a" } +tree-sitter = { package = "tree-sitter-c2rust", version = "0.20" } nucleo = "0.2.0" diff --git a/helix-core/Cargo.toml b/helix-core/Cargo.toml index f0903f42bc88..8c4e52e374fd 100644 --- a/helix-core/Cargo.toml +++ b/helix-core/Cargo.toml @@ -24,9 +24,9 @@ unicode-segmentation = "1.10" unicode-width = "0.1" unicode-general-category = "0.6" # slab = "0.4.2" -slotmap = "1.0" -tree-sitter.workspace = true +tree-sitter = { package = "tree-sitter-c2rust", version = "0.20" } once_cell = "1.18" +slotmap = "1.0" arc-swap = "1" regex = "1" bitflags = "2.4" @@ -43,14 +43,20 @@ imara-diff = "0.1.0" encoding_rs = "0.8" -chrono = { version = "0.4", default-features = false, features = ["alloc", "std"] } +chrono = { version = "0.4", default-features = false, features = [ + "alloc", + "std", +] } -etcetera = "0.8" textwrap = "0.16.0" nucleo.workspace = true parking_lot = "0.12" + +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +etcetera = "0.8" + [dev-dependencies] quickcheck = { version = "1", default-features = false } indoc = "2.0.4" diff --git a/helix-core/src/path.rs b/helix-core/src/path.rs index ede37e044e05..fd2a60b67ff6 100644 --- a/helix-core/src/path.rs +++ b/helix-core/src/path.rs @@ -1,9 +1,11 @@ +#[cfg(not(target_arch = "wasm32"))] use etcetera::home_dir; use std::path::{Component, Path, PathBuf}; /// Replaces users home directory from `path` with tilde `~` if the directory /// is available, otherwise returns the path unchanged. -pub fn fold_home_dir(path: &Path) -> PathBuf { +fn fold_home_dir(path: &Path) -> PathBuf { + #[cfg(not(target_arch = "wasm32"))] if let Ok(home) = home_dir() { if let Ok(stripped) = path.strip_prefix(&home) { return PathBuf::from("~").join(stripped); @@ -20,6 +22,7 @@ pub fn expand_tilde(path: &Path) -> PathBuf { let mut components = path.components().peekable(); if let Some(Component::Normal(c)) = components.peek() { if c == &"~" { + #[cfg(not(target_arch = "wasm32"))] if let Ok(home) = home_dir() { // it's ok to unwrap, the path starts with `~` return home.join(path.strip_prefix("~").unwrap()); diff --git a/helix-core/src/syntax.rs b/helix-core/src/syntax.rs index 881b45098a9e..97a882249f3f 100644 --- a/helix-core/src/syntax.rs +++ b/helix-core/src/syntax.rs @@ -1614,7 +1614,7 @@ impl<'a> Iterator for ChunksBytes<'a> { } pub struct RopeProvider<'a>(pub RopeSlice<'a>); -impl<'a> TextProvider<&'a [u8]> for RopeProvider<'a> { +impl<'a> TextProvider<'a> for RopeProvider<'a> { type I = ChunksBytes<'a>; fn text(&mut self, node: Node) -> Self::I { @@ -1628,7 +1628,7 @@ impl<'a> TextProvider<&'a [u8]> for RopeProvider<'a> { struct HighlightIterLayer<'a> { _tree: Option, cursor: QueryCursor, - captures: RefCell, &'a [u8]>>>, + captures: RefCell>>>, config: &'a HighlightConfiguration, highlight_end_stack: Vec, scope_stack: Vec>, diff --git a/helix-loader/Cargo.toml b/helix-loader/Cargo.toml index 8e52e9725f77..abeda33fe477 100644 --- a/helix-loader/Cargo.toml +++ b/helix-loader/Cargo.toml @@ -17,19 +17,19 @@ path = "src/main.rs" anyhow = "1" serde = { version = "1.0", features = ["derive"] } toml = "0.7" -etcetera = "0.8" -tree-sitter.workspace = true +tree-sitter = { package = "tree-sitter-c2rust", version = "0.20" } once_cell = "1.18" log = "0.4" -which = "4.4" # TODO: these two should be on !wasm32 only -# cloning/compiling tree-sitter grammars -cc = { version = "1" } threadpool = { version = "1.0" } tempfile = "3.8.0" dunce = "1.0.4" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] libloading = "0.8" +which = "4.4" +etcetera = "0.8" +# cloning/compiling tree-sitter grammars +cc = { version = "1" } diff --git a/helix-loader/src/grammar.rs b/helix-loader/src/grammar.rs index 66111aebb829..8b6a0bfb1fdc 100644 --- a/helix-loader/src/grammar.rs +++ b/helix-loader/src/grammar.rs @@ -85,6 +85,7 @@ pub fn get_language(name: &str) -> Result { Ok(language) } +#[cfg(not(target_arch = "wasm32"))] fn ensure_git_is_available() -> Result<()> { match which::which("git") { Ok(_cmd) => Ok(()), @@ -92,6 +93,7 @@ fn ensure_git_is_available() -> Result<()> { } } +#[cfg(not(target_arch = "wasm32"))] pub fn fetch_grammars() -> Result<()> { ensure_git_is_available()?; @@ -153,6 +155,7 @@ pub fn fetch_grammars() -> Result<()> { Ok(()) } +#[cfg(not(target_arch = "wasm32"))] pub fn build_grammars(target: Option) -> Result<()> { ensure_git_is_available()?; @@ -348,6 +351,7 @@ enum BuildStatus { Built, } +#[cfg(not(target_arch = "wasm32"))] fn build_grammar(grammar: GrammarConfiguration, target: Option<&str>) -> Result { let grammar_dir = if let GrammarSource::Local { path } = &grammar.source { PathBuf::from(&path) @@ -386,6 +390,7 @@ fn build_grammar(grammar: GrammarConfiguration, target: Option<&str>) -> Result< build_tree_sitter_library(&path, grammar, target) } +#[cfg(not(target_arch = "wasm32"))] fn build_tree_sitter_library( src_path: &Path, grammar: GrammarConfiguration, diff --git a/helix-loader/src/lib.rs b/helix-loader/src/lib.rs index 5337d6027877..031efd3dd267 100644 --- a/helix-loader/src/lib.rs +++ b/helix-loader/src/lib.rs @@ -1,6 +1,7 @@ pub mod config; pub mod grammar; +#[cfg(not(target_arch = "wasm32"))] use etcetera::base_strategy::{choose_base_strategy, BaseStrategy}; use std::path::{Path, PathBuf}; use std::sync::RwLock; @@ -140,7 +141,17 @@ pub fn runtime_file(rel_path: &Path) -> PathBuf { .unwrap_or_default() }) } +#[cfg(target_arch = "wasm32")] +pub fn config_dir() -> PathBuf { + todo!() +} + +#[cfg(target_arch = "wasm32")] +pub fn cache_dir() -> PathBuf { + todo!() +} +#[cfg(not(target_arch = "wasm32"))] pub fn config_dir() -> PathBuf { // TODO: allow env var override let strategy = choose_base_strategy().expect("Unable to find the config directory!"); @@ -149,6 +160,7 @@ pub fn config_dir() -> PathBuf { path } +#[cfg(not(target_arch = "wasm32"))] pub fn cache_dir() -> PathBuf { // TODO: allow env var override let strategy = choose_base_strategy().expect("Unable to find the config directory!"); diff --git a/helix-term/build.rs b/helix-term/build.rs index b47dae8ef653..e1b71a435823 100644 --- a/helix-term/build.rs +++ b/helix-term/build.rs @@ -1,6 +1,7 @@ use helix_loader::grammar::{build_grammars, fetch_grammars}; fn main() { + #[cfg(not(target_arch = "wasm32"))] if std::env::var("HELIX_DISABLE_AUTO_GRAMMAR_BUILD").is_err() { fetch_grammars().expect("Failed to fetch tree-sitter grammars"); build_grammars(Some(std::env::var("TARGET").unwrap())) diff --git a/helix-term/src/main.rs b/helix-term/src/main.rs index 6411a7c5f00c..0106f2c9c669 100644 --- a/helix-term/src/main.rs +++ b/helix-term/src/main.rs @@ -109,6 +109,7 @@ FLAGS: return Ok(0); } + #[cfg(not(target_arch = "wasm32"))] if args.build_grammars { helix_loader::grammar::build_grammars(None)?; return Ok(0); From a42389ed3d9c621c5d1022ba8a9b8f84ac2a42f0 Mon Sep 17 00:00:00 2001 From: makemeunsee Date: Thu, 26 Oct 2023 20:59:24 +0200 Subject: [PATCH 02/46] wip helix view wasm32 --- Cargo.lock | 1 + helix-core/Cargo.toml | 1 + helix-term/src/commands/typed.rs | 6 ++++++ helix-view/Cargo.toml | 2 ++ helix-view/src/document.rs | 2 ++ helix-view/src/editor.rs | 2 +- helix-view/src/env.rs | 1 + helix-view/src/gutter.rs | 1 + 8 files changed, 15 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 0579d42d837d..9fe3a6ec5774 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1140,6 +1140,7 @@ dependencies = [ "dunce", "encoding_rs", "etcetera", + "getrandom", "hashbrown 0.14.2", "helix-loader", "imara-diff", diff --git a/helix-core/Cargo.toml b/helix-core/Cargo.toml index 8c4e52e374fd..4438a05546cd 100644 --- a/helix-core/Cargo.toml +++ b/helix-core/Cargo.toml @@ -31,6 +31,7 @@ arc-swap = "1" regex = "1" bitflags = "2.4" ahash = "0.8.5" +getrandom = { version = "*", features = ["js"] } hashbrown = { version = "0.14.2", features = ["raw"] } dunce = "1.0" diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index abe6dd97ec89..4e493fcd966b 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -339,6 +339,9 @@ fn write_impl( insert_final_newline(doc, view); } + #[cfg(target_arch = "wasm32")] + let fmt = None; + #[cfg(not(target_arch = "wasm32"))] let fmt = if config.auto_format { doc.auto_format().map(|fmt| { let callback = make_format_callback( @@ -717,6 +720,9 @@ pub fn write_all_impl( insert_final_newline(doc, view_mut!(cx.editor, target_view)); } + #[cfg(target_arch = "wasm32")] + let fmt = None; + #[cfg(not(target_arch = "wasm32"))] let fmt = if config.auto_format { doc.auto_format().map(|fmt| { let callback = make_format_callback( diff --git a/helix-view/Cargo.toml b/helix-view/Cargo.toml index 6218e9e41f50..477370498fa1 100644 --- a/helix-view/Cargo.toml +++ b/helix-view/Cargo.toml @@ -46,6 +46,8 @@ log = "~0.4" which = "4.4" parking_lot = "0.12.1" +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +which = "4.4" [target.'cfg(windows)'.dependencies] clipboard-win = { version = "4.5", features = ["std"] } diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs index bb61eaa6aae6..d1675e16073f 100644 --- a/helix-view/src/document.rs +++ b/helix-view/src/document.rs @@ -718,6 +718,7 @@ impl Document { Ok(doc) } + #[cfg(not(target_arch = "wasm32"))] /// The same as [`format`], but only returns formatting changes if auto-formatting /// is configured. pub fn auto_format(&self) -> Option>> { @@ -728,6 +729,7 @@ impl Document { } } + #[cfg(not(target_arch = "wasm32"))] /// If supported, returns the changes that should be applied to this document in order /// to format it nicely. // We can't use anyhow::Result here since the output of the future has to be diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index 7af28ccc680a..1b8d6bbd7b5b 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -341,7 +341,7 @@ pub fn get_terminal_provider() -> Option { }) } -#[cfg(not(any(windows, target_os = "wasm32")))] +#[cfg(not(any(windows, target_arch = "wasm32")))] pub fn get_terminal_provider() -> Option { use crate::env::{binary_exists, env_var_is_set}; diff --git a/helix-view/src/env.rs b/helix-view/src/env.rs index c68cc609a3b0..43e6f50d9120 100644 --- a/helix-view/src/env.rs +++ b/helix-view/src/env.rs @@ -1,3 +1,4 @@ +#[cfg(not(target_arch = "wasm32"))] pub fn binary_exists(binary_name: &str) -> bool { which::which(binary_name).is_ok() } diff --git a/helix-view/src/gutter.rs b/helix-view/src/gutter.rs index 397dff4f4782..8fa93d5666ef 100644 --- a/helix-view/src/gutter.rs +++ b/helix-view/src/gutter.rs @@ -46,6 +46,7 @@ impl GutterType { } } +#[cfg(not(target_arch = "wasm32"))] pub fn diagnostic<'doc>( _editor: &'doc Editor, doc: &'doc Document, From ea954e3282183da62de0a392e313520e76b7edeb Mon Sep 17 00:00:00 2001 From: makemeunsee Date: Thu, 26 Oct 2023 20:59:25 +0200 Subject: [PATCH 03/46] horrible feature gating --- Cargo.lock | 3 ++ helix-core/Cargo.toml | 2 + helix-lsp/Cargo.toml | 18 ++++++- helix-term/Cargo.toml | 31 +++++++++--- helix-term/src/application.rs | 11 ++++- helix-term/src/commands.rs | 70 ++++++++++++++++++++++++--- helix-term/src/commands/typed.rs | 29 +++++++++--- helix-term/src/compositor.rs | 6 ++- helix-term/src/keymap.rs | 2 +- helix-term/src/keymap/default.rs | 81 ++++++++++++++++---------------- helix-term/src/ui/completion.rs | 2 +- helix-term/src/ui/editor.rs | 26 +++++++++- helix-term/src/ui/mod.rs | 3 ++ helix-term/src/ui/statusline.rs | 7 +++ helix-view/Cargo.toml | 25 ++++++++-- helix-view/src/document.rs | 33 +++++++++---- helix-view/src/editor.rs | 62 +++++++++++++++++++----- helix-view/src/gutter.rs | 37 +++++++++++---- helix-view/src/handlers/dap.rs | 3 +- helix-view/src/lib.rs | 1 + helix-view/src/view.rs | 35 ++++++++++---- 21 files changed, 370 insertions(+), 117 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9fe3a6ec5774..ae3917e7fbf7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1158,6 +1158,7 @@ dependencies = [ "smallvec", "smartstring", "textwrap", + "thiserror", "toml", "tree-sitter-c2rust", "unicode-general-category", @@ -1243,6 +1244,7 @@ dependencies = [ "content_inspector", "crossterm", "fern", + "futures-executor", "futures-util", "grep-regex", "grep-searcher", @@ -1315,6 +1317,7 @@ dependencies = [ "chardetng", "clipboard-win", "crossterm", + "futures-executor", "futures-util", "helix-core", "helix-dap", diff --git a/helix-core/Cargo.toml b/helix-core/Cargo.toml index 4438a05546cd..84b57e8aa04e 100644 --- a/helix-core/Cargo.toml +++ b/helix-core/Cargo.toml @@ -54,6 +54,8 @@ textwrap = "0.16.0" nucleo.workspace = true parking_lot = "0.12" +thiserror = "1.0" + [target.'cfg(not(target_arch = "wasm32"))'.dependencies] etcetera = "0.8" diff --git a/helix-lsp/Cargo.toml b/helix-lsp/Cargo.toml index 0b181a845474..eda4e391520d 100644 --- a/helix-lsp/Cargo.toml +++ b/helix-lsp/Cargo.toml @@ -18,14 +18,28 @@ helix-parsec = { version = "0.6", path = "../helix-parsec" } anyhow = "1.0" futures-executor = "0.3" -futures-util = { version = "0.3", features = ["std", "async-await"], default-features = false } +futures-util = { version = "0.3", features = [ + "std", + "async-await", +], default-features = false } globset = "0.4.13" log = "0.4" lsp-types = { version = "0.94" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" thiserror = "1.0" -tokio = { version = "1.33", features = ["rt", "rt-multi-thread", "io-util", "io-std", "time", "process", "macros", "fs", "parking_lot", "sync"] } +tokio = { version = "1.33", features = [ + "rt", + "rt-multi-thread", + "io-util", + "io-std", + "time", + "process", + "macros", + "fs", + "parking_lot", + "sync", +] } tokio-stream = "0.1.14" which = "4.4" parking_lot = "0.12.1" diff --git a/helix-term/Cargo.toml b/helix-term/Cargo.toml index 72ddf360caed..259345612eee 100644 --- a/helix-term/Cargo.toml +++ b/helix-term/Cargo.toml @@ -13,7 +13,8 @@ default-run = "hx" rust-version = "1.65" [features] -default = ["git"] +default = ["git"] #, "dap_lsp"] +dap_lsp = ["dep:helix-lsp", "dep:helix-dap"] unicode-lines = ["helix-core/unicode-lines"] integration = [] git = ["helix-vcs/git"] @@ -26,22 +27,38 @@ path = "src/main.rs" helix-core = { version = "0.6", path = "../helix-core" } helix-event = { version = "0.6", path = "../helix-event" } helix-view = { version = "0.6", path = "../helix-view" } -helix-lsp = { version = "0.6", path = "../helix-lsp" } -helix-dap = { version = "0.6", path = "../helix-dap" } +helix-lsp = { version = "0.6", path = "../helix-lsp", optional = true } +helix-dap = { version = "0.6", path = "../helix-dap", optional = true } helix-vcs = { version = "0.6", path = "../helix-vcs" } helix-loader = { version = "0.6", path = "../helix-loader" } +futures-executor = "0.3" anyhow = "1" once_cell = "1.18" which = "4.4" -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"] } +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.6.0" } # Logging @@ -67,7 +84,7 @@ serde = { version = "1.0", features = ["derive"] } grep-regex = "0.1.11" grep-searcher = "0.1.11" -[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.149" diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs index 43e1cdfc9eb0..5a3c35bdf8dc 100644 --- a/helix-term/src/application.rs +++ b/helix-term/src/application.rs @@ -5,6 +5,7 @@ use helix_core::{ path::get_relative_path, pos_at_coords, syntax, Selection, }; +#[cfg(feature = "dap_lsp")] use helix_lsp::{ lsp::{self, notification::Notification}, util::lsp_pos_to_pos, @@ -22,9 +23,10 @@ use helix_view::{ use serde_json::json; use tui::backend::Backend; +#[cfg(feature = "dap_lsp")] +use crate::commands::apply_workspace_edit; use crate::{ args::Args, - commands::apply_workspace_edit, compositor::{Compositor, Event}, config::Config, job::Jobs, @@ -73,6 +75,7 @@ pub struct Application { signals: Signals, jobs: Jobs, + #[cfg(feature = "dap_lsp")] lsp_progress: LspProgressMap, } @@ -243,6 +246,7 @@ impl Application { signals, jobs: Jobs::new(), + #[cfg(feature = "dap_lsp")] lsp_progress: LspProgressMap::new(), }; @@ -558,6 +562,7 @@ impl Application { let doc = doc_mut!(self.editor, &doc_save_event.doc_id); let id = doc.id(); doc.detect_language(loader); + #[cfg(feature = "dap_lsp")] self.editor.refresh_language_servers(id); } @@ -583,11 +588,13 @@ impl Application { self.handle_config_events(event); self.render().await; } + #[cfg(feature = "dap_lsp")] EditorEvent::LanguageServerMessage((id, call)) => { self.handle_language_server_message(call, id).await; // limit render calls for fast language server messages helix_event::request_redraw(); } + #[cfg(feature = "dap_lsp")] EditorEvent::DebuggerEvent(payload) => { let needs_render = self.editor.handle_debugger_message(payload).await; if needs_render { @@ -644,6 +651,7 @@ impl Application { } } + #[cfg(feature = "dap_lsp")] pub async fn handle_language_server_message( &mut self, call: helix_lsp::Call, @@ -1200,6 +1208,7 @@ impl Application { errs.push(err); } + #[cfg(feature = "dap_lsp")] if self.editor.close_language_servers(None).await.is_err() { log::error!("Timed out waiting for language servers to shutdown"); errs.push(anyhow::format_err!( diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 75df430a3eb1..238d4c5c75a3 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -1,9 +1,13 @@ +#[cfg(feature = "dap_lsp")] pub(crate) mod dap; +#[cfg(feature = "dap_lsp")] pub(crate) mod lsp; pub(crate) mod typed; +#[cfg(feature = "dap_lsp")] pub use dap::*; use helix_vcs::Hunk; +#[cfg(feature = "dap_lsp")] pub use lsp::*; use tokio::sync::oneshot; use tui::widgets::Row; @@ -46,6 +50,8 @@ use anyhow::{anyhow, bail, ensure, Context as _}; use insert::*; use movement::Movement; +#[cfg(feature = "dap_lsp")] +use crate::ui::CompletionItem; use crate::{ args, compositor::{self, Component, Compositor}, @@ -53,8 +59,8 @@ use crate::{ job::Callback, keymap::ReverseKeymap, ui::{ - self, editor::InsertEvent, lsp::SignatureHelp, overlay::overlaid, CompletionItem, Picker, - Popup, Prompt, PromptEvent, + self, editor::InsertEvent, lsp::SignatureHelp, overlay::overlaid, Picker, Popup, Prompt, + PromptEvent, }, }; @@ -110,6 +116,7 @@ impl<'a> Context<'a> { self.on_next_key_callback = Some(Box::new(on_next_key_callback)); } + #[cfg(feature = "dap_lsp")] #[inline] pub fn callback( &mut self, @@ -129,6 +136,7 @@ impl<'a> Context<'a> { } } +#[cfg(feature = "dap_lsp")] #[inline] fn make_job_callback( call: impl Future> + 'static + Send, @@ -170,8 +178,9 @@ pub enum MappableCommand { } macro_rules! static_commands { - ( $($name:ident, $doc:literal,)* ) => { + ( $($(#[cfg($attr:meta)])? $name:ident, $doc:literal,)* ) => { $( + $(#[cfg($attr)])? #[allow(non_upper_case_globals)] pub const $name: Self = Self::Static { name: stringify!($name), @@ -181,7 +190,7 @@ macro_rules! static_commands { )* pub const STATIC_COMMAND_LIST: &'static [Self] = &[ - $( Self::$name, )* + $( $(#[cfg($attr)])? Self::$name, )* ]; } } @@ -307,13 +316,19 @@ impl MappableCommand { file_picker, "Open file picker", file_picker_in_current_buffer_directory, "Open file picker at current buffers's directory", file_picker_in_current_directory, "Open file picker at current working directory", + #[cfg(feature = "dap_lsp")] code_action, "Perform code action", buffer_picker, "Open buffer picker", jumplist_picker, "Open jumplist picker", + #[cfg(feature = "dap_lsp")] symbol_picker, "Open symbol picker", + #[cfg(feature = "dap_lsp")] select_references_to_symbol_under_cursor, "Select symbol references", + #[cfg(feature = "dap_lsp")] workspace_symbol_picker, "Open workspace symbol picker", + #[cfg(feature = "dap_lsp")] diagnostics_picker, "Open diagnostic picker", + #[cfg(feature = "dap_lsp")] workspace_diagnostics_picker, "Open workspace diagnostic picker", last_picker, "Open last picker", insert_at_line_start, "Insert at start of line", @@ -323,17 +338,22 @@ impl MappableCommand { normal_mode, "Enter normal mode", select_mode, "Enter selection extend mode", exit_select_mode, "Exit selection mode", + #[cfg(feature = "dap_lsp")] goto_definition, "Goto definition", + #[cfg(feature = "dap_lsp")] goto_declaration, "Goto declaration", add_newline_above, "Add newline above", add_newline_below, "Add newline below", + #[cfg(feature = "dap_lsp")] goto_type_definition, "Goto type definition", + #[cfg(feature = "dap_lsp")] goto_implementation, "Goto implementation", goto_file_start, "Goto line number else file start", goto_file_end, "Goto file end", goto_file, "Goto files in selection", goto_file_hsplit, "Goto files in selection (hsplit)", goto_file_vsplit, "Goto files in selection (vsplit)", + #[cfg(feature = "dap_lsp")] goto_reference, "Goto references", goto_window_top, "Goto window top", goto_window_center, "Goto window center", @@ -343,9 +363,13 @@ impl MappableCommand { goto_last_modification, "Goto last modification", goto_line, "Goto line", goto_last_line, "Goto last line", + #[cfg(feature = "dap_lsp")] goto_first_diag, "Goto first diagnostic", + #[cfg(feature = "dap_lsp")] goto_last_diag, "Goto last diagnostic", + #[cfg(feature = "dap_lsp")] goto_next_diag, "Goto next diagnostic", + #[cfg(feature = "dap_lsp")] goto_prev_diag, "Goto previous diagnostic", goto_next_change, "Goto next change", goto_prev_change, "Goto previous change", @@ -362,6 +386,7 @@ impl MappableCommand { extend_to_first_nonwhitespace, "Extend to first non-blank in line", extend_to_line_end, "Extend to line end", extend_to_line_end_newline, "Extend to line end", + #[cfg(feature = "dap_lsp")] signature_help, "Show signature help", smart_tab, "Insert tab if all cursors have all whitespace to their left; otherwise, run a separate command.", insert_tab, "Insert tab char", @@ -396,6 +421,7 @@ impl MappableCommand { paste_primary_clipboard_before, "Paste primary clipboard before selections", indent, "Indent selection", unindent, "Unindent selection", + #[cfg(feature = "dap_lsp")] format_selections, "Format selection", join_selections, "Join lines inside selection", join_selections_space, "Join lines inside selection and select spaces", @@ -404,7 +430,9 @@ impl MappableCommand { align_selections, "Align selections in column", keep_primary_selection, "Keep primary selection", remove_primary_selection, "Remove primary selection", + #[cfg(feature = "dap_lsp")] completion, "Invoke completion popup", + #[cfg(feature = "dap_lsp")] hover, "Show docs for item under cursor", toggle_comments, "Comment/uncomment selections", rotate_selections_forward, "Rotate selections forward", @@ -462,21 +490,37 @@ impl MappableCommand { goto_prev_test, "Goto previous test", goto_next_paragraph, "Goto next paragraph", goto_prev_paragraph, "Goto previous paragraph", + #[cfg(feature = "dap_lsp")] dap_launch, "Launch debug target", + #[cfg(feature = "dap_lsp")] dap_restart, "Restart debugging session", + #[cfg(feature = "dap_lsp")] dap_toggle_breakpoint, "Toggle breakpoint", + #[cfg(feature = "dap_lsp")] dap_continue, "Continue program execution", + #[cfg(feature = "dap_lsp")] dap_pause, "Pause program execution", + #[cfg(feature = "dap_lsp")] dap_step_in, "Step in", + #[cfg(feature = "dap_lsp")] dap_step_out, "Step out", + #[cfg(feature = "dap_lsp")] dap_next, "Step to next", + #[cfg(feature = "dap_lsp")] dap_variables, "List variables", + #[cfg(feature = "dap_lsp")] dap_terminate, "End debug session", + #[cfg(feature = "dap_lsp")] dap_edit_condition, "Edit breakpoint condition on current line", + #[cfg(feature = "dap_lsp")] dap_edit_log, "Edit breakpoint log message on current line", + #[cfg(feature = "dap_lsp")] dap_switch_thread, "Switch current thread", + #[cfg(feature = "dap_lsp")] dap_switch_stack_frame, "Switch stack frame", + #[cfg(feature = "dap_lsp")] dap_enable_exceptions, "Enable exception breakpoints", + #[cfg(feature = "dap_lsp")] dap_disable_exceptions, "Disable exception breakpoints", shell_pipe, "Pipe selections through shell command", shell_pipe_to, "Pipe selections into shell command ignoring output", @@ -484,6 +528,7 @@ impl MappableCommand { shell_append_output, "Append shell command output after selections", shell_keep_pipe, "Filter selections with shell predicate", suspend, "Suspend and return to shell", + #[cfg(feature = "dap_lsp")] rename_symbol, "Rename symbol", increment, "Increment item under cursor", decrement, "Decrement item under cursor", @@ -2538,6 +2583,7 @@ fn delete_by_selection_insert_mode( ); } doc.apply(&transaction, view.id); + #[cfg(feature = "dap_lsp")] lsp::signature_help_impl(cx, SignatureHelpInvoked::Automatic); } @@ -3278,6 +3324,7 @@ fn exit_select_mode(cx: &mut Context) { } } +#[cfg(feature = "dap_lsp")] fn goto_first_diag(cx: &mut Context) { let (view, doc) = current!(cx.editor); let selection = match doc.shown_diagnostics().next() { @@ -3287,6 +3334,7 @@ fn goto_first_diag(cx: &mut Context) { doc.set_selection(view.id, selection); } +#[cfg(feature = "dap_lsp")] fn goto_last_diag(cx: &mut Context) { let (view, doc) = current!(cx.editor); let selection = match doc.shown_diagnostics().last() { @@ -3296,6 +3344,7 @@ fn goto_last_diag(cx: &mut Context) { doc.set_selection(view.id, selection); } +#[cfg(feature = "dap_lsp")] fn goto_next_diag(cx: &mut Context) { let (view, doc) = current!(cx.editor); @@ -3316,6 +3365,7 @@ fn goto_next_diag(cx: &mut Context) { doc.set_selection(view.id, selection); } +#[cfg(feature = "dap_lsp")] fn goto_prev_diag(cx: &mut Context) { let (view, doc) = current!(cx.editor); @@ -3453,8 +3503,8 @@ pub mod insert { } } - // It trigger completion when idle timer reaches deadline - // Only trigger completion if the word under cursor is longer than n characters + #[cfg(feature = "dap_lsp")] // It trigger completion when idle timer reaches deadline + // Only trigger completion if the word under cursor is longer than n characters pub fn idle_completion(cx: &mut Context) { let config = cx.editor.config(); let (view, doc) = current!(cx.editor); @@ -3473,6 +3523,7 @@ pub mod insert { super::completion(cx); } + #[cfg(feature = "dap_lsp")] fn language_server_completion(cx: &mut Context, ch: char) { let config = cx.editor.config(); if !config.auto_completion { @@ -3498,6 +3549,7 @@ pub mod insert { } } + #[cfg(feature = "dap_lsp")] fn signature_help(cx: &mut Context, ch: char) { use helix_lsp::lsp; // if ch matches signature_help char, trigger @@ -3564,6 +3616,7 @@ pub mod insert { doc.apply(&t, view.id); } + #[cfg(feature = "dap_lsp")] // TODO: need a post insert hook too for certain triggers (autocomplete, signature help, etc) // this could also generically look at Transaction, but it's a bit annoying to look at // Operation instead of Change. @@ -3794,6 +3847,7 @@ pub mod insert { let (view, doc) = current!(cx.editor); doc.apply(&transaction, view.id); + #[cfg(feature = "dap_lsp")] lsp::signature_help_impl(cx, SignatureHelpInvoked::Automatic); } @@ -4248,6 +4302,7 @@ fn unindent(cx: &mut Context) { doc.apply(&transaction, view.id); } +#[cfg(feature = "dap_lsp")] fn format_selections(cx: &mut Context) { use helix_lsp::{lsp, util::range_to_lsp_range}; @@ -4430,6 +4485,7 @@ fn remove_primary_selection(cx: &mut Context) { doc.set_selection(view.id, selection); } +#[cfg(feature = "dap_lsp")] pub fn completion(cx: &mut Context) { use helix_lsp::{lsp, util::pos_to_lsp_pos}; @@ -5403,7 +5459,7 @@ fn shell_keep_pipe(cx: &mut Context) { } fn shell_impl(shell: &[String], cmd: &str, input: Option) -> anyhow::Result<(Tendril, bool)> { - tokio::task::block_in_place(|| helix_lsp::block_on(shell_impl_async(shell, cmd, input))) + tokio::task::block_in_place(|| futures_executor::block_on(shell_impl_async(shell, cmd, input))) } async fn shell_impl_async( diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index 4e493fcd966b..da057258f5e6 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -339,9 +339,7 @@ fn write_impl( insert_final_newline(doc, view); } - #[cfg(target_arch = "wasm32")] - let fmt = None; - #[cfg(not(target_arch = "wasm32"))] + #[cfg(feature = "dap_lsp")] let fmt = if config.auto_format { doc.auto_format().map(|fmt| { let callback = make_format_callback( @@ -357,6 +355,8 @@ fn write_impl( } else { None }; + #[cfg(not(feature = "dap_lsp"))] + let fmt: Option<()> = None; if fmt.is_none() { let id = doc.id(); @@ -444,6 +444,7 @@ fn new_file( Ok(()) } +#[cfg(feature = "dap_lsp")] fn format( cx: &mut compositor::Context, _args: &[Cow], @@ -720,9 +721,7 @@ pub fn write_all_impl( insert_final_newline(doc, view_mut!(cx.editor, target_view)); } - #[cfg(target_arch = "wasm32")] - let fmt = None; - #[cfg(not(target_arch = "wasm32"))] + #[cfg(feature = "dap_lsp")] let fmt = if config.auto_format { doc.auto_format().map(|fmt| { let callback = make_format_callback( @@ -737,6 +736,8 @@ pub fn write_all_impl( } else { None }; + #[cfg(not(feature = "dap_lsp"))] + let fmt: Option<()> = None; if fmt.is_none() { cx.editor.save::(doc_id, None, force)?; @@ -1292,6 +1293,7 @@ fn reload( doc.reload(view, &cx.editor.diff_providers).map(|_| { view.ensure_cursor_in_view(doc, scrolloff); })?; + #[cfg(feature = "dap_lsp")] if let Some(path) = doc.path() { cx.editor .language_servers @@ -1338,6 +1340,7 @@ fn reload_all( view.sync_changes(doc); doc.reload(view, &cx.editor.diff_providers)?; + #[cfg(feature = "dap_lsp")] if let Some(path) = doc.path() { cx.editor .language_servers @@ -1374,6 +1377,7 @@ fn update( } } +#[cfg(feature = "dap_lsp")] fn lsp_workspace_command( cx: &mut compositor::Context, args: &[Cow], @@ -1441,6 +1445,7 @@ fn lsp_workspace_command( Ok(()) } +#[cfg(feature = "dap_lsp")] fn lsp_restart( cx: &mut compositor::Context, _args: &[Cow], @@ -1489,6 +1494,7 @@ fn lsp_restart( Ok(()) } +#[cfg(feature = "dap_lsp")] fn lsp_stop( cx: &mut compositor::Context, _args: &[Cow], @@ -1697,6 +1703,7 @@ fn hsplit_new( Ok(()) } +#[cfg(feature = "dap_lsp")] fn debug_eval( cx: &mut compositor::Context, args: &[Cow], @@ -1723,6 +1730,7 @@ fn debug_eval( Ok(()) } +#[cfg(feature = "dap_lsp")] fn debug_start( cx: &mut compositor::Context, args: &[Cow], @@ -1740,6 +1748,7 @@ fn debug_start( dap_start_impl(cx, name.as_deref(), None, Some(args)) } +#[cfg(feature = "dap_lsp")] fn debug_remote( cx: &mut compositor::Context, args: &[Cow], @@ -2013,6 +2022,7 @@ fn language( doc.detect_indent_and_line_ending(); let id = doc.id(); + #[cfg(feature = "dap_lsp")] cx.editor.refresh_language_servers(id); Ok(()) } @@ -2527,6 +2537,7 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ fun: new_file, signature: CommandSignature::none(), }, + #[cfg(feature = "dap_lsp")] TypableCommand { name: "format", aliases: &["fmt"], @@ -2775,6 +2786,7 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ fun: update, signature: CommandSignature::none(), }, + #[cfg(feature = "dap_lsp")] TypableCommand { name: "lsp-workspace-command", aliases: &[], @@ -2782,6 +2794,7 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ fun: lsp_workspace_command, signature: CommandSignature::positional(&[completers::lsp_workspace_command]), }, + #[cfg(feature = "dap_lsp")] TypableCommand { name: "lsp-restart", aliases: &[], @@ -2789,6 +2802,7 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ fun: lsp_restart, signature: CommandSignature::none(), }, + #[cfg(feature = "dap_lsp")] TypableCommand { name: "lsp-stop", aliases: &[], @@ -2810,6 +2824,7 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ fun: tree_sitter_highlight_name, signature: CommandSignature::none(), }, + #[cfg(feature = "dap_lsp")] TypableCommand { name: "debug-start", aliases: &["dbg"], @@ -2817,6 +2832,7 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ fun: debug_start, signature: CommandSignature::none(), }, + #[cfg(feature = "dap_lsp")] TypableCommand { name: "debug-remote", aliases: &["dbg-tcp"], @@ -2824,6 +2840,7 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ fun: debug_remote, signature: CommandSignature::none(), }, + #[cfg(feature = "dap_lsp")] TypableCommand { name: "debug-eval", aliases: &[], diff --git a/helix-term/src/compositor.rs b/helix-term/src/compositor.rs index 3dcb5f2bfcbc..5fc8d3cddf70 100644 --- a/helix-term/src/compositor.rs +++ b/helix-term/src/compositor.rs @@ -31,8 +31,10 @@ impl<'a> Context<'a> { /// Waits on all pending jobs, and then tries to flush all pending write /// operations for all documents. pub fn block_try_flush_writes(&mut self) -> anyhow::Result<()> { - tokio::task::block_in_place(|| helix_lsp::block_on(self.jobs.finish(self.editor, None)))?; - tokio::task::block_in_place(|| helix_lsp::block_on(self.editor.flush_writes()))?; + tokio::task::block_in_place(|| { + futures_executor::block_on(self.jobs.finish(self.editor, None)) + })?; + tokio::task::block_in_place(|| futures_executor::block_on(self.editor.flush_writes()))?; Ok(()) } } diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs index 598be55b5ff4..28005e03a64e 100644 --- a/helix-term/src/keymap.rs +++ b/helix-term/src/keymap.rs @@ -387,7 +387,7 @@ mod tests { fn duplicate_keys_should_panic() { keymap!({ "Normal mode" "i" => normal_mode, - "i" => goto_definition, + "i" => goto_file, }); } diff --git a/helix-term/src/keymap/default.rs b/helix-term/src/keymap/default.rs index 763ed4ae71ce..eede202813ed 100644 --- a/helix-term/src/keymap/default.rs +++ b/helix-term/src/keymap/default.rs @@ -5,6 +5,7 @@ use super::{KeyTrie, Mode}; use helix_core::hashmap; pub fn default() -> HashMap { + // TODO feature gate somehow let normal = keymap!({ "Normal mode" "h" | "left" => move_char_left, "j" | "down" => move_visual_line_down, @@ -43,11 +44,11 @@ pub fn default() -> HashMap { "h" => goto_line_start, "l" => goto_line_end, "s" => goto_first_nonwhitespace, - "d" => goto_definition, - "D" => goto_declaration, - "y" => goto_type_definition, - "r" => goto_reference, - "i" => goto_implementation, + // "d" => goto_definition, + // "D" => goto_declaration, + // "y" => goto_type_definition, + // "r" => goto_reference, + // "i" => goto_implementation, "t" => goto_window_top, "c" => goto_window_center, "b" => goto_window_bottom, @@ -105,8 +106,8 @@ pub fn default() -> HashMap { "i" => select_textobject_inner, }, "[" => { "Left bracket" - "d" => goto_prev_diag, - "D" => goto_first_diag, + // "d" => goto_prev_diag, + // "D" => goto_first_diag, "g" => goto_prev_change, "G" => goto_first_change, "f" => goto_prev_function, @@ -118,8 +119,8 @@ pub fn default() -> HashMap { "space" => add_newline_above, }, "]" => { "Right bracket" - "d" => goto_next_diag, - "D" => goto_last_diag, + // "d" => goto_next_diag, + // "D" => goto_last_diag, "g" => goto_next_change, "G" => goto_last_change, "f" => goto_next_function, @@ -153,7 +154,7 @@ pub fn default() -> HashMap { ">" => indent, "<" => unindent, - "=" => format_selections, + // "=" => format_selections, "J" => join_selections, "A-J" => join_selections_space, "K" => keep_selections, @@ -218,33 +219,33 @@ pub fn default() -> HashMap { "F" => file_picker_in_current_directory, "b" => buffer_picker, "j" => jumplist_picker, - "s" => symbol_picker, - "S" => workspace_symbol_picker, - "d" => diagnostics_picker, - "D" => workspace_diagnostics_picker, - "a" => code_action, + // "s" => symbol_picker, + // "S" => workspace_symbol_picker, + // "d" => diagnostics_picker, + // "D" => workspace_diagnostics_picker, + // "a" => code_action, "'" => last_picker, - "g" => { "Debug (experimental)" sticky=true - "l" => dap_launch, - "r" => dap_restart, - "b" => dap_toggle_breakpoint, - "c" => dap_continue, - "h" => dap_pause, - "i" => dap_step_in, - "o" => dap_step_out, - "n" => dap_next, - "v" => dap_variables, - "t" => dap_terminate, - "C-c" => dap_edit_condition, - "C-l" => dap_edit_log, - "s" => { "Switch" - "t" => dap_switch_thread, - "f" => dap_switch_stack_frame, - // sl, sb - }, - "e" => dap_enable_exceptions, - "E" => dap_disable_exceptions, - }, + // "g" => { "Debug (experimental)" sticky=true + // "l" => dap_launch, + // "r" => dap_restart, + // "b" => dap_toggle_breakpoint, + // "c" => dap_continue, + // "h" => dap_pause, + // "i" => dap_step_in, + // "o" => dap_step_out, + // "n" => dap_next, + // "v" => dap_variables, + // "t" => dap_terminate, + // "C-c" => dap_edit_condition, + // "C-l" => dap_edit_log, + // "s" => { "Switch" + // "t" => dap_switch_thread, + // "f" => dap_switch_stack_frame, + // // sl, sb + // }, + // "e" => dap_enable_exceptions, + // "E" => dap_disable_exceptions, + // }, "w" => { "Window" "C-w" | "w" => rotate_view, "C-s" | "s" => hsplit, @@ -273,9 +274,9 @@ pub fn default() -> HashMap { "P" => paste_clipboard_before, "R" => replace_selections_with_clipboard, "/" => global_search, - "k" => hover, - "r" => rename_symbol, - "h" => select_references_to_symbol_under_cursor, + // "k" => hover, + // "r" => rename_symbol, + // "h" => select_references_to_symbol_under_cursor, "?" => command_palette, }, "z" => { "View" @@ -363,7 +364,7 @@ pub fn default() -> HashMap { "esc" => normal_mode, "C-s" => commit_undo_checkpoint, - "C-x" => completion, + // "C-x" => completion, "C-r" => insert_register, "C-w" | "A-backspace" => delete_word_backward, diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs index e06147224465..8d2e10a9dfb4 100644 --- a/helix-term/src/ui/completion.rs +++ b/helix-term/src/ui/completion.rs @@ -346,7 +346,7 @@ impl Completion { completion_item: lsp::CompletionItem, ) -> Option { let future = language_server.resolve_completion_item(completion_item)?; - let response = helix_lsp::block_on(future); + let response = futures_executor::block_on(future); match response { Ok(value) => serde_json::from_value(value).ok(), Err(err) => { diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index 31195a4e557a..de5c8f52f4ee 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -1,3 +1,5 @@ +#[cfg(feature = "dap_lsp")] +use crate::ui::Completion; use crate::{ commands::{self, OnKeyCallback}, compositor::{Component, Context, Event, EventResult}, @@ -6,7 +8,7 @@ use crate::{ keymap::{KeymapResult, Keymaps}, ui::{ document::{render_document, LinePos, TextRenderer, TranslatedPosition}, - Completion, ProgressSpinners, + ProgressSpinners, }, }; @@ -33,7 +35,9 @@ use std::{mem::take, num::NonZeroUsize, path::PathBuf, rc::Rc, sync::Arc}; use tui::{buffer::Buffer as Surface, text::Span}; -use super::{completion::CompletionItem, statusline}; +#[cfg(feature = "dap_lsp")] +use super::completion::CompletionItem; +use super::statusline; use super::{document::LineDecoration, lsp::SignatureHelp}; pub struct EditorView { @@ -41,6 +45,7 @@ pub struct EditorView { on_next_key: Option, pseudo_pending: Vec, pub(crate) last_insert: (commands::MappableCommand, Vec), + #[cfg(feature = "dap_lsp")] pub(crate) completion: Option, spinners: ProgressSpinners, /// Tracks if the terminal window is focused by reaction to terminal focus events @@ -71,6 +76,7 @@ impl EditorView { on_next_key: None, pseudo_pending: Vec::new(), last_insert: (commands::MappableCommand::normal_mode, Vec::new()), + #[cfg(feature = "dap_lsp")] completion: None, spinners: ProgressSpinners::default(), terminal_focused: true, @@ -107,6 +113,7 @@ impl EditorView { Self::highlight_cursorcolumn(doc, view, surface, theme, inner, &text_annotations); } + #[cfg(feature = "dap_lsp")] // Set DAP highlights, if needed. if let Some(frame) = editor.current_stack_frame() { let dap_line = frame.line.saturating_sub(1); @@ -658,6 +665,7 @@ impl EditorView { .primary() .cursor(doc.text().slice(..)); + #[cfg(feature = "dap_lsp")] let diagnostics = doc.shown_diagnostics().filter(|diagnostic| { diagnostic.range.start <= cursor && diagnostic.range.end >= cursor }); @@ -669,6 +677,7 @@ impl EditorView { let mut lines = Vec::new(); let background_style = theme.get("ui.background"); + #[cfg(feature = "dap_lsp")] for diagnostic in diagnostics { let style = Style::reset() .patch(background_style) @@ -820,9 +829,11 @@ impl EditorView { self.last_insert.0 = command.clone(); self.last_insert.1.clear(); + #[cfg(feature = "dap_lsp")] commands::signature_help_impl(cxt, commands::SignatureHelpInvoked::Automatic); } (Mode::Insert, Mode::Normal) => { + #[cfg(feature = "dap_lsp")] // if exiting insert mode, remove completion self.clear_completion(cxt.editor); cxt.editor.completion_request_handle = None; @@ -959,6 +970,7 @@ impl EditorView { } } + #[cfg(feature = "dap_lsp")] #[allow(clippy::too_many_arguments)] pub fn set_completion( &mut self, @@ -987,6 +999,7 @@ impl EditorView { Some(area) } + #[cfg(feature = "dap_lsp")] pub fn clear_completion(&mut self, editor: &mut Editor) { self.completion = None; if let Some(last_completion) = editor.last_completion.take() { @@ -1010,8 +1023,10 @@ impl EditorView { } pub fn handle_idle_timeout(&mut self, cx: &mut commands::Context) -> EventResult { + #[cfg(feature = "dap_lsp")] commands::compute_inlay_hints_for_all_views(cx.editor, cx.jobs); + #[cfg(feature = "dap_lsp")] if let Some(completion) = &mut self.completion { return if completion.ensure_item_resolved(cx) { EventResult::Consumed(None) @@ -1024,6 +1039,7 @@ impl EditorView { return EventResult::Ignored(None); } + #[cfg(feature = "dap_lsp")] crate::commands::insert::idle_completion(cx); EventResult::Consumed(None) @@ -1083,6 +1099,7 @@ impl EditorView { doc.set_selection(view_id, Selection::point(pos)); } + #[cfg(feature = "dap_lsp")] if view_id != prev_view_id { self.clear_completion(editor); } @@ -1103,6 +1120,7 @@ impl EditorView { None => return EventResult::Ignored(None), }; + #[cfg(feature = "dap_lsp")] if let Some(char_idx) = view.pos_at_visual_coords(doc, coords.row as u16, coords.col as u16, true) { @@ -1186,6 +1204,7 @@ impl EditorView { view.pos_at_visual_coords(doc, coords.row as u16, coords.col as u16, true) { doc.set_selection(view_id, Selection::point(pos)); + #[cfg(feature = "dap_lsp")] if modifiers == KeyModifiers::ALT { commands::MappableCommand::dap_edit_log.execute(cxt); } else { @@ -1287,6 +1306,7 @@ impl Component for EditorView { Mode::Insert => { // let completion swallow the event if necessary let mut consumed = false; + #[cfg(feature = "dap_lsp")] if let Some(completion) = &mut self.completion { let res = { // use a fake context here @@ -1331,6 +1351,7 @@ impl Component for EditorView { // record last_insert key self.last_insert.1.push(InsertEvent::Key(key)); + #[cfg(feature = "dap_lsp")] // lastly we recalculate completion if let Some(completion) = &mut self.completion { completion.update(&mut cx); @@ -1493,6 +1514,7 @@ impl Component for EditorView { } } + #[cfg(feature = "dap_lsp")] if let Some(completion) = self.completion.as_mut() { completion.render(area, surface, cx); } diff --git a/helix-term/src/ui/mod.rs b/helix-term/src/ui/mod.rs index 660bbfea363d..1d66e6c22579 100644 --- a/helix-term/src/ui/mod.rs +++ b/helix-term/src/ui/mod.rs @@ -1,3 +1,4 @@ +#[cfg(feature = "dap_lsp")] mod completion; mod document; pub(crate) mod editor; @@ -16,6 +17,7 @@ mod text; use crate::compositor::{Component, Compositor}; use crate::filter_picker_entry; use crate::job::{self, Callback}; +#[cfg(feature = "dap_lsp")] pub use completion::{Completion, CompletionItem}; pub use editor::EditorView; pub use markdown::Markdown; @@ -348,6 +350,7 @@ pub mod completers { .collect() } + #[cfg(feature = "dap_lsp")] pub fn lsp_workspace_command(editor: &Editor, input: &str) -> Vec { let Some(options) = doc!(editor) .language_servers_with_feature(LanguageServerFeature::WorkspaceCommand) diff --git a/helix-term/src/ui/statusline.rs b/helix-term/src/ui/statusline.rs index 52dd49f9e212..ca40589aa7cf 100644 --- a/helix-term/src/ui/statusline.rs +++ b/helix-term/src/ui/statusline.rs @@ -1,4 +1,5 @@ use helix_core::{coords_at_pos, encoding, Position}; +#[cfg(feature = "dap_lsp")] use helix_lsp::lsp::DiagnosticSeverity; use helix_view::document::DEFAULT_LANGUAGE_NAME; use helix_view::{ @@ -139,6 +140,7 @@ where { match element_id { helix_view::editor::StatusLineElement::Mode => render_mode, + #[cfg(feature = "dap_lsp")] helix_view::editor::StatusLineElement::Spinner => render_lsp_spinner, helix_view::editor::StatusLineElement::FileBaseName => render_file_base_name, helix_view::editor::StatusLineElement::FileName => render_file_name, @@ -149,7 +151,9 @@ where helix_view::editor::StatusLineElement::FileEncoding => render_file_encoding, helix_view::editor::StatusLineElement::FileLineEnding => render_file_line_ending, helix_view::editor::StatusLineElement::FileType => render_file_type, + #[cfg(feature = "dap_lsp")] helix_view::editor::StatusLineElement::Diagnostics => render_diagnostics, + #[cfg(feature = "dap_lsp")] helix_view::editor::StatusLineElement::WorkspaceDiagnostics => render_workspace_diagnostics, helix_view::editor::StatusLineElement::Selections => render_selections, helix_view::editor::StatusLineElement::PrimarySelectionLength => { @@ -199,6 +203,7 @@ where ); } +#[cfg(feature = "dap_lsp")] // TODO think about handling multiple language servers fn render_lsp_spinner(context: &mut RenderContext, write: F) where @@ -221,6 +226,7 @@ where ); } +#[cfg(feature = "dap_lsp")] fn render_diagnostics(context: &mut RenderContext, write: F) where F: Fn(&mut RenderContext, String, Option