From 659db742e3f9fe4438fad31a2f60159a5eea42ac Mon Sep 17 00:00:00 2001 From: nolan Date: Mon, 22 Apr 2024 20:04:33 -0400 Subject: [PATCH 01/10] hover menu support --- .../src/server/api/requests/hover.rs | 131 ++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 crates/ruff_server/src/server/api/requests/hover.rs diff --git a/crates/ruff_server/src/server/api/requests/hover.rs b/crates/ruff_server/src/server/api/requests/hover.rs new file mode 100644 index 0000000000000..08fddcdcf54a8 --- /dev/null +++ b/crates/ruff_server/src/server/api/requests/hover.rs @@ -0,0 +1,131 @@ +use crate::server::{client::Notifier, Result}; +use crate::session::DocumentSnapshot; +use lsp_types::{self as types, request as req}; +use regex::Regex; +use ruff_diagnostics::FixAvailability; +use ruff_linter::registry::{Linter, Rule, RuleNamespace}; + +pub(crate) struct Hover; + +impl super::RequestHandler for Hover { + type RequestType = req::HoverRequest; +} + +impl super::BackgroundDocumentRequestHandler for Hover { + fn document_url(params: &types::HoverParams) -> std::borrow::Cow { + let url = params + .text_document_position_params + .text_document + .uri + .clone(); + std::borrow::Cow::Owned(url) + } + fn run_with_snapshot( + snapshot: DocumentSnapshot, + _notifier: Notifier, + params: types::HoverParams, + ) -> Result> { + hover(&snapshot, ¶ms.text_document_position_params) + } +} + +#[allow(clippy::unnecessary_wraps)] +pub(crate) fn hover( + snapshot: &DocumentSnapshot, + position: &types::TextDocumentPositionParams, +) -> Result> { + let doc: &str = snapshot.document().contents(); + let binding = String::from(doc); + let line = binding.lines().nth(position.position.line as usize); + let line = line.unwrap(); + + if !line.contains("noqa") { + return Ok(None); // No noqa in line + } + + // Get the list of codes. + let re = Regex::new(r"(?i:# (?:(?:ruff|flake8): )?(?Pnoqa))(?::\s?(?P([A-Z]+[0-9]+(?:[,\s]+)?)+))?").unwrap(); + let caps = re.captures(line).unwrap(); + let codes = caps.name("codes").unwrap().as_str(); + + // Get the word under the cursor. + let pos = position.position.character as usize; + let words: Vec<&str> = line.split(' ').collect(); + let mut start = 0; + let mut word = ""; + for &w in &words { + let end = start + w.len(); + if pos >= start && pos < end { + let w = w.trim_end_matches(','); + word = w; + break; + } + start = end + 1; + } + + tracing::warn!("codes: {}", codes); + tracing::warn!("word: {}", word); + if !codes.contains(word) || word.is_empty() { + return Ok(None); // Cursor was not over a code. + } + + // Get rule for the code under the cursor. + let rule = Rule::from_code(word); + let output = if let Ok(rule) = rule { + format_rule_text(rule) + } else { + format!("{word}: Rule not found") + }; + + let hover = types::Hover { + contents: types::HoverContents::Markup(types::MarkupContent { + kind: types::MarkupKind::Markdown, + value: output, + }), + range: None, + }; + + Ok(Some(hover)) +} + +fn format_rule_text(rule: Rule) -> String { + let mut output = String::new(); + output.push_str(&format!("# {} ({})", rule.as_ref(), rule.noqa_code())); + output.push('\n'); + output.push('\n'); + + let (linter, _) = Linter::parse_code(&rule.noqa_code().to_string()).unwrap(); + output.push_str(&format!("Derived from the **{}** linter.", linter.name())); + output.push('\n'); + output.push('\n'); + + let fix_availability = rule.fixable(); + if matches!( + fix_availability, + FixAvailability::Always | FixAvailability::Sometimes + ) { + output.push_str(&fix_availability.to_string()); + output.push('\n'); + output.push('\n'); + } + + //if rule.is_preview() || rule.is_nursery() { + //output.push_str( + //r"This rule is in preview and is not stable. The `--preview` flag is required for use.", + //); + //output.push('\n'); + //output.push('\n'); + //} + + if let Some(explanation) = rule.explanation() { + output.push_str(explanation.trim()); + } else { + output.push_str("Something went wrong."); + //output.push_str("Message formats:"); + //for format in rule.message_formats() { + //output.push('\n'); + //output.push_str(&format!("* {format}")); + //} + } + output +} From 9d46417791189a1fd9ee555b91a186faabeccf55 Mon Sep 17 00:00:00 2001 From: nolan Date: Mon, 22 Apr 2024 20:12:36 -0400 Subject: [PATCH 02/10] Hover menu support (forgot some files last time) --- Cargo.lock | 79 ++++++++++--------- crates/ruff_server/Cargo.toml | 1 + crates/ruff_server/src/server.rs | 1 + crates/ruff_server/src/server/api.rs | 3 + crates/ruff_server/src/server/api/requests.rs | 2 + 5 files changed, 47 insertions(+), 39 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8b8f9fec2f26e..4980405519d4d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -347,7 +347,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.59", ] [[package]] @@ -371,9 +371,9 @@ dependencies = [ [[package]] name = "codspeed" -version = "2.5.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "735f16ee0fc63cb90596cd7b57ce481522adfe1714f95bc04a94d4f4b0a06a6d" +checksum = "655a6d8e698ef8de25b6fb160dc904d98cf3642df48fae8bb05711db1893f47d" dependencies = [ "colored", "libc", @@ -382,9 +382,9 @@ dependencies = [ [[package]] name = "codspeed-criterion-compat" -version = "2.5.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572ca9c8ad460591b40aad63c99d6746aa3c532f979175344eb015389499860c" +checksum = "cb377d73b85084b1ca5615e42fdbf3b52631d6d8feda4be6dfc2150646f53cea" dependencies = [ "codspeed", "colored", @@ -578,7 +578,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.10.0", - "syn 2.0.60", + "syn 2.0.59", ] [[package]] @@ -589,7 +589,7 @@ checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" dependencies = [ "darling_core", "quote", - "syn 2.0.60", + "syn 2.0.59", ] [[package]] @@ -1054,7 +1054,7 @@ dependencies = [ "Inflector", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.59", ] [[package]] @@ -1201,7 +1201,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a5011f2d59093de14a4a90e01b9d85dee9276e58a25f0107dcee167dd601be0" dependencies = [ "quote", - "syn 2.0.60", + "syn 2.0.59", ] [[package]] @@ -1613,7 +1613,7 @@ checksum = "52a40bc70c2c58040d2d8b167ba9a5ff59fc9dab7ad44771cfde3dcfde7a09c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.59", ] [[package]] @@ -1640,9 +1640,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.81" +version = "1.0.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" +checksum = "a56dea16b0a29e94408b9aa5e2940a4eedbd128a1ba20e8f7ae60fd3d465af0e" dependencies = [ "unicode-ident", ] @@ -1825,7 +1825,7 @@ dependencies = [ "pmutil", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.59", ] [[package]] @@ -2075,7 +2075,7 @@ dependencies = [ "proc-macro2", "quote", "ruff_python_trivia", - "syn 2.0.60", + "syn 2.0.59", ] [[package]] @@ -2262,6 +2262,7 @@ dependencies = [ "libc", "lsp-server", "lsp-types", + "regex", "ruff_diagnostics", "ruff_formatter", "ruff_linter", @@ -2492,9 +2493,9 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "serde" -version = "1.0.198" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" dependencies = [ "serde_derive", ] @@ -2512,13 +2513,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.198" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.59", ] [[package]] @@ -2534,9 +2535,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.116" +version = "1.0.115" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" +checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" dependencies = [ "itoa", "ryu", @@ -2551,7 +2552,7 @@ checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.59", ] [[package]] @@ -2592,7 +2593,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.59", ] [[package]] @@ -2689,7 +2690,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.60", + "syn 2.0.59", ] [[package]] @@ -2711,9 +2712,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.60" +version = "2.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" +checksum = "4a6531ffc7b071655e4ce2e04bd464c4830bb585a61cabb96cf808f05172615a" dependencies = [ "proc-macro2", "quote", @@ -2773,7 +2774,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.59", ] [[package]] @@ -2784,28 +2785,28 @@ checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.59", "test-case-core", ] [[package]] name = "thiserror" -version = "1.0.59" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa" +checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.59" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66" +checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.59", ] [[package]] @@ -2917,7 +2918,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.59", ] [[package]] @@ -3147,7 +3148,7 @@ checksum = "9881bea7cbe687e36c9ab3b778c36cd0487402e270304e8b1296d5085303c1a2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.59", ] [[package]] @@ -3232,7 +3233,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.59", "wasm-bindgen-shared", ] @@ -3266,7 +3267,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.59", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3299,7 +3300,7 @@ checksum = "b7f89739351a2e03cb94beb799d47fb2cac01759b40ec441f7de39b00cbf7ef0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.59", ] [[package]] @@ -3561,7 +3562,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.59", ] [[package]] diff --git a/crates/ruff_server/Cargo.toml b/crates/ruff_server/Cargo.toml index 24297c970717f..a93430d6eb0d3 100644 --- a/crates/ruff_server/Cargo.toml +++ b/crates/ruff_server/Cargo.toml @@ -36,6 +36,7 @@ serde = { workspace = true } serde_json = { workspace = true } tracing = { workspace = true } walkdir = { workspace = true } +regex = { workspace = true } [dev-dependencies] insta = { workspace = true } diff --git a/crates/ruff_server/src/server.rs b/crates/ruff_server/src/server.rs index 647e42f353eab..e9944db053c63 100644 --- a/crates/ruff_server/src/server.rs +++ b/crates/ruff_server/src/server.rs @@ -257,6 +257,7 @@ impl Server { }, }, )), + hover_provider: Some(types::HoverProviderCapability::Simple(true)), text_document_sync: Some(TextDocumentSyncCapability::Options( TextDocumentSyncOptions { open_close: Some(true), diff --git a/crates/ruff_server/src/server/api.rs b/crates/ruff_server/src/server/api.rs index 81e969a5a1ac8..610774ced0171 100644 --- a/crates/ruff_server/src/server/api.rs +++ b/crates/ruff_server/src/server/api.rs @@ -48,6 +48,9 @@ pub(super) fn request<'a>(req: server::Request) -> Task<'a> { request::FormatRange::METHOD => { background_request_task::(req, BackgroundSchedule::Fmt) } + request::Hover::METHOD => { + background_request_task::(req, BackgroundSchedule::Worker) + } method => { tracing::warn!("Received request {method} which does not have a handler"); return Task::nothing(); diff --git a/crates/ruff_server/src/server/api/requests.rs b/crates/ruff_server/src/server/api/requests.rs index 3713ef536f592..049f396f639f2 100644 --- a/crates/ruff_server/src/server/api/requests.rs +++ b/crates/ruff_server/src/server/api/requests.rs @@ -4,6 +4,7 @@ mod diagnostic; mod execute_command; mod format; mod format_range; +mod hover; use super::{ define_document_url, @@ -15,5 +16,6 @@ pub(super) use diagnostic::DocumentDiagnostic; pub(super) use execute_command::ExecuteCommand; pub(super) use format::Format; pub(super) use format_range::FormatRange; +pub(super) use hover::Hover; type FormatResponse = Option>; From 5718e6456b0e89731abbbac3b41e60852871d843 Mon Sep 17 00:00:00 2001 From: nolan Date: Mon, 22 Apr 2024 20:57:50 -0400 Subject: [PATCH 03/10] Remove logging from debugging --- crates/ruff_server/src/server/api/requests/hover.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/crates/ruff_server/src/server/api/requests/hover.rs b/crates/ruff_server/src/server/api/requests/hover.rs index 08fddcdcf54a8..78d8851253104 100644 --- a/crates/ruff_server/src/server/api/requests/hover.rs +++ b/crates/ruff_server/src/server/api/requests/hover.rs @@ -63,8 +63,6 @@ pub(crate) fn hover( start = end + 1; } - tracing::warn!("codes: {}", codes); - tracing::warn!("word: {}", word); if !codes.contains(word) || word.is_empty() { return Ok(None); // Cursor was not over a code. } From cb4521b3198cc4af6e47cc9b88c3ea5205024f32 Mon Sep 17 00:00:00 2001 From: nolan Date: Tue, 23 Apr 2024 08:36:32 -0400 Subject: [PATCH 04/10] Revert Cargo.lock --- Cargo.lock | 79 +++++++++++++++++++++++++++--------------------------- 1 file changed, 39 insertions(+), 40 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4980405519d4d..8b8f9fec2f26e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -347,7 +347,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.60", ] [[package]] @@ -371,9 +371,9 @@ dependencies = [ [[package]] name = "codspeed" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "655a6d8e698ef8de25b6fb160dc904d98cf3642df48fae8bb05711db1893f47d" +checksum = "735f16ee0fc63cb90596cd7b57ce481522adfe1714f95bc04a94d4f4b0a06a6d" dependencies = [ "colored", "libc", @@ -382,9 +382,9 @@ dependencies = [ [[package]] name = "codspeed-criterion-compat" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb377d73b85084b1ca5615e42fdbf3b52631d6d8feda4be6dfc2150646f53cea" +checksum = "572ca9c8ad460591b40aad63c99d6746aa3c532f979175344eb015389499860c" dependencies = [ "codspeed", "colored", @@ -578,7 +578,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.10.0", - "syn 2.0.59", + "syn 2.0.60", ] [[package]] @@ -589,7 +589,7 @@ checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" dependencies = [ "darling_core", "quote", - "syn 2.0.59", + "syn 2.0.60", ] [[package]] @@ -1054,7 +1054,7 @@ dependencies = [ "Inflector", "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.60", ] [[package]] @@ -1201,7 +1201,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a5011f2d59093de14a4a90e01b9d85dee9276e58a25f0107dcee167dd601be0" dependencies = [ "quote", - "syn 2.0.59", + "syn 2.0.60", ] [[package]] @@ -1613,7 +1613,7 @@ checksum = "52a40bc70c2c58040d2d8b167ba9a5ff59fc9dab7ad44771cfde3dcfde7a09c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.60", ] [[package]] @@ -1640,9 +1640,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.80" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56dea16b0a29e94408b9aa5e2940a4eedbd128a1ba20e8f7ae60fd3d465af0e" +checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" dependencies = [ "unicode-ident", ] @@ -1825,7 +1825,7 @@ dependencies = [ "pmutil", "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.60", ] [[package]] @@ -2075,7 +2075,7 @@ dependencies = [ "proc-macro2", "quote", "ruff_python_trivia", - "syn 2.0.59", + "syn 2.0.60", ] [[package]] @@ -2262,7 +2262,6 @@ dependencies = [ "libc", "lsp-server", "lsp-types", - "regex", "ruff_diagnostics", "ruff_formatter", "ruff_linter", @@ -2493,9 +2492,9 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "serde" -version = "1.0.197" +version = "1.0.198" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc" dependencies = [ "serde_derive", ] @@ -2513,13 +2512,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.198" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.60", ] [[package]] @@ -2535,9 +2534,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.115" +version = "1.0.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" +checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" dependencies = [ "itoa", "ryu", @@ -2552,7 +2551,7 @@ checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.60", ] [[package]] @@ -2593,7 +2592,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.60", ] [[package]] @@ -2690,7 +2689,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.59", + "syn 2.0.60", ] [[package]] @@ -2712,9 +2711,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.59" +version = "2.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a6531ffc7b071655e4ce2e04bd464c4830bb585a61cabb96cf808f05172615a" +checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" dependencies = [ "proc-macro2", "quote", @@ -2774,7 +2773,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.60", ] [[package]] @@ -2785,28 +2784,28 @@ checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.60", "test-case-core", ] [[package]] name = "thiserror" -version = "1.0.58" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" +checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.58" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" +checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.60", ] [[package]] @@ -2918,7 +2917,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.60", ] [[package]] @@ -3148,7 +3147,7 @@ checksum = "9881bea7cbe687e36c9ab3b778c36cd0487402e270304e8b1296d5085303c1a2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.60", ] [[package]] @@ -3233,7 +3232,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.60", "wasm-bindgen-shared", ] @@ -3267,7 +3266,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.60", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3300,7 +3299,7 @@ checksum = "b7f89739351a2e03cb94beb799d47fb2cac01759b40ec441f7de39b00cbf7ef0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.60", ] [[package]] @@ -3562,7 +3561,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.60", ] [[package]] From e8b46611f0eb86bd30d43728b910687213598192 Mon Sep 17 00:00:00 2001 From: nolan Date: Tue, 23 Apr 2024 08:51:09 -0400 Subject: [PATCH 05/10] Borrow url --- crates/ruff_server/src/server/api/requests/hover.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/crates/ruff_server/src/server/api/requests/hover.rs b/crates/ruff_server/src/server/api/requests/hover.rs index 78d8851253104..9e8e5e5019437 100644 --- a/crates/ruff_server/src/server/api/requests/hover.rs +++ b/crates/ruff_server/src/server/api/requests/hover.rs @@ -13,12 +13,7 @@ impl super::RequestHandler for Hover { impl super::BackgroundDocumentRequestHandler for Hover { fn document_url(params: &types::HoverParams) -> std::borrow::Cow { - let url = params - .text_document_position_params - .text_document - .uri - .clone(); - std::borrow::Cow::Owned(url) + std::borrow::Cow::Borrowed(¶ms.text_document_position_params.text_document.uri) } fn run_with_snapshot( snapshot: DocumentSnapshot, From c94030f98c5383d371ddc13101d1dbce644f7a45 Mon Sep 17 00:00:00 2001 From: nolan Date: Tue, 23 Apr 2024 11:01:44 -0400 Subject: [PATCH 06/10] Simplify hover function; fixed unnecessary wraps --- .../src/server/api/requests/hover.rs | 67 +++++++++---------- 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/crates/ruff_server/src/server/api/requests/hover.rs b/crates/ruff_server/src/server/api/requests/hover.rs index 9e8e5e5019437..8886c4311ce95 100644 --- a/crates/ruff_server/src/server/api/requests/hover.rs +++ b/crates/ruff_server/src/server/api/requests/hover.rs @@ -1,9 +1,10 @@ -use crate::server::{client::Notifier, Result}; +use crate::server::{ client::Notifier, Result }; use crate::session::DocumentSnapshot; use lsp_types::{self as types, request as req}; use regex::Regex; use ruff_diagnostics::FixAvailability; use ruff_linter::registry::{Linter, Rule, RuleNamespace}; +use ruff_source_file::OneIndexed; pub(crate) struct Hover; @@ -20,54 +21,52 @@ impl super::BackgroundDocumentRequestHandler for Hover { _notifier: Notifier, params: types::HoverParams, ) -> Result> { - hover(&snapshot, ¶ms.text_document_position_params) + Ok(hover(&snapshot, ¶ms.text_document_position_params)) } } -#[allow(clippy::unnecessary_wraps)] pub(crate) fn hover( snapshot: &DocumentSnapshot, position: &types::TextDocumentPositionParams, -) -> Result> { - let doc: &str = snapshot.document().contents(); - let binding = String::from(doc); - let line = binding.lines().nth(position.position.line as usize); - let line = line.unwrap(); +) -> Option { + let document = snapshot.document(); + let line_number: usize = position + .position + .line + .try_into() + .expect("line number should fit within a usize"); + let line_range = document.index().line_range( + OneIndexed::from_zero_indexed(line_number), + document.contents(), + ); + + let line = &document.contents()[line_range]; if !line.contains("noqa") { - return Ok(None); // No noqa in line + return None; // No noqa in line } // Get the list of codes. - let re = Regex::new(r"(?i:# (?:(?:ruff|flake8): )?(?Pnoqa))(?::\s?(?P([A-Z]+[0-9]+(?:[,\s]+)?)+))?").unwrap(); - let caps = re.captures(line).unwrap(); - let codes = caps.name("codes").unwrap().as_str(); - - // Get the word under the cursor. - let pos = position.position.character as usize; - let words: Vec<&str> = line.split(' ').collect(); - let mut start = 0; - let mut word = ""; - for &w in &words { - let end = start + w.len(); - if pos >= start && pos < end { - let w = w.trim_end_matches(','); - word = w; - break; - } - start = end + 1; - } - - if !codes.contains(word) || word.is_empty() { - return Ok(None); // Cursor was not over a code. - } + let noqa_regex = Regex::new(r"(?i:# (?:(?:ruff|flake8): )?(?Pnoqa))(?::\s?(?P([A-Z]+[0-9]+(?:[,\s]+)?)+))?").unwrap(); + let noqa_captures = noqa_regex.captures(line)?; + let codes_match = noqa_captures.name("code")?; + let codes_start = codes_match.start(); + let code_regex = Regex::new(r"[A-Z]+[0-9]+").unwrap(); + let cursor: usize = position + .position + .character + .try_into() + .expect("column number should fit within a usize"); + let word = code_regex.find_iter(codes_match.as_str()).find(|code| { + cursor > (code.start() + codes_start) && cursor <= (code.end() + codes_start) + })?; // Get rule for the code under the cursor. - let rule = Rule::from_code(word); + let rule = Rule::from_code(word.as_str()); let output = if let Ok(rule) = rule { format_rule_text(rule) } else { - format!("{word}: Rule not found") + format!("{}: Rule not found", word.as_str()) }; let hover = types::Hover { @@ -78,7 +77,7 @@ pub(crate) fn hover( range: None, }; - Ok(Some(hover)) + Some(hover) } fn format_rule_text(rule: Rule) -> String { From 46e712eb296152d2065902e5e7c48887c0a3f713 Mon Sep 17 00:00:00 2001 From: nolan Date: Tue, 23 Apr 2024 12:56:59 -0400 Subject: [PATCH 07/10] Fixed check for code under cursor --- .../src/server/api/requests/hover.rs | 30 +++++++------------ 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/crates/ruff_server/src/server/api/requests/hover.rs b/crates/ruff_server/src/server/api/requests/hover.rs index 8886c4311ce95..4f930d298e398 100644 --- a/crates/ruff_server/src/server/api/requests/hover.rs +++ b/crates/ruff_server/src/server/api/requests/hover.rs @@ -1,4 +1,4 @@ -use crate::server::{ client::Notifier, Result }; +use crate::server::{client::Notifier, Result}; use crate::session::DocumentSnapshot; use lsp_types::{self as types, request as req}; use regex::Regex; @@ -42,14 +42,10 @@ pub(crate) fn hover( let line = &document.contents()[line_range]; - if !line.contains("noqa") { - return None; // No noqa in line - } - // Get the list of codes. let noqa_regex = Regex::new(r"(?i:# (?:(?:ruff|flake8): )?(?Pnoqa))(?::\s?(?P([A-Z]+[0-9]+(?:[,\s]+)?)+))?").unwrap(); let noqa_captures = noqa_regex.captures(line)?; - let codes_match = noqa_captures.name("code")?; + let codes_match = noqa_captures.name("codes")?; let codes_start = codes_match.start(); let code_regex = Regex::new(r"[A-Z]+[0-9]+").unwrap(); let cursor: usize = position @@ -58,7 +54,7 @@ pub(crate) fn hover( .try_into() .expect("column number should fit within a usize"); let word = code_regex.find_iter(codes_match.as_str()).find(|code| { - cursor > (code.start() + codes_start) && cursor <= (code.end() + codes_start) + cursor > (code.start() + codes_start) - 1 && cursor <= (code.end() + codes_start) - 1 })?; // Get rule for the code under the cursor. @@ -101,23 +97,17 @@ fn format_rule_text(rule: Rule) -> String { output.push('\n'); } - //if rule.is_preview() || rule.is_nursery() { - //output.push_str( - //r"This rule is in preview and is not stable. The `--preview` flag is required for use.", - //); - //output.push('\n'); - //output.push('\n'); - //} + if rule.is_preview() || rule.is_nursery() { + output.push_str(r"This rule is in preview and is not stable."); + output.push('\n'); + output.push('\n'); + } if let Some(explanation) = rule.explanation() { output.push_str(explanation.trim()); } else { - output.push_str("Something went wrong."); - //output.push_str("Message formats:"); - //for format in rule.message_formats() { - //output.push('\n'); - //output.push_str(&format!("* {format}")); - //} + tracing::warn!("Rule {} does not have an explanation", rule.noqa_code()); + output.push_str("An issue occurred: an explanation for this rule was not found."); } output } From 0beecd92a79e741a7097079c3a9449384fe8e621 Mon Sep 17 00:00:00 2001 From: nolan Date: Tue, 23 Apr 2024 13:08:43 -0400 Subject: [PATCH 08/10] Fixed Cargo.lock --- Cargo.lock | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.lock b/Cargo.lock index 8b8f9fec2f26e..73a117e1cf857 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2262,6 +2262,7 @@ dependencies = [ "libc", "lsp-server", "lsp-types", + "regex", "ruff_diagnostics", "ruff_formatter", "ruff_linter", From 8c4eb747f5ad1278e44b5e5e95b6ff9760444fbd Mon Sep 17 00:00:00 2001 From: nolan Date: Tue, 23 Apr 2024 13:14:09 -0400 Subject: [PATCH 09/10] Fix <= to < --- crates/ruff_server/src/server/api/requests/hover.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/ruff_server/src/server/api/requests/hover.rs b/crates/ruff_server/src/server/api/requests/hover.rs index 4f930d298e398..8fdb6acc9bfe5 100644 --- a/crates/ruff_server/src/server/api/requests/hover.rs +++ b/crates/ruff_server/src/server/api/requests/hover.rs @@ -54,7 +54,7 @@ pub(crate) fn hover( .try_into() .expect("column number should fit within a usize"); let word = code_regex.find_iter(codes_match.as_str()).find(|code| { - cursor > (code.start() + codes_start) - 1 && cursor <= (code.end() + codes_start) - 1 + cursor > (code.start() + codes_start) - 1 && cursor < (code.end() + codes_start) })?; // Get rule for the code under the cursor. From 8c3130e81f6fdd9a2189bcbc34edceabfd7a2b44 Mon Sep 17 00:00:00 2001 From: Jane Lewis Date: Tue, 23 Apr 2024 13:06:26 -0700 Subject: [PATCH 10/10] Simplify comparison --- crates/ruff_server/src/server/api/requests/hover.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/ruff_server/src/server/api/requests/hover.rs b/crates/ruff_server/src/server/api/requests/hover.rs index 8fdb6acc9bfe5..23a6c09c393b0 100644 --- a/crates/ruff_server/src/server/api/requests/hover.rs +++ b/crates/ruff_server/src/server/api/requests/hover.rs @@ -54,7 +54,7 @@ pub(crate) fn hover( .try_into() .expect("column number should fit within a usize"); let word = code_regex.find_iter(codes_match.as_str()).find(|code| { - cursor > (code.start() + codes_start) - 1 && cursor < (code.end() + codes_start) + cursor >= (code.start() + codes_start) && cursor < (code.end() + codes_start) })?; // Get rule for the code under the cursor.