Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pylight/src/parser/ruff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ impl<'a> SymbolExtractor<'a> {
let location = self
.source_code
.source_location(offset.into(), ruff_source_file::PositionEncoding::Utf8);
// Both line and column are 1-based in Ruff
(location.line.get(), location.character_offset.get())
// Ruff returns 1-based line and column, but we need 0-based column for compatibility
(location.line.get(), location.character_offset.get() - 1)
}
}

Expand Down
45 changes: 45 additions & 0 deletions pylight/src/parser/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,49 @@ class MyClass:
.iter()
.any(|s| s.name == "value" && s.kind == SymbolKind::Method));
}

#[test]
fn test_column_positions() {
use crate::parser::{create_parser, ParserBackend};

// Test both parser backends
for backend in [ParserBackend::TreeSitter, ParserBackend::Ruff] {
let parser = create_parser(backend).unwrap();

// Test function column position
let code = "def my_func():\n pass";
let symbols = parser.parse_file(Path::new("test.py"), code).unwrap();
assert_eq!(symbols.len(), 1);
assert_eq!(symbols[0].name, "my_func");
assert_eq!(symbols[0].line, 1);
assert_eq!(
symbols[0].column, 4,
"Function name should start at column 4 (0-based) for parser {:?}",
backend
);

// Test class column position
let code = "class MyClass:\n pass";
let symbols = parser.parse_file(Path::new("test.py"), code).unwrap();
assert_eq!(symbols.len(), 1);
assert_eq!(symbols[0].name, "MyClass");
assert_eq!(symbols[0].line, 1);
assert_eq!(
symbols[0].column, 6,
"Class name should start at column 6 (0-based) for parser {:?}",
backend
);

// Test indented method column position
let code = "class MyClass:\n def my_method(self):\n pass";
let symbols = parser.parse_file(Path::new("test.py"), code).unwrap();
let method = symbols.iter().find(|s| s.name == "my_method").unwrap();
assert_eq!(method.line, 2);
assert_eq!(
method.column, 8,
"Method name should start at column 8 (0-based) for parser {:?}",
backend
);
}
}
}
Loading