diff --git a/Cargo.toml b/Cargo.toml index 1ee1598209e2..40074b195101 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -resolver = "2" +resolver = "3" members = [ "helix-core", "helix-view", @@ -60,7 +60,7 @@ arc-swap = "1.9" [workspace.package] version = "25.7.1" -edition = "2021" +edition = "2024" authors = ["Blaž Hrastnik "] categories = ["editor"] repository = "https://github.com/helix-editor/helix" diff --git a/helix-core/src/auto_pairs.rs b/helix-core/src/auto_pairs.rs index 5811186cd4c3..c78d12cfb8b7 100644 --- a/helix-core/src/auto_pairs.rs +++ b/helix-core/src/auto_pairs.rs @@ -150,10 +150,11 @@ pub fn hook_delete(doc: &Rope, range: &Range, pairs: &AutoPairs) -> Option<(Dele let second_next = doc.get_char(graphemes::next_grapheme_boundary(text, cursor))?; log::debug!("second_prev: {}, second_next: {}", second_prev, second_next); - if let Some(pair) = pairs.get(second_prev) { - if pair.open == second_prev && pair.close == second_next { - return handle_delete(doc, range); - } + if let Some(pair) = pairs.get(second_prev) + && pair.open == second_prev + && pair.close == second_next + { + return handle_delete(doc, range); } } diff --git a/helix-core/src/doc_formatter.rs b/helix-core/src/doc_formatter.rs index 1c3bfec76a6f..57e1643b242c 100644 --- a/helix-core/src/doc_formatter.rs +++ b/helix-core/src/doc_formatter.rs @@ -239,10 +239,9 @@ impl<'t> DocumentFormatter<'t> { loop { if let Some(&mut (ref mut annotation, highlight)) = self.inline_annotation_graphemes.as_mut() + && let Some(grapheme) = annotation.next() { - if let Some(grapheme) = annotation.next() { - return Some((grapheme, highlight)); - } + return Some((grapheme, highlight)); } if let Some((annotation, highlight)) = diff --git a/helix-core/src/indent.rs b/helix-core/src/indent.rs index f53f060220f0..6390bae4b8cd 100644 --- a/helix-core/src/indent.rs +++ b/helix-core/src/indent.rs @@ -295,10 +295,11 @@ fn add_indent_level( fn is_first_in_line(node: &Node, text: RopeSlice, new_line_byte_pos: Option) -> bool { let line = text.byte_to_line(node.start_byte() as usize); let mut line_start_byte_pos = text.line_to_byte(line) as u32; - if let Some(pos) = new_line_byte_pos { - if line_start_byte_pos < pos && pos <= node.start_byte() { - line_start_byte_pos = pos; - } + if let Some(pos) = new_line_byte_pos + && line_start_byte_pos < pos + && pos <= node.start_byte() + { + line_start_byte_pos = pos; } text.byte_slice(line_start_byte_pos as usize..node.start_byte() as usize) .chars() @@ -1020,67 +1021,65 @@ pub fn indent_for_newline( indent_heuristic, syntax.and_then(|syntax| loader.indent_query(syntax.root_language())), syntax, + ) && let Some(indent) = treesitter_indent_for_pos( + query, + syntax, + tab_width, + indent_width, + text, + line_before, + line_before_end_pos, + true, ) { - if let Some(indent) = treesitter_indent_for_pos( - query, - syntax, - tab_width, - indent_width, - text, - line_before, - line_before_end_pos, - true, - ) { - if *indent_heuristic == IndentationHeuristic::Hybrid { - // We want to compute the indentation not only based on the - // syntax tree but also on the actual indentation of a previous - // line. This makes indentation computation more resilient to - // incomplete queries, incomplete source code & differing indentation - // styles for the same language. - // However, using the indent of a previous line as a baseline may not - // make sense, e.g. if it has a different alignment than the new line. - // In order to prevent edge cases with long running times, we only try - // a constant number of (non-empty) lines. - const MAX_ATTEMPTS: usize = 4; - let mut num_attempts = 0; - for line_idx in (0..=line_before).rev() { - let line = text.line(line_idx); - let first_non_whitespace_char = match line.first_non_whitespace_char() { - Some(i) => i, - None => { - continue; - } - }; - if let Some(indent) = (|| { - let computed_indent = treesitter_indent_for_pos( - query, - syntax, - tab_width, - indent_width, - text, - line_idx, - text.line_to_char(line_idx) + first_non_whitespace_char, - false, - )?; - let leading_whitespace = line.slice(0..first_non_whitespace_char); - indent.relative_indent( - &computed_indent, - leading_whitespace, - indent_style, - tab_width, - ) - })() { - return indent; - } - num_attempts += 1; - if num_attempts == MAX_ATTEMPTS { - break; + if *indent_heuristic == IndentationHeuristic::Hybrid { + // We want to compute the indentation not only based on the + // syntax tree but also on the actual indentation of a previous + // line. This makes indentation computation more resilient to + // incomplete queries, incomplete source code & differing indentation + // styles for the same language. + // However, using the indent of a previous line as a baseline may not + // make sense, e.g. if it has a different alignment than the new line. + // In order to prevent edge cases with long running times, we only try + // a constant number of (non-empty) lines. + const MAX_ATTEMPTS: usize = 4; + let mut num_attempts = 0; + for line_idx in (0..=line_before).rev() { + let line = text.line(line_idx); + let first_non_whitespace_char = match line.first_non_whitespace_char() { + Some(i) => i, + None => { + continue; } + }; + if let Some(indent) = (|| { + let computed_indent = treesitter_indent_for_pos( + query, + syntax, + tab_width, + indent_width, + text, + line_idx, + text.line_to_char(line_idx) + first_non_whitespace_char, + false, + )?; + let leading_whitespace = line.slice(0..first_non_whitespace_char); + indent.relative_indent( + &computed_indent, + leading_whitespace, + indent_style, + tab_width, + ) + })() { + return indent; + } + num_attempts += 1; + if num_attempts == MAX_ATTEMPTS { + break; } } - return indent.to_string(indent_style, tab_width); - }; - } + } + return indent.to_string(indent_style, tab_width); + }; // Fallback in case we either don't have indent queries or they failed for some reason let indent_level = indent_level_for_line(text.line(current_line), tab_width, indent_width); indent_style.as_str().repeat(indent_level) diff --git a/helix-core/src/match_brackets.rs b/helix-core/src/match_brackets.rs index e1e40e0d99a7..e3f0c1739a97 100644 --- a/helix-core/src/match_brackets.rs +++ b/helix-core/src/match_brackets.rs @@ -92,35 +92,34 @@ fn find_pair( if let (Some((start_pos, open)), Some((end_pos, close))) = (as_char(doc, &open), as_char(doc, &close)) + && PAIRS.contains(&(open, close)) + && start_pos <= pos_ + && pos_ <= end_pos { - if PAIRS.contains(&(open, close)) && start_pos <= pos_ && pos_ <= end_pos { - if end_pos == pos_ { - return Some(start_pos); - } - - // We return the end char if the cursor is either on the start char - // or at some arbitrary position between start and end char. - if traverse_parents || start_pos == pos_ { - return Some(end_pos); - } + if end_pos == pos_ { + return Some(start_pos); + } + + // We return the end char if the cursor is either on the start char + // or at some arbitrary position between start and end char. + if traverse_parents || start_pos == pos_ { + return Some(end_pos); } } } // this node itselt wasn't a pair but maybe its siblings are - if let Some((start_char, end_char)) = as_close_pair(doc, &node) { - if let Some(pair_start) = + if let Some((start_char, end_char)) = as_close_pair(doc, &node) + && let Some(pair_start) = find_pair_end(doc, node.prev_sibling(), start_char, end_char, Backward) - { - return Some(pair_start); - } + { + return Some(pair_start); } - if let Some((start_char, end_char)) = as_open_pair(doc, &node) { - if let Some(pair_end) = + if let Some((start_char, end_char)) = as_open_pair(doc, &node) + && let Some(pair_end) = find_pair_end(doc, node.next_sibling(), start_char, end_char, Forward) - { - return Some(pair_end); - } + { + return Some(pair_end); } if traverse_parents { diff --git a/helix-core/src/movement.rs b/helix-core/src/movement.rs index 09a99db2575f..5988c04acc4f 100644 --- a/helix-core/src/movement.rs +++ b/helix-core/src/movement.rs @@ -577,10 +577,10 @@ pub fn goto_treesitter_object( let cap_name = |t: TextObject| format!("{}.{}", object_name, t); let nodes = textobject_query?.capture_nodes_any( - &[ - &cap_name(TextObject::Movement), - &cap_name(TextObject::Around), - &cap_name(TextObject::Inside), + [ + cap_name(TextObject::Movement), + cap_name(TextObject::Around), + cap_name(TextObject::Inside), ], slice_tree, slice, diff --git a/helix-core/src/position.rs b/helix-core/src/position.rs index e70cb94943e0..6792df1767c0 100644 --- a/helix-core/src/position.rs +++ b/helix-core/src/position.rs @@ -230,10 +230,10 @@ pub fn visual_offset_from_anchor( } } - if let Some(anchor_line) = anchor_line { - if grapheme.visual_pos.row >= anchor_line + max_rows { - return Err(VisualOffsetError::PosAfterMaxRow); - } + if let Some(anchor_line) = anchor_line + && grapheme.visual_pos.row >= anchor_line + max_rows + { + return Err(VisualOffsetError::PosAfterMaxRow); } } diff --git a/helix-core/src/snippets/parser.rs b/helix-core/src/snippets/parser.rs index 74e940da8f8d..bbc3ae32269c 100644 --- a/helix-core/src/snippets/parser.rs +++ b/helix-core/src/snippets/parser.rs @@ -119,12 +119,12 @@ fn text<'a>( while let Some((i, c)) = chars.next() { match c { '\\' => { - if let Some(&(_, c)) = chars.peek() { - if escape_chars.contains(&c) { - chars.next(); - res.push(c); - continue; - } + if let Some(&(_, c)) = chars.peek() + && escape_chars.contains(&c) + { + chars.next(); + res.push(c); + continue; } res.push('\\'); } diff --git a/helix-core/src/syntax.rs b/helix-core/src/syntax.rs index f1f0e24adf55..aed84bcf82ec 100644 --- a/helix-core/src/syntax.rs +++ b/helix-core/src/syntax.rs @@ -360,13 +360,13 @@ impl Loader { let mut best_match_length = 0; let mut best_match_position = None; for (idx, data) in self.languages.iter().enumerate() { - if let Some(injection_regex) = &data.config.injection_regex { - if let Some(mat) = injection_regex.find(text.regex_input()) { - let length = mat.end() - mat.start(); - if length > best_match_length { - best_match_position = Some(idx); - best_match_length = length; - } + if let Some(injection_regex) = &data.config.injection_regex + && let Some(mat) = injection_regex.find(text.regex_input()) + { + let length = mat.end() - mat.start(); + if length > best_match_length { + best_match_position = Some(idx); + best_match_length = length; } } } @@ -679,20 +679,17 @@ impl Syntax { }, highlight: Highlight::new((scope_stack.len() % rainbow_length) as u32), }); - } else if capture == rainbow_query.bracket_capture { - if let Some(scope) = scope_stack.last() { - if !scope - .node - .as_ref() - .is_some_and(|node| mat.node.parent().as_ref() != Some(node)) - { - let start = source - .byte_to_char(source.floor_char_boundary(byte_range.start as usize)); - let end = - source.byte_to_char(source.ceil_char_boundary(byte_range.end as usize)); - highlights.push((scope.highlight, start..end)); - } - } + } else if capture == rainbow_query.bracket_capture + && let Some(scope) = scope_stack.last() + && !scope + .node + .as_ref() + .is_some_and(|node| mat.node.parent().as_ref() != Some(node)) + { + let start = + source.byte_to_char(source.floor_char_boundary(byte_range.start as usize)); + let end = source.byte_to_char(source.ceil_char_boundary(byte_range.end as usize)); + highlights.push((scope.highlight, start..end)); } } @@ -1036,20 +1033,20 @@ impl TextObjectQuery { node: &Node<'a>, slice: RopeSlice<'a>, ) -> Option>> { - self.capture_nodes_any(&[capture_name], node, slice) + self.capture_nodes_any(iter::once(capture_name), node, slice) } /// Find the first capture that exists out of all given `capture_names` /// and return sub nodes that match this capture. - pub fn capture_nodes_any<'a>( + pub fn capture_nodes_any<'a, S: AsRef, I: IntoIterator>( &'a self, - capture_names: &[&str], + capture_names: I, node: &Node<'a>, slice: RopeSlice<'a>, ) -> Option>> { let capture = capture_names - .iter() - .find_map(|cap| self.query.get_capture(cap))?; + .into_iter() + .find_map(|cap| self.query.get_capture(cap.as_ref()))?; let mut cursor = InactiveQueryCursor::new(0..u32::MAX, TREE_SITTER_MATCH_LIMIT) .execute_query(&self.query, node, RopeInput::new(slice)); diff --git a/helix-core/src/text_annotations.rs b/helix-core/src/text_annotations.rs index 0f492b8be2e5..fc0ccfb7c69c 100644 --- a/helix-core/src/text_annotations.rs +++ b/helix-core/src/text_annotations.rs @@ -256,7 +256,7 @@ impl RawBox { /// created by this function may exist at a given time. #[allow(clippy::mut_from_ref)] unsafe fn get(&self) -> &mut T { - &mut *self.0.as_ptr() + unsafe { &mut *self.0.as_ptr() } } } impl From> for RawBox { diff --git a/helix-core/tests/indent.rs b/helix-core/tests/indent.rs index 6d4b0c3e50e6..ff258c51bbf7 100644 --- a/helix-core/tests/indent.rs +++ b/helix-core/tests/indent.rs @@ -193,7 +193,7 @@ fn test_treesitter_indent( // set runtime path so we can find the queries let mut runtime = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")); runtime.push("../runtime"); - std::env::set_var("HELIX_RUNTIME", runtime.to_str().unwrap()); + unsafe { std::env::set_var("HELIX_RUNTIME", runtime.to_str().unwrap()) }; let language = loader.language_for_scope(lang_scope).unwrap(); let language_config = loader.language(language).config(); diff --git a/helix-dap/Cargo.toml b/helix-dap/Cargo.toml index 1cf003519dd4..1cbd97cf9400 100644 --- a/helix-dap/Cargo.toml +++ b/helix-dap/Cargo.toml @@ -3,7 +3,7 @@ name = "helix-dap" description = "DAP client implementation for Helix project" version.workspace = true authors.workspace = true -edition.workspace = true +edition = "2021" license.workspace = true rust-version.workspace = true categories.workspace = true diff --git a/helix-event/Cargo.toml b/helix-event/Cargo.toml index 3ad2701d545d..f8ca06396c01 100644 --- a/helix-event/Cargo.toml +++ b/helix-event/Cargo.toml @@ -17,7 +17,7 @@ hashbrown = "0.16" tokio = { version = "1", features = ["rt", "rt-multi-thread", "time", "sync", "parking_lot", "macros"] } # the event registry is essentially read only but must be an rwlock so we can # setup new events on initialization, hardware-lock-elision hugely benefits this case -# as it essentially makes the lock entirely free as long as there is no writes +# as it essentially makes the lock entirely free as long as there is no writes parking_lot = { workspace = true, features = ["hardware-lock-elision"] } once_cell = "1.21" diff --git a/helix-event/src/hook.rs b/helix-event/src/hook.rs index 7fb68148368d..3b0cb69561ef 100644 --- a/helix-event/src/hook.rs +++ b/helix-event/src/hook.rs @@ -36,11 +36,13 @@ impl ErasedHook { _event: NonNull, result: NonNull, ) { - let hook: NonNull = hook.cast(); - let result: NonNull> = result.cast(); - let hook: &F = hook.as_ref(); - let res = hook(); - ptr::write(result.as_ptr(), res) + unsafe { + let hook: NonNull = hook.cast(); + let result: NonNull> = result.cast(); + let hook: &F = hook.as_ref(); + let res = hook(); + ptr::write(result.as_ptr(), res) + } } unsafe { @@ -57,12 +59,14 @@ impl ErasedHook { event: NonNull, result: NonNull, ) { - let hook: NonNull = hook.cast(); - let mut event: NonNull = event.cast(); - let result: NonNull> = result.cast(); - let hook: &F = hook.as_ref(); - let res = hook(event.as_mut()); - ptr::write(result.as_ptr(), res) + unsafe { + let hook: NonNull = hook.cast(); + let mut event: NonNull = event.cast(); + let result: NonNull> = result.cast(); + let hook: &F = hook.as_ref(); + let res = hook(event.as_mut()); + ptr::write(result.as_ptr(), res) + } } unsafe { diff --git a/helix-event/src/lib.rs b/helix-event/src/lib.rs index 8aa6b52fa2f9..ecb07c637eb8 100644 --- a/helix-event/src/lib.rs +++ b/helix-event/src/lib.rs @@ -70,7 +70,7 @@ pub fn register_event() { pub unsafe fn register_hook_raw( hook: impl Fn(&mut E) -> Result<()> + 'static + Send + Sync, ) { - registry::with_mut(|registry| registry.register_hook(hook)) + unsafe { registry::with_mut(|registry| registry.register_hook(hook)) } } /// Register a hook solely by event name diff --git a/helix-loader/src/grammar.rs b/helix-loader/src/grammar.rs index 3574e589df46..78c65dc6d390 100644 --- a/helix-loader/src/grammar.rs +++ b/helix-loader/src/grammar.rs @@ -632,10 +632,10 @@ fn needs_recompile( if mtime(parser_c_path)? > lib_mtime { return Ok(true); } - if let Some(scanner_path) = scanner_path { - if mtime(scanner_path)? > lib_mtime { - return Ok(true); - } + if let Some(scanner_path) = scanner_path + && mtime(scanner_path)? > lib_mtime + { + return Ok(true); } Ok(false) } diff --git a/helix-loader/src/lib.rs b/helix-loader/src/lib.rs index 2e3b760dac45..7dfc9aa6b5fa 100644 --- a/helix-loader/src/lib.rs +++ b/helix-loader/src/lib.rs @@ -287,10 +287,10 @@ fn default_config_file() -> PathBuf { } fn ensure_parent_dir(path: &Path) { - if let Some(parent) = path.parent() { - if !parent.exists() { - std::fs::create_dir_all(parent).ok(); - } + if let Some(parent) = path.parent() + && !parent.exists() + { + std::fs::create_dir_all(parent).ok(); } } diff --git a/helix-loader/src/workspace_trust.rs b/helix-loader/src/workspace_trust.rs index 40bc198aed22..2048ba225ef3 100644 --- a/helix-loader/src/workspace_trust.rs +++ b/helix-loader/src/workspace_trust.rs @@ -66,11 +66,11 @@ impl WorkspaceTrust { } } // let chains aren't supported in current MSRV - if let Ok(false) = fs::exists(data_dir()) { - if let Err(e) = fs::create_dir_all(data_dir()) { - log::error!("Couldn't create helix's data directory: {:?}", e); - }; - } + if let Ok(false) = fs::exists(data_dir()) + && let Err(e) = fs::create_dir_all(data_dir()) + { + log::error!("Couldn't create helix's data directory: {:?}", e); + }; if let Err(e) = fs::write(workspace_trust_file(), trust_text) { log::error!("Error during write of workspace_trust file: {:?}", e); } @@ -85,11 +85,11 @@ impl WorkspaceTrust { } } // let chains aren't supported in current MSRV - if let Ok(false) = fs::exists(data_dir()) { - if let Err(e) = fs::create_dir_all(data_dir()) { - log::error!("Couldn't create helix's data directory: {:?}", e); - }; - } + if let Ok(false) = fs::exists(data_dir()) + && let Err(e) = fs::create_dir_all(data_dir()) + { + log::error!("Couldn't create helix's data directory: {:?}", e); + }; if let Err(e) = fs::write(workspace_exclude_file(), trust_text) { log::error!("Error during write of workspace_trust file: {:?}", e); } diff --git a/helix-lsp-types/Cargo.toml b/helix-lsp-types/Cargo.toml index 3aae5b340de4..98cca55dea38 100644 --- a/helix-lsp-types/Cargo.toml +++ b/helix-lsp-types/Cargo.toml @@ -8,7 +8,7 @@ authors = [ # Since forking "Helix contributors" ] -edition = "2018" +edition.workspace = true description = "Types for interaction with a language server, using VSCode's Language Server Protocol" repository = "https://github.com/gluon-lang/lsp-types" diff --git a/helix-lsp/Cargo.toml b/helix-lsp/Cargo.toml index d13ddca3ee57..8a2bc9b7a478 100644 --- a/helix-lsp/Cargo.toml +++ b/helix-lsp/Cargo.toml @@ -3,7 +3,7 @@ name = "helix-lsp" description = "LSP client implementation for Helix project" version.workspace = true authors.workspace = true -edition.workspace = true +edition = "2021" license.workspace = true rust-version.workspace = true categories.workspace = true diff --git a/helix-parsec/src/lib.rs b/helix-parsec/src/lib.rs index 0ec44436fdbf..57b15353ceb9 100644 --- a/helix-parsec/src/lib.rs +++ b/helix-parsec/src/lib.rs @@ -338,10 +338,10 @@ where F: Fn(&P::Output) -> bool, { move |input| { - if let Ok((next_input, value)) = parser.parse(input) { - if pred_fn(&value) { - return Ok((next_input, value)); - } + if let Ok((next_input, value)) = parser.parse(input) + && pred_fn(&value) + { + return Ok((next_input, value)); } Err(input) } diff --git a/helix-stdx/src/env.rs b/helix-stdx/src/env.rs index 9e7781a0cec2..c181a432a2c0 100644 --- a/helix-stdx/src/env.rs +++ b/helix-stdx/src/env.rs @@ -27,10 +27,10 @@ pub fn current_working_dir() -> PathBuf { #[cfg(windows)] let pwd = pwd.or_else(|| std::env::var_os("CD")); - if let Some(pwd) = pwd.map(PathBuf::from) { - if pwd.canonicalize().ok().as_ref() == Some(&cwd) { - cwd = pwd; - } + if let Some(pwd) = pwd.map(PathBuf::from) + && pwd.canonicalize().ok().as_ref() == Some(&cwd) + { + cwd = pwd; } let mut dst = CWD.write().unwrap(); *dst = Some(cwd.clone()); diff --git a/helix-stdx/src/path.rs b/helix-stdx/src/path.rs index 740f7bcb51d9..4fbd51c05faf 100644 --- a/helix-stdx/src/path.rs +++ b/helix-stdx/src/path.rs @@ -21,14 +21,14 @@ where P: Into>, { let path = path.into(); - if let Ok(home) = home_dir() { - if let Ok(stripped) = path.strip_prefix(&home) { - let mut path = OsString::with_capacity(2 + stripped.as_os_str().len()); - path.push("~"); - path.push(MAIN_SEPARATOR_STR); - path.push(stripped); - return Cow::Owned(PathBuf::from(path)); - } + if let Ok(home) = home_dir() + && let Ok(stripped) = path.strip_prefix(&home) + { + let mut path = OsString::with_capacity(2 + stripped.as_os_str().len()); + path.push("~"); + path.push(MAIN_SEPARATOR_STR); + path.push(stripped); + return Cow::Owned(PathBuf::from(path)); } path @@ -45,13 +45,12 @@ where { let path = path.into(); let mut components = path.components(); - if let Some(Component::Normal(c)) = components.next() { - if c == "~" { - if let Ok(mut buf) = home_dir() { - buf.push(components); - return Cow::Owned(buf); - } - } + if let Some(Component::Normal(c)) = components.next() + && c == "~" + && let Ok(mut buf) = home_dir() + { + buf.push(components); + return Cow::Owned(buf); } path diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs index c4e0bc3eb126..0cae402edf0b 100644 --- a/helix-term/src/application.rs +++ b/helix-term/src/application.rs @@ -1141,15 +1141,13 @@ impl Application { }; if let Some(language_server) = editor.language_server_by_id(server_id) - { - if let Err(err) = + && let Err(err) = language_server.reply(id.clone(), Ok(json!(reply))) - { - log::error!( + { + log::error!( "Failed to send reply to server '{}' request {id}: {err}", language_server.name() ); - } } }, ); @@ -1260,7 +1258,9 @@ impl Application { } #[cfg(all(not(feature = "integration"), not(windows)))] - pub fn event_stream(&self) -> impl Stream> + Unpin { + pub fn event_stream( + &self, + ) -> impl Stream> + Unpin + use<> { use termina::{escape::csi, Terminal as _}; let reader = self.terminal.backend().terminal().event_reader(); termina::EventStream::new(reader, |event| { @@ -1274,12 +1274,16 @@ impl Application { } #[cfg(all(not(feature = "integration"), windows))] - pub fn event_stream(&self) -> impl Stream> + Unpin { + pub fn event_stream( + &self, + ) -> impl Stream> + Unpin + use<> { crossterm::event::EventStream::new() } #[cfg(feature = "integration")] - pub fn event_stream(&self) -> impl Stream> + Unpin { + pub fn event_stream( + &self, + ) -> impl Stream> + Unpin + use<> { use std::{ pin::Pin, task::{Context, Poll}, diff --git a/helix-term/src/args.rs b/helix-term/src/args.rs index 090c1192feb9..9fa50f32495c 100644 --- a/helix-term/src/args.rs +++ b/helix-term/src/args.rs @@ -118,14 +118,13 @@ impl Args { insert_file_with_position(&arg); } - if line_number != 0 { - if let Some(first_position) = args + if line_number != 0 + && let Some(first_position) = args .files .first_mut() .and_then(|(_, positions)| positions.first_mut()) - { - first_position.row = line_number; - } + { + first_position.row = line_number; } Ok(args) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index eaf5d33f393c..cde5436b64b8 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -1413,10 +1413,10 @@ fn goto_file_impl(cx: &mut Context, action: Action) { if lsp_targets_seen.insert(target.clone()) { lsp_targets.push(target); } - } else if unresolved_links.insert((link.start, link.end, link.language_server_id)) { - if let Some(request) = resolve_document_link_request(cx.editor, link) { - resolve_requests.push(request); - } + } else if unresolved_links.insert((link.start, link.end, link.language_server_id)) + && let Some(request) = resolve_document_link_request(cx.editor, link) + { + resolve_requests.push(request); } } if !matched { @@ -1440,10 +1440,10 @@ fn goto_file_impl(cx: &mut Context, action: Action) { for request in resolve_requests { match request.await { Ok(link) => { - if let Some(target) = link.target { - if seen.insert(target.clone()) { - targets.push(target); - } + if let Some(target) = link.target + && seen.insert(target.clone()) + { + targets.push(target); } } Err(err) => log::warn!("Failed to resolve document link: {err}"), @@ -2201,12 +2201,15 @@ fn select_regex(cx: &mut Context) { return; } let text = doc.text().slice(..); - if let Some(selection) = - selection::select_on_matches(text, doc.selection(view.id), ®ex) - { - doc.set_selection(view.id, selection); - } else if event == PromptEvent::Validate { - cx.editor.set_error("nothing selected"); + match selection::select_on_matches(text, doc.selection(view.id), ®ex) { + Some(selection) => { + doc.set_selection(view.id, selection); + } + _ => { + if event == PromptEvent::Validate { + cx.editor.set_error("nothing selected"); + } + } } }, ); @@ -3639,10 +3642,11 @@ pub fn command_palette(cx: &mut Context) { fn last_picker(cx: &mut Context) { // TODO: last picker does not seem to work well with buffer_picker cx.callback.push(Box::new(|compositor, cx| { - if let Some(picker) = compositor.last_picker.take() { - compositor.push(picker); - } else { - cx.editor.set_error("no last picker") + match compositor.last_picker.take() { + Some(picker) => { + compositor.push(picker); + } + _ => cx.editor.set_error("no last picker"), } })); } @@ -5374,12 +5378,15 @@ fn keep_or_remove_selections_impl(cx: &mut Context, remove: bool) { } let text = doc.text().slice(..); - if let Some(selection) = - selection::keep_or_remove_matches(text, doc.selection(view.id), ®ex, remove) - { - doc.set_selection(view.id, selection); - } else if event == PromptEvent::Validate { - cx.editor.set_error("no selections remaining"); + match selection::keep_or_remove_matches(text, doc.selection(view.id), ®ex, remove) { + Some(selection) => { + doc.set_selection(view.id, selection); + } + _ => { + if event == PromptEvent::Validate { + cx.editor.set_error("no selections remaining"); + } + } } }, ) @@ -5917,11 +5924,11 @@ fn vsplit_new(cx: &mut Context) { } fn wclose(cx: &mut Context) { - if cx.editor.tree.views().count() == 1 { - if let Err(err) = typed::buffers_remaining_impl(cx.editor) { - cx.editor.set_error(err.to_string()); - return; - } + if cx.editor.tree.views().count() == 1 + && let Err(err) = typed::buffers_remaining_impl(cx.editor) + { + cx.editor.set_error(err.to_string()); + return; } let view_id = view!(cx.editor).id; // close current split @@ -6467,12 +6474,15 @@ fn shell_keep_pipe(cx: &mut Context) { for (i, range) in selection.ranges().iter().enumerate() { let fragment = range.slice(text); - if let Err(err) = shell_impl(shell, args.join(" ").as_str(), Some(fragment.into())) { - log::debug!("Shell command failed: {}", err); - } else { - ranges.push(*range); - if i >= old_index && index.is_none() { - index = Some(ranges.len() - 1); + match shell_impl(shell, args.join(" ").as_str(), Some(fragment.into())) { + Err(err) => { + log::debug!("Shell command failed: {}", err); + } + _ => { + ranges.push(*range); + if i >= old_index && index.is_none() { + index = Some(ranges.len() - 1); + } } } } @@ -6520,22 +6530,25 @@ async fn shell_impl_async( return Err(e.into()); } }; - let output = if let Some(mut stdin) = process.stdin.take() { - let input_task = tokio::spawn(async move { - if let Some(input) = input { - helix_view::document::to_writer(&mut stdin, (encoding::UTF_8, false), &input) - .await?; - } - anyhow::Ok(()) - }); - let (output, _) = tokio::join! { - process.wait_with_output(), - input_task, - }; - output? - } else { - // Process has no stdin, so we just take the output - process.wait_with_output().await? + let output = match process.stdin.take() { + Some(mut stdin) => { + let input_task = tokio::spawn(async move { + if let Some(input) = input { + helix_view::document::to_writer(&mut stdin, (encoding::UTF_8, false), &input) + .await?; + } + anyhow::Ok(()) + }); + let (output, _) = tokio::join! { + process.wait_with_output(), + input_task, + }; + output? + } + _ => { + // Process has no stdin, so we just take the output + process.wait_with_output().await? + } }; let output = if !output.status.success() { diff --git a/helix-term/src/commands/dap.rs b/helix-term/src/commands/dap.rs index 922d0ade3be7..b43e1bfd734c 100644 --- a/helix-term/src/commands/dap.rs +++ b/helix-term/src/commands/dap.rs @@ -192,13 +192,13 @@ fn prepare_dap_params(template: &DebugTemplate, params: &[std::borrow::Cow] .enumerate() .map(|(i, x)| { let mut param = x.to_string(); - if let Some(DebugConfigCompletion::Advanced(cfg)) = template.completion.get(i) { - if matches!(cfg.completion.as_deref(), Some("filename" | "directory")) { - param = std::fs::canonicalize(x.as_ref()) - .ok() - .and_then(|pb| pb.into_os_string().into_string().ok()) - .unwrap_or_else(|| x.to_string()); - } + if let Some(DebugConfigCompletion::Advanced(cfg)) = template.completion.get(i) + && matches!(cfg.completion.as_deref(), Some("filename" | "directory")) + { + param = std::fs::canonicalize(x.as_ref()) + .ok() + .and_then(|pb| pb.into_os_string().into_string().ok()) + .unwrap_or_else(|| x.to_string()); } param }) diff --git a/helix-term/src/commands/lsp.rs b/helix-term/src/commands/lsp.rs index 66cfbfc6b442..a3a39af465e8 100644 --- a/helix-term/src/commands/lsp.rs +++ b/helix-term/src/commands/lsp.rs @@ -41,7 +41,7 @@ use std::{cmp::Ordering, collections::HashSet, fmt::Display, future::Future, pat /// will spam the "No configured language server supports \" status message confusingly. #[macro_export] macro_rules! language_server_with_feature { - ($editor:expr, $doc:expr, $feature:expr) => {{ + ($editor:expr_2021, $doc:expr_2021, $feature:expr_2021) => {{ let language_server = $doc.language_servers_with_feature($feature).next(); match language_server { Some(language_server) => language_server, @@ -790,12 +790,11 @@ pub fn code_action(cx: &mut Context) { log::debug!("code action: {:?}", code_action); // we support lsp "codeAction/resolve" for `edit` and `command` fields let mut resolved_code_action = None; - if code_action.edit.is_none() || code_action.command.is_none() { - if let Some(future) = language_server.resolve_code_action(code_action) { - if let Ok(code_action) = helix_lsp::block_on(future) { - resolved_code_action = Some(code_action); - } - } + if (code_action.edit.is_none() || code_action.command.is_none()) + && let Some(future) = language_server.resolve_code_action(code_action) + && let Ok(code_action) = helix_lsp::block_on(future) + { + resolved_code_action = Some(code_action); } let resolved_code_action = resolved_code_action.as_ref().unwrap_or(code_action); @@ -1289,7 +1288,9 @@ pub fn compute_inlay_hints_for_all_views(editor: &mut Editor, jobs: &mut crate:: fn compute_inlay_hints_for_view( view: &View, doc: &Document, -) -> Option>>>> { +) -> Option< + std::pin::Pin> + use<>>>, +> { let view_id = view.id; let doc_id = view.doc; diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index 85cf6b1d1290..e83c9e931e3a 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -183,12 +183,9 @@ fn buffer_close_by_ids_impl( let (modified_ids, modified_names): (Vec<_>, Vec<_>) = doc_ids .iter() - .filter_map(|&doc_id| { - if let Err(CloseError::BufferModified(name)) = cx.editor.close_document(doc_id, force) { - Some((doc_id, name)) - } else { - None - } + .filter_map(|&doc_id| match cx.editor.close_document(doc_id, force) { + Err(CloseError::BufferModified(name)) => Some((doc_id, name)), + _ => None, }) .unzip(); @@ -1031,14 +1028,14 @@ fn theme(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow if args.is_empty() { // Ensures that a preview theme gets cleaned up if the user backspaces until the prompt is empty. cx.editor.unset_theme_preview()?; - } else if let Some(theme_name) = args.first() { - if let Ok(theme) = cx.editor.theme_loader.load(theme_name) { - if !(true_color || theme.is_16_color()) { - bail!("Unsupported theme: theme requires true color support"); - } - cx.editor.set_theme_preview(theme)?; - }; - }; + } else if let Some(theme_name) = args.first() + && let Ok(theme) = cx.editor.theme_loader.load(theme_name) + { + if !(true_color || theme.is_16_color()) { + bail!("Unsupported theme: theme requires true color support"); + } + cx.editor.set_theme_preview(theme)?; + } } PromptEvent::Validate => { if let Some(theme_name) = args.first() { @@ -2223,14 +2220,14 @@ fn toggle_option( let value = config.pointer_mut(&pointer).ok_or_else(key_error)?; *value = match value { - Value::Bool(ref value) => { + &mut Value::Bool(ref value) => { ensure!( args.len() == 1, "Bad arguments. For boolean configurations use: `:toggle {key}`" ); Value::Bool(!value) } - Value::String(ref value) => { + &mut Value::String(ref value) => { ensure!( args.len() == 2, "Bad arguments. For string configurations use: `:toggle {key} val1 val2 ...`", @@ -2747,17 +2744,14 @@ fn move_buffer_impl( .map(|old_file_name| new_path.join(old_file_name)) .unwrap_or(new_path); - if old_path.exists() { - if let Some(parent) = new_path.parent() { - if !parent.exists() { - if options.force { - std::fs::DirBuilder::new().recursive(true).create(parent)?; - } else { - bail!( - "can't move file, parent directory does not exist (use :mv! to create it)" - ) - } - } + if old_path.exists() + && let Some(parent) = new_path.parent() + && !parent.exists() + { + if options.force { + std::fs::DirBuilder::new().recursive(true).create(parent)?; + } else { + bail!("can't move file, parent directory does not exist (use :mv! to create it)") } } diff --git a/helix-term/src/compositor.rs b/helix-term/src/compositor.rs index 266a8aec897b..f76409dbf2ea 100644 --- a/helix-term/src/compositor.rs +++ b/helix-term/src/compositor.rs @@ -144,10 +144,10 @@ impl Compositor { pub fn handle_event(&mut self, event: &Event, cx: &mut Context) -> bool { // If it is a key event, a macro is being recorded, and a macro isn't being replayed, // push the key event to the recording. - if let (Event::Key(key), Some((_, keys))) = (event, &mut cx.editor.macro_recording) { - if cx.editor.macro_replaying.is_empty() { - keys.push(*key); - } + if let (Event::Key(key), Some((_, keys))) = (event, &mut cx.editor.macro_recording) + && cx.editor.macro_replaying.is_empty() + { + keys.push(*key); } let mut callbacks = Vec::new(); diff --git a/helix-term/src/handlers/completion/path.rs b/helix-term/src/handlers/completion/path.rs index c2ffa5efa44e..8c968252b17c 100644 --- a/helix-term/src/handlers/completion/path.rs +++ b/helix-term/src/handlers/completion/path.rs @@ -19,7 +19,7 @@ pub(crate) fn path_completion( doc: &Document, handle: TaskHandle, savepoint: Arc, -) -> Option CompletionResponse> { +) -> Option CompletionResponse + use<>> { if !doc.path_completion_enabled() { return None; } diff --git a/helix-term/src/handlers/completion/request.rs b/helix-term/src/handlers/completion/request.rs index fd65cd4d8e2c..f8c03277ea3f 100644 --- a/helix-term/src/handlers/completion/request.rs +++ b/helix-term/src/handlers/completion/request.rs @@ -296,7 +296,7 @@ fn request_completions_from_language_server( context: lsp::CompletionContext, priority: i8, savepoint: Arc, -) -> impl Future { +) -> impl Future + use<> { let provider = ls.id(); let offset_encoding = ls.offset_encoding(); let text = doc.text(); diff --git a/helix-term/src/handlers/completion/word.rs b/helix-term/src/handlers/completion/word.rs index aa204bf8f73d..c6623110657b 100644 --- a/helix-term/src/handlers/completion/word.rs +++ b/helix-term/src/handlers/completion/word.rs @@ -18,7 +18,7 @@ pub(super) fn completion( trigger: Trigger, handle: TaskHandle, savepoint: Arc, -) -> Option CompletionResponse> { +) -> Option CompletionResponse + use<>> { if !doc!(editor).word_completion_enabled() { return None; } diff --git a/helix-term/src/handlers/document_highlight.rs b/helix-term/src/handlers/document_highlight.rs index 1783722de50e..bf48822be843 100644 --- a/helix-term/src/handlers/document_highlight.rs +++ b/helix-term/src/handlers/document_highlight.rs @@ -85,13 +85,13 @@ fn document_highlight_ranges( let mut merged: Vec> = Vec::with_capacity(ranges.len()); for range in ranges { - if let Some(last) = merged.last_mut() { - if range.start <= last.end { - if range.end > last.end { - last.end = range.end; - } - continue; + if let Some(last) = merged.last_mut() + && range.start <= last.end + { + if range.end > last.end { + last.end = range.end; } + continue; } merged.push(range); } diff --git a/helix-term/src/handlers/snippet.rs b/helix-term/src/handlers/snippet.rs index 3860d3f7223b..3693034aecdb 100644 --- a/helix-term/src/handlers/snippet.rs +++ b/helix-term/src/handlers/snippet.rs @@ -4,10 +4,10 @@ use helix_view::handlers::Handlers; pub(super) fn register_hooks(_handlers: &Handlers) { register_hook!(move |event: &mut SelectionDidChange<'_>| { - if let Some(snippet) = &event.doc.active_snippet { - if !snippet.is_valid(event.doc.selection(event.view)) { - event.doc.active_snippet = None; - } + if let Some(snippet) = &event.doc.active_snippet + && !snippet.is_valid(event.doc.selection(event.view)) + { + event.doc.active_snippet = None; } Ok(()) }); diff --git a/helix-term/src/handlers/workspace_trust.rs b/helix-term/src/handlers/workspace_trust.rs index 68e9d8bdfffe..b2da40c1b653 100644 --- a/helix-term/src/handlers/workspace_trust.rs +++ b/helix-term/src/handlers/workspace_trust.rs @@ -21,13 +21,12 @@ pub(super) fn register_hooks(_handlers: &Handlers) { let doc = doc!(event.editor, &event.doc); // If there is no servers to be loaded, then the workspace might not be trusted yet - if doc.language_servers().next().is_none() { - if let TrustUntrustStatus::DenyOnce = + if doc.language_servers().next().is_none() + && let TrustUntrustStatus::DenyOnce = quick_query_workspace_with_explicit_untrust(event.editor.config().insecure) - { - let (workspace, _) = helix_loader::find_workspace(); - job::dispatch_blocking(|_editor, compositor| prompt(workspace, compositor)); - } + { + let (workspace, _) = helix_loader::find_workspace(); + job::dispatch_blocking(|_editor, compositor| prompt(workspace, compositor)); } Ok(()) }); diff --git a/helix-term/src/job.rs b/helix-term/src/job.rs index 72ed892ddf9a..d1b264615f15 100644 --- a/helix-term/src/job.rs +++ b/helix-term/src/job.rs @@ -140,7 +140,7 @@ impl Jobs { log::debug!("waiting on jobs..."); let mut wait_futures = std::mem::take(&mut self.wait_futures); - while let (Some(job), tail) = wait_futures.into_future().await { + while let (Some(job), tail) = StreamExt::into_future(wait_futures).await { match job { Ok(callback) => { wait_futures = tail; diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs index a9013edcf9cf..57287516dd58 100644 --- a/helix-term/src/keymap.rs +++ b/helix-term/src/keymap.rs @@ -44,11 +44,11 @@ impl KeyTrieNode { /// subnodes for same key. In that case the merge is recursive. pub fn merge(&mut self, mut other: Self) { for (key, trie) in std::mem::take(&mut other.map) { - if let Some(KeyTrie::Node(node)) = self.map.get_mut(&key) { - if let KeyTrie::Node(other_node) = trie { - node.merge(other_node); - continue; - } + if let Some(KeyTrie::Node(node)) = self.map.get_mut(&key) + && let KeyTrie::Node(other_node) = trie + { + node.merge(other_node); + continue; } self.map.insert(key, trie); } @@ -324,10 +324,10 @@ impl Keymaps { }; let trie = match trie_node.search(&[*first]) { - Some(KeyTrie::MappableCommand(ref cmd)) => { + Some(KeyTrie::MappableCommand(cmd)) => { return KeymapResult::Matched(cmd.clone()); } - Some(KeyTrie::Sequence(ref cmds)) => { + Some(KeyTrie::Sequence(cmds)) => { return KeymapResult::MatchedSequence(cmds.clone()); } None => return KeymapResult::NotFound, diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs index 0bf00cea9b58..ef7e27db9d97 100644 --- a/helix-term/src/ui/completion.rs +++ b/helix-term/src/ui/completion.rs @@ -140,7 +140,7 @@ impl Completion { let (view, doc) = current!(editor); macro_rules! language_server { - ($item:expr) => { + ($item:expr_2021) => { match editor .language_servers .get_by_id($item.provider) @@ -219,13 +219,13 @@ impl Completion { let language_server = language_server!(item); // resolve item if not yet resolved - if !item.resolved { - if let Some(resolved_item) = Self::resolve_completion_item( + if !item.resolved + && let Some(resolved_item) = Self::resolve_completion_item( language_server, item.item.clone(), - ) { - item.item = resolved_item; - } + ) + { + item.item = resolved_item; }; let encoding = language_server.offset_encoding(); @@ -266,15 +266,15 @@ impl Completion { }); // TODO: add additional _edits to completion_changes? - if let Some((additional_edits, offset_encoding)) = additional_edits { - if !additional_edits.is_empty() { - let transaction = util::generate_transaction_from_edits( - doc.text(), - additional_edits, - offset_encoding, // TODO: should probably transcode in Client - ); - doc.apply(&transaction, view.id); - } + if let Some((additional_edits, offset_encoding)) = additional_edits + && !additional_edits.is_empty() + { + let transaction = util::generate_transaction_from_edits( + doc.text(), + additional_edits, + offset_encoding, // TODO: should probably transcode in Client + ); + doc.apply(&transaction, view.id); } // we could have just inserted a trigger char (like a `crate::` completion for rust // so we want to retrigger immediately when accepting a completion. diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index 3626c5ddcfcd..687757b12d65 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -131,12 +131,10 @@ impl EditorView { .language_config() .and_then(|config| config.rainbow_brackets) .unwrap_or(config.rainbow_brackets) - { - if let Some(overlay) = + && let Some(overlay) = Self::doc_rainbow_highlights(doc, view_offset.anchor, inner.height, theme, &loader) - { - overlays.push(overlay); - } + { + overlays.push(overlay); } if let Some(overlay) = Self::doc_document_link_highlights(doc, theme) { @@ -146,10 +144,10 @@ impl EditorView { Self::doc_diagnostics_highlights_into(doc, theme, &mut overlays); if is_focused { - if config.lsp.auto_document_highlight { - if let Some(overlay) = Self::doc_document_highlights(doc, view, theme) { - overlays.push(overlay); - } + if config.lsp.auto_document_highlight + && let Some(overlay) = Self::doc_document_highlights(doc, view, theme) + { + overlays.push(overlay); } if let Some(tabstops) = Self::tabstop_highlights(doc, theme) { overlays.push(tabstops); @@ -836,7 +834,7 @@ impl EditorView { } /// Apply the highlighting on the lines where a cursor is active - pub fn cursorline(doc: &Document, view: &View, theme: &Theme) -> impl Decoration { + pub fn cursorline(doc: &Document, view: &View, theme: &Theme) -> impl Decoration + use<> { let text = doc.text().slice(..); // TODO only highlight the visual line that contains the cursor instead of the full visual line let primary_line = doc.selection(view.id).primary().cursor_line(text); @@ -980,10 +978,10 @@ impl EditorView { if let Some(keyresult) = self.handle_keymap_event(Mode::Insert, cx, event) { match keyresult { KeymapResult::NotFound => { - if !self.on_next_key(OnKeyCallbackKind::Fallback, cx, event) { - if let Some(ch) = event.char() { - commands::insert::insert_char(cx, ch) - } + if !self.on_next_key(OnKeyCallbackKind::Fallback, cx, event) + && let Some(ch) = event.char() + { + commands::insert::insert_char(cx, ch) } } KeymapResult::Cancelled(pending) => { @@ -1414,16 +1412,17 @@ impl EditorView { ctx: &mut commands::Context, event: KeyEvent, ) -> bool { - if let Some((on_next_key, kind_)) = self.on_next_key.take() { - if kind == kind_ { - on_next_key(ctx, event); - true - } else { - self.on_next_key = Some((on_next_key, kind_)); - false + match self.on_next_key.take() { + Some((on_next_key, kind_)) => { + if kind == kind_ { + on_next_key(ctx, event); + true + } else { + self.on_next_key = Some((on_next_key, kind_)); + false + } } - } else { - false + _ => false, } } } @@ -1468,7 +1467,7 @@ impl Component for EditorView { // Handling it here but not re-rendering will cause flashing EventResult::Consumed(None) } - Event::Key(mut key) => { + &Event::Key(mut key) => { cx.editor.reset_idle_timer(); canonicalize_key(&mut key); @@ -1491,31 +1490,33 @@ impl Component for EditorView { scroll: None, }; - if let EventResult::Consumed(callback) = - completion.handle_event(event, &mut cx) - { - consumed = true; - Some(callback) - } else if let EventResult::Consumed(callback) = - completion.handle_event(&Event::Key(key!(Enter)), &mut cx) - { - Some(callback) - } else { - None + match completion.handle_event(event, &mut cx) { + EventResult::Consumed(callback) => { + consumed = true; + Some(callback) + } + _ => { + match completion + .handle_event(&Event::Key(key!(Enter)), &mut cx) + { + EventResult::Consumed(callback) => Some(callback), + _ => None, + } + } } }; - if let Some(callback) = res { - if callback.is_some() { - // assume close_fn - if let Some(cb) = self.clear_completion(cx.editor) { - if consumed { - cx.on_next_key_callback = - Some((cb, OnKeyCallbackKind::Fallback)) - } else { - self.on_next_key = - Some((cb, OnKeyCallbackKind::Fallback)); - } + if let Some(callback) = res + && callback.is_some() + { + // assume close_fn + if let Some(cb) = self.clear_completion(cx.editor) { + if consumed { + cx.on_next_key_callback = + Some((cb, OnKeyCallbackKind::Fallback)) + } else { + self.on_next_key = + Some((cb, OnKeyCallbackKind::Fallback)); } } } @@ -1627,11 +1628,11 @@ impl Component for EditorView { self.render_view(cx.editor, doc, view, area, surface, is_focused); } - if config.auto_info { - if let Some(mut info) = cx.editor.autoinfo.take() { - info.render(area, surface, cx); - cx.editor.autoinfo = Some(info) - } + if config.auto_info + && let Some(mut info) = cx.editor.autoinfo.take() + { + info.render(area, surface, cx); + cx.editor.autoinfo = Some(info) } let key_width = 15u16; // for showing pending keys diff --git a/helix-term/src/ui/markdown.rs b/helix-term/src/ui/markdown.rs index 6bef59d14c92..632f2ff44071 100644 --- a/helix-term/src/ui/markdown.rs +++ b/helix-term/src/ui/markdown.rs @@ -355,10 +355,10 @@ impl Markdown { } // if last line is empty, remove it - if let Some(line) = lines.last() { - if line.0.is_empty() { - lines.pop(); - } + if let Some(line) = lines.last() + && line.0.is_empty() + { + lines.pop(); } Text::from(lines) diff --git a/helix-term/src/ui/menu.rs b/helix-term/src/ui/menu.rs index 5dde9a6feb4a..e2a491c8a355 100644 --- a/helix-term/src/ui/menu.rs +++ b/helix-term/src/ui/menu.rs @@ -376,17 +376,15 @@ impl Component for Menu { let render_borders = cx.editor.menu_border(); - if !render_borders { - if let Some(cursor) = self.cursor { - let offset_from_top = cursor - scroll; - let left = &mut surface[(area.left(), area.y + offset_from_top as u16)]; - left.set_style(selected); - let right = &mut surface[( - area.right().saturating_sub(1), - area.y + offset_from_top as u16, - )]; - right.set_style(selected); - } + if !render_borders && let Some(cursor) = self.cursor { + let offset_from_top = cursor - scroll; + let left = &mut surface[(area.left(), area.y + offset_from_top as u16)]; + left.set_style(selected); + let right = &mut surface[( + area.right().saturating_sub(1), + area.y + offset_from_top as u16, + )]; + right.set_style(selected); } let fits = len <= win_height; diff --git a/helix-term/src/ui/picker.rs b/helix-term/src/ui/picker.rs index c61321f6fcac..ba9e59e3d427 100644 --- a/helix-term/src/ui/picker.rs +++ b/helix-term/src/ui/picker.rs @@ -968,16 +968,15 @@ impl Picker { .language_config() .and_then(|config| config.rainbow_brackets) .unwrap_or(config.rainbow_brackets) - { - if let Some(overlay) = EditorView::doc_rainbow_highlights( + && let Some(overlay) = EditorView::doc_rainbow_highlights( doc, offset.anchor, area.height, &cx.editor.theme, &loader, - ) { - overlay_highlights.push(overlay); - } + ) + { + overlay_highlights.push(overlay); } EditorView::doc_diagnostics_highlights_into( @@ -1132,14 +1131,13 @@ impl Component for Picker AsyncHook return; }; - let Some(CachedPreview::Document(ref mut doc)) = picker.preview_cache.get_mut(&path) - else { + let Some(CachedPreview::Document(doc)) = picker.preview_cache.get_mut(&path) else { return; }; @@ -94,8 +93,7 @@ impl AsyncHook log::info!("picker closed before syntax highlighting finished"); return; }; - let Some(CachedPreview::Document(ref mut doc)) = - picker.preview_cache.get_mut(&path) + let Some(CachedPreview::Document(doc)) = picker.preview_cache.get_mut(&path) else { return; }; diff --git a/helix-term/src/ui/prompt.rs b/helix-term/src/ui/prompt.rs index 04b785fe9171..45cac1fdee75 100644 --- a/helix-term/src/ui/prompt.rs +++ b/helix-term/src/ui/prompt.rs @@ -688,12 +688,11 @@ impl Component for Prompt { } else { if last_item != self.line { // store in history - if let Some(register) = self.history_register { - if let Err(err) = + if let Some(register) = self.history_register + && let Err(err) = cx.editor.registers.push(register, self.line.clone()) - { - cx.editor.set_error(err.to_string()); - } + { + cx.editor.set_error(err.to_string()); }; } diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs index 4b3e1bba09de..b45dfa619c20 100644 --- a/helix-view/src/document.rs +++ b/helix-view/src/document.rs @@ -1036,14 +1036,12 @@ impl Document { } // Protect against overwriting changes made externally - if !force { - if let Ok(metadata) = fs::metadata(&path).await { - if let Ok(mtime) = metadata.modified() { - if last_saved_time < mtime { - bail!("file modified by an external process, use :w! to overwrite"); - } - } - } + if !force + && let Ok(metadata) = fs::metadata(&path).await + && let Ok(mtime) = metadata.modified() + && last_saved_time < mtime + { + bail!("file modified by an external process, use :w! to overwrite"); } let write_path = tokio::fs::read_link(&path) .await @@ -1231,10 +1229,10 @@ impl Document { } pub fn detect_editor_config(&mut self) { - if self.config.load().editor_config { - if let Some(path) = self.path.as_ref() { - self.editor_config = EditorConfig::find(path); - } + if self.config.load().editor_config + && let Some(path) = self.path.as_ref() + { + self.editor_config = EditorConfig::find(path); } } @@ -2143,12 +2141,11 @@ impl Document { } }); - if let Some(lang_conf) = language_config { - if let Some(severity) = severity { - if severity < lang_conf.diagnostic_severity { - return None; - } - } + if let Some(lang_conf) = language_config + && let Some(severity) = severity + && severity < lang_conf.diagnostic_severity + { + return None; }; use helix_core::diagnostic::{DiagnosticTag, NumberOrString}; @@ -2161,16 +2158,13 @@ impl Document { }; let tags = if let Some(tags) = &diagnostic.tags { - let new_tags = tags - .iter() + tags.iter() .filter_map(|tag| match *tag { lsp::DiagnosticTag::DEPRECATED => Some(DiagnosticTag::Deprecated), lsp::DiagnosticTag::UNNECESSARY => Some(DiagnosticTag::Unnecessary), _ => None, }) - .collect(); - - new_tags + .collect() } else { Vec::new() }; diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index 2146bc877fac..509f961c5175 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -2460,7 +2460,7 @@ fn try_restore_indent(doc: &mut Document, view: &mut View) { }; fn inserted_a_new_blank_line(changes: &[Operation], pos: usize, line_end_pos: usize) -> bool { - if let [Operation::Retain(move_pos), Operation::Insert(ref inserted_str), Operation::Retain(_)] = + if let [Operation::Retain(move_pos), Operation::Insert(inserted_str), Operation::Retain(_)] = changes { let mut graphemes = inserted_str.graphemes(true); diff --git a/helix-view/src/handlers/dap.rs b/helix-view/src/handlers/dap.rs index b913ce8e1ae3..a17c8b7db433 100644 --- a/helix-view/src/handlers/dap.rs +++ b/helix-view/src/handlers/dap.rs @@ -269,10 +269,10 @@ impl Editor { warn!("DAP breakpoint event missing id"); return false; }; - if let Some(source) = &breakpoint.source { - if source.path.is_none() { - warn!("DAP breakpoint event missing source path"); - } + if let Some(source) = &breakpoint.source + && source.path.is_none() + { + warn!("DAP breakpoint event missing source path"); } if breakpoint.line.is_none() { warn!("DAP breakpoint event missing line"); diff --git a/helix-view/src/handlers/lsp.rs b/helix-view/src/handlers/lsp.rs index b052138f8400..115a46c834ee 100644 --- a/helix-view/src/handlers/lsp.rs +++ b/helix-view/src/handlers/lsp.rs @@ -111,13 +111,13 @@ impl Editor { }; let doc = doc_mut!(self, &doc_id); - if let Some(version) = version { - if version != doc.version() { - let err = format!("outdated workspace edit for {path:?}"); - log::error!("{err}, expected {} but got {version}", doc.version()); - self.set_error(err); - return Err(ApplyEditErrorKind::DocumentChanged); - } + if let Some(version) = version + && version != doc.version() + { + let err = format!("outdated workspace edit for {path:?}"); + log::error!("{err}, expected {} but got {version}", doc.version()); + self.set_error(err); + return Err(ApplyEditErrorKind::DocumentChanged); } // Need to determine a view for apply/append_changes_to_history @@ -242,10 +242,10 @@ impl Editor { }); if !ignore_if_exists || !path.exists() { // Create directory if it does not exist - if let Some(dir) = path.parent() { - if !dir.is_dir() { - fs::create_dir_all(dir)?; - } + if let Some(dir) = path.parent() + && !dir.is_dir() + { + fs::create_dir_all(dir)?; } fs::write(path, [])?; @@ -304,11 +304,11 @@ impl Editor { .values_mut() .find(|doc| doc.uri().is_some_and(|u| u == uri)); - if let Some((version, doc)) = version.zip(doc.as_ref()) { - if version != doc.version() { - log::info!("Version ({version}) is out of date for {uri:?} (expected ({})), dropping PublishDiagnostic notification", doc.version()); - return; - } + if let Some((version, doc)) = version.zip(doc.as_ref()) + && version != doc.version() + { + log::info!("Version ({version}) is out of date for {uri:?} (expected ({})), dropping PublishDiagnostic notification", doc.version()); + return; } let mut unchanged_diag_sources = Vec::new(); diff --git a/helix-view/src/view.rs b/helix-view/src/view.rs index a0962d84df87..cd6b36d5d5e8 100644 --- a/helix-view/src/view.rs +++ b/helix-view/src/view.rs @@ -478,20 +478,19 @@ impl View { }; let config = doc.config.load(); - if config.lsp.display_color_swatches { - if let Some(DocumentColorSwatches { + if config.lsp.display_color_swatches + && let Some(DocumentColorSwatches { color_swatches, colors, color_swatches_padding, }) = &doc.color_swatches - { - for (color_swatch, color) in color_swatches.iter().zip(colors) { - text_annotations - .add_inline_annotations(std::slice::from_ref(color_swatch), Some(*color)); - } - - text_annotations.add_inline_annotations(color_swatches_padding, None); + { + for (color_swatch, color) in color_swatches.iter().zip(colors) { + text_annotations + .add_inline_annotations(std::slice::from_ref(color_swatch), Some(*color)); } + + text_annotations.add_inline_annotations(color_swatches_padding, None); } let width = self.inner_width(doc); diff --git a/rustfmt.toml b/rustfmt.toml index e69de29bb2d1..8153a3d0b763 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -0,0 +1 @@ +style_edition = "2021"