Skip to content

Commit 378fe73

Browse files
authored
Don't show noqa hover for non-Python documents (#24040)
1 parent b5665bd commit 378fe73

File tree

1 file changed

+93
-1
lines changed
  • crates/ruff_server/src/server/api/requests

1 file changed

+93
-1
lines changed

crates/ruff_server/src/server/api/requests/hover.rs

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use lsp_types::{self as types, request as req};
55
use regex::Regex;
66
use ruff_linter::FixAvailability;
77
use ruff_linter::registry::{Linter, Rule, RuleNamespace};
8+
use ruff_python_ast::SourceType;
89
use ruff_source_file::OneIndexed;
910
use std::fmt::Write;
1011

@@ -31,7 +32,11 @@ pub(crate) fn hover(
3132
snapshot: &DocumentSnapshot,
3233
position: &types::TextDocumentPositionParams,
3334
) -> Option<types::Hover> {
34-
// Hover only operates on text documents or notebook cells
35+
// Don't show noqa hover for non-Python documents (e.g., markdown files).
36+
let SourceType::Python(_) = snapshot.query().source_type() else {
37+
return None;
38+
};
39+
3540
let document = snapshot
3641
.query()
3742
.as_single_document()
@@ -122,3 +127,90 @@ fn format_rule_text(rule: Rule) -> String {
122127
}
123128
output
124129
}
130+
131+
#[cfg(test)]
132+
mod tests {
133+
use lsp_types::{self as types, ClientCapabilities, Url};
134+
135+
use crate::session::{Client, GlobalOptions};
136+
use crate::{PositionEncoding, TextDocument, Workspace, Workspaces};
137+
138+
use super::*;
139+
140+
fn create_session_and_snapshot(
141+
file_name: &str,
142+
language_id: &str,
143+
content: &str,
144+
) -> (crate::Session, Url) {
145+
let (main_loop_sender, _) = crossbeam::channel::unbounded();
146+
let (client_sender, _) = crossbeam::channel::unbounded();
147+
let client = Client::new(main_loop_sender, client_sender);
148+
149+
let workspace_dir = std::env::temp_dir();
150+
let workspace_url = Url::from_file_path(&workspace_dir).unwrap();
151+
152+
let options = GlobalOptions::default();
153+
let global = options.into_settings(client.clone());
154+
155+
let mut session = crate::Session::new(
156+
&ClientCapabilities::default(),
157+
PositionEncoding::UTF16,
158+
global,
159+
&Workspaces::new(vec![
160+
Workspace::new(workspace_url).with_options(crate::ClientOptions::default()),
161+
]),
162+
&client,
163+
)
164+
.unwrap();
165+
166+
let file_url = Url::from_file_path(workspace_dir.join(file_name)).unwrap();
167+
let document = TextDocument::new(content.to_string(), 0).with_language_id(language_id);
168+
session.open_text_document(file_url.clone(), document);
169+
170+
(session, file_url)
171+
}
172+
173+
#[test]
174+
fn no_hover_for_markdown() {
175+
let (session, file_url) =
176+
create_session_and_snapshot("test.md", "markdown", "# noqa: RUF100\n");
177+
178+
let snapshot = session.take_snapshot(file_url.clone()).unwrap();
179+
180+
let position = types::TextDocumentPositionParams {
181+
text_document: types::TextDocumentIdentifier { uri: file_url },
182+
position: types::Position {
183+
line: 0,
184+
character: 9,
185+
},
186+
};
187+
188+
let result = hover(&snapshot, &position);
189+
assert!(
190+
result.is_none(),
191+
"Expected no hover for markdown file, got: {result:?}"
192+
);
193+
}
194+
195+
#[test]
196+
fn hover_for_python_noqa() {
197+
let (session, file_url) =
198+
create_session_and_snapshot("test.py", "python", "x = 1 # noqa: RUF100\n");
199+
200+
let snapshot = session.take_snapshot(file_url.clone()).unwrap();
201+
202+
let position = types::TextDocumentPositionParams {
203+
text_document: types::TextDocumentIdentifier { uri: file_url },
204+
position: types::Position {
205+
line: 0,
206+
character: 16,
207+
},
208+
};
209+
210+
let result = hover(&snapshot, &position);
211+
assert!(
212+
result.is_some(),
213+
"Expected hover tooltip for Python noqa comment"
214+
);
215+
}
216+
}

0 commit comments

Comments
 (0)