[isort] Add support for length-sort settings (#8841)

## Summary

Closes #1567.

Add both `length-sort` and `length-sort-straight` settings for isort.

Here are a few notable points:
- The length is determined using the
[`unicode_width`](https://crates.io/crates/unicode-width) crate, i.e. we
are talking about displayed length (this is explicitly mentioned in the
description of the setting)
- The dots are taken into account in the length to be compatible with
the original isort
- I had to reorder a few fields of the module key struct for it all to
make sense (notably the `force_to_top` field is now the first one)

## Test Plan

I added tests for the following cases:
- Basic tests for length-sort with ASCII characters only
- Tests with non-ASCII characters
- Tests with relative imports
- Tests for length-sort-straight
This commit is contained in:
Joffrey Bluthé 2023-11-28 07:00:37 +01:00 committed by GitHub
parent ed14fd9163
commit 578ddf1bb1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 417 additions and 12 deletions

View file

@ -2047,6 +2047,40 @@ pub struct IsortOptions {
)]
pub from_first: Option<bool>,
/// Sort imports by their string length, such that shorter imports appear
/// before longer imports. For example, by default, imports will be sorted
/// alphabetically, as in:
/// ```python
/// import collections
/// import os
/// ```
///
/// Setting `length-sort = true` will instead sort such that shorter imports
/// appear before longer imports, as in:
/// ```python
/// import os
/// import collections
/// ```
#[option(
default = r#"false"#,
value_type = "bool",
example = r#"
length-sort = true
"#
)]
pub length_sort: Option<bool>,
/// Sort straight imports by their string length. Similar to `length-sort`,
/// but applies only to straight imports and doesn't affect `from` imports.
#[option(
default = r#"false"#,
value_type = "bool",
example = r#"
length-sort-straight = true
"#
)]
pub length_sort_straight: Option<bool>,
// Tables are required to go last.
/// A list of mappings from section names to modules.
/// By default custom sections are output last, but this can be overridden with `section-order`.
@ -2234,6 +2268,8 @@ impl IsortOptions {
section_order,
no_sections,
from_first,
length_sort: self.length_sort.unwrap_or(false),
length_sort_straight: self.length_sort_straight.unwrap_or(false),
})
}
}