Skip to content

Commit 338d8e7

Browse files
fix
1 parent bfb716a commit 338d8e7

File tree

4 files changed

+45
-9
lines changed

4 files changed

+45
-9
lines changed

pyrefly/lib/commands/infer.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use crate::commands::files::get_project_config_for_current_dir;
2525
use crate::commands::util::CommandExitStatus;
2626
use crate::config::error_kind::ErrorKind;
2727
use crate::state::ide::insert_import_edit_with_forced_import_format;
28+
use crate::state::ide::ImportEdit;
2829
use crate::state::lsp::AnnotationKind;
2930
use crate::state::lsp::ParameterAnnotation;
3031
use crate::state::require::Require;

pyrefly/lib/state/ide.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ use ruff_python_ast::Expr;
1616
use ruff_python_ast::ModModule;
1717
use ruff_python_ast::helpers::is_docstring_stmt;
1818
use ruff_python_ast::name::Name;
19+
use ruff_python_ast::Stmt;
20+
use ruff_python_ast::StmtImportFrom;
1921
use ruff_text_size::Ranged;
2022
use ruff_text_size::TextRange;
2123
use ruff_text_size::TextSize;
@@ -32,6 +34,13 @@ use crate::state::lsp::ImportFormat;
3234

3335
const KEY_TO_DEFINITION_INITIAL_GAS: Gas = Gas::new(100);
3436

37+
#[derive(Clone, Debug, PartialEq, Eq)]
38+
pub struct ImportEdit {
39+
pub position: TextSize,
40+
pub insert_text: String,
41+
pub display_text: String,
42+
}
43+
3544
pub enum IntermediateDefinition {
3645
Local(Export),
3746
NamedImport(TextRange, ModuleName, Name, Option<TextRange>),
@@ -242,6 +251,25 @@ pub fn insert_import_edit_with_forced_import_format(
242251
} else {
243252
handle_to_import_from.module()
244253
};
254+
let display_text = format!(
255+
"from {} import {}",
256+
module_name_to_import.as_str(),
257+
export_name
258+
);
259+
if let Some((position, insert_text)) =
260+
try_extend_existing_from_import(ast, module_name_to_import.as_str(), export_name)
261+
{
262+
return ImportEdit {
263+
position,
264+
insert_text,
265+
display_text,
266+
};
267+
}
268+
let position = if let Some(first_stmt) = ast.body.iter().find(|stmt| !is_docstring_stmt(stmt)) {
269+
first_stmt.range().start()
270+
} else {
271+
ast.range.end()
272+
};
245273
let insert_text = format!(
246274
"from {} import {}\n",
247275
module_name_to_import.as_str(),

pyrefly/lib/state/lsp.rs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1915,9 +1915,15 @@ impl<'a> Transaction<'a> {
19151915
unknown_name,
19161916
import_format,
19171917
);
1918-
let range = TextRange::at(position, TextSize::new(0));
1919-
let title = format!("Insert import: `{}`", insert_text.trim());
1920-
code_actions.push((title, module_info.dupe(), range, insert_text));
1918+
let range = TextRange::at(import_edit.position, TextSize::new(0));
1919+
let title =
1920+
format!("Insert import: `{}`", import_edit.display_text);
1921+
code_actions.push((
1922+
title,
1923+
module_info.dupe(),
1924+
range,
1925+
import_edit.insert_text,
1926+
));
19211927
}
19221928

19231929
for module_name in self.search_modules_fuzzy(unknown_name) {
@@ -2445,8 +2451,11 @@ impl<'a> Transaction<'a> {
24452451
import_format,
24462452
);
24472453
let import_text_edit = TextEdit {
2448-
range: module_info.to_lsp_range(TextRange::at(position, TextSize::new(0))),
2449-
new_text: insert_text.clone(),
2454+
range: module_info.to_lsp_range(TextRange::at(
2455+
import_edit.position,
2456+
TextSize::new(0),
2457+
)),
2458+
new_text: import_edit.insert_text.clone(),
24502459
};
24512460
(insert_text, Some(vec![import_text_edit]), module_name)
24522461
};

pyrefly/lib/test/lsp/code_actions.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -210,8 +210,7 @@ fn insertion_test_duplicate_imports() {
210210
],
211211
get_test_report,
212212
);
213-
// The insertion won't attempt to merge imports from the same module.
214-
// It's not illegal, but it would be nice if we do merge.
213+
// When another import from the same module already exists, we should append to it.
215214
assert_eq!(
216215
r#"
217216
# a.py
@@ -227,8 +226,7 @@ from a import another_thing
227226
my_export
228227
# ^
229228
## After:
230-
from a import my_export
231-
from a import another_thing
229+
from a import another_thing, my_export
232230
my_export
233231
# ^
234232
"#

0 commit comments

Comments
 (0)