mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-26 11:59:35 +00:00
Unify line size settings between ruff and the formatter (#6873)
This commit is contained in:
parent
a6aa16630d
commit
e615870659
28 changed files with 227 additions and 190 deletions
|
@ -1,12 +1,13 @@
|
||||||
//! Extract Black configuration settings from a pyproject.toml.
|
//! Extract Black configuration settings from a pyproject.toml.
|
||||||
|
|
||||||
|
use ruff::line_width::LineLength;
|
||||||
use ruff::settings::types::PythonVersion;
|
use ruff::settings::types::PythonVersion;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Default)]
|
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Default)]
|
||||||
pub(crate) struct Black {
|
pub(crate) struct Black {
|
||||||
#[serde(alias = "line-length", alias = "line_length")]
|
#[serde(alias = "line-length", alias = "line_length")]
|
||||||
pub(crate) line_length: Option<usize>,
|
pub(crate) line_length: Option<LineLength>,
|
||||||
#[serde(alias = "target-version", alias = "target_version")]
|
#[serde(alias = "target-version", alias = "target_version")]
|
||||||
pub(crate) target_version: Option<Vec<PythonVersion>>,
|
pub(crate) target_version: Option<Vec<PythonVersion>>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
|
@ -119,10 +120,8 @@ pub(crate) fn convert(
|
||||||
"builtins" => {
|
"builtins" => {
|
||||||
options.builtins = Some(parser::parse_strings(value.as_ref()));
|
options.builtins = Some(parser::parse_strings(value.as_ref()));
|
||||||
}
|
}
|
||||||
"max-line-length" | "max_line_length" => match value.parse::<usize>() {
|
"max-line-length" | "max_line_length" => match LineLength::from_str(value) {
|
||||||
Ok(line_length) => {
|
Ok(line_length) => options.line_length = Some(line_length),
|
||||||
options.line_length = Some(LineLength::from(line_length));
|
|
||||||
}
|
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
warn_user!("Unable to parse '{key}' property: {e}");
|
warn_user!("Unable to parse '{key}' property: {e}");
|
||||||
}
|
}
|
||||||
|
@ -405,7 +404,7 @@ pub(crate) fn convert(
|
||||||
// Extract any settings from the existing `pyproject.toml`.
|
// Extract any settings from the existing `pyproject.toml`.
|
||||||
if let Some(black) = &external_config.black {
|
if let Some(black) = &external_config.black {
|
||||||
if let Some(line_length) = &black.line_length {
|
if let Some(line_length) = &black.line_length {
|
||||||
options.line_length = Some(LineLength::from(*line_length));
|
options.line_length = Some(*line_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(target_version) = &black.target_version {
|
if let Some(target_version) = &black.target_version {
|
||||||
|
@ -512,7 +511,7 @@ mod tests {
|
||||||
Some(vec![]),
|
Some(vec![]),
|
||||||
);
|
);
|
||||||
let expected = Pyproject::new(Options {
|
let expected = Pyproject::new(Options {
|
||||||
line_length: Some(LineLength::from(100)),
|
line_length: Some(LineLength::try_from(100).unwrap()),
|
||||||
..default_options([])
|
..default_options([])
|
||||||
});
|
});
|
||||||
assert_eq!(actual, expected);
|
assert_eq!(actual, expected);
|
||||||
|
@ -529,7 +528,7 @@ mod tests {
|
||||||
Some(vec![]),
|
Some(vec![]),
|
||||||
);
|
);
|
||||||
let expected = Pyproject::new(Options {
|
let expected = Pyproject::new(Options {
|
||||||
line_length: Some(LineLength::from(100)),
|
line_length: Some(LineLength::try_from(100).unwrap()),
|
||||||
..default_options([])
|
..default_options([])
|
||||||
});
|
});
|
||||||
assert_eq!(actual, expected);
|
assert_eq!(actual, expected);
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
//! Lint rules based on checking physical lines.
|
//! Lint rules based on checking physical lines.
|
||||||
use ruff_text_size::TextSize;
|
|
||||||
|
|
||||||
use ruff_diagnostics::Diagnostic;
|
use ruff_diagnostics::Diagnostic;
|
||||||
use ruff_python_codegen::Stylist;
|
use ruff_python_codegen::Stylist;
|
||||||
use ruff_python_index::Indexer;
|
use ruff_python_index::Indexer;
|
||||||
use ruff_source_file::{Locator, UniversalNewlines};
|
use ruff_source_file::{Locator, UniversalNewlines};
|
||||||
|
use ruff_text_size::TextSize;
|
||||||
|
|
||||||
use crate::registry::Rule;
|
use crate::registry::Rule;
|
||||||
use crate::rules::flake8_copyright::rules::missing_copyright_notice;
|
use crate::rules::flake8_copyright::rules::missing_copyright_notice;
|
||||||
|
@ -99,11 +98,10 @@ pub(crate) fn check_physical_lines(
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use ruff_python_parser::lexer::lex;
|
|
||||||
use ruff_python_parser::Mode;
|
|
||||||
|
|
||||||
use ruff_python_codegen::Stylist;
|
use ruff_python_codegen::Stylist;
|
||||||
use ruff_python_index::Indexer;
|
use ruff_python_index::Indexer;
|
||||||
|
use ruff_python_parser::lexer::lex;
|
||||||
|
use ruff_python_parser::Mode;
|
||||||
use ruff_source_file::Locator;
|
use ruff_source_file::Locator;
|
||||||
|
|
||||||
use crate::line_width::LineLength;
|
use crate::line_width::LineLength;
|
||||||
|
@ -132,7 +130,7 @@ mod tests {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
let line_length = LineLength::from(8);
|
let line_length = LineLength::try_from(8).unwrap();
|
||||||
assert_eq!(check_with_max_line_length(line_length), vec![]);
|
assert_eq!(check_with_max_line_length(line_length), vec![]);
|
||||||
assert_eq!(check_with_max_line_length(line_length), vec![]);
|
assert_eq!(check_with_max_line_length(line_length), vec![]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,30 +1,111 @@
|
||||||
|
use ruff_cache::{CacheKey, CacheKeyHasher};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::num::NonZeroU8;
|
use std::error::Error;
|
||||||
|
use std::hash::Hasher;
|
||||||
|
use std::num::{NonZeroU16, NonZeroU8, ParseIntError};
|
||||||
|
use std::str::FromStr;
|
||||||
use unicode_width::UnicodeWidthChar;
|
use unicode_width::UnicodeWidthChar;
|
||||||
|
|
||||||
use ruff_macros::CacheKey;
|
use ruff_macros::CacheKey;
|
||||||
|
|
||||||
/// The length of a line of text that is considered too long.
|
/// The length of a line of text that is considered too long.
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, CacheKey)]
|
///
|
||||||
|
/// The allowed range of values is 1..=320
|
||||||
|
#[derive(Clone, Copy, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
|
||||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||||
pub struct LineLength(usize);
|
pub struct LineLength(NonZeroU16);
|
||||||
|
|
||||||
impl Default for LineLength {
|
|
||||||
/// The default line length.
|
|
||||||
fn default() -> Self {
|
|
||||||
Self(88)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LineLength {
|
impl LineLength {
|
||||||
pub const fn get(&self) -> usize {
|
/// Maximum allowed value for a valid [`LineLength`]
|
||||||
self.0
|
pub const MAX: u16 = 320;
|
||||||
|
|
||||||
|
/// Return the numeric value for this [`LineLength`]
|
||||||
|
pub fn value(&self) -> u16 {
|
||||||
|
self.0.get()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<usize> for LineLength {
|
impl Default for LineLength {
|
||||||
fn from(value: usize) -> Self {
|
fn default() -> Self {
|
||||||
Self(value)
|
Self(NonZeroU16::new(88).unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CacheKey for LineLength {
|
||||||
|
fn cache_key(&self, state: &mut CacheKeyHasher) {
|
||||||
|
state.write_u16(self.0.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Error type returned when parsing a [`LineLength`] from a string fails
|
||||||
|
pub enum ParseLineWidthError {
|
||||||
|
/// The string could not be parsed as a valid [u16]
|
||||||
|
ParseError(ParseIntError),
|
||||||
|
/// The [u16] value of the string is not a valid [LineLength]
|
||||||
|
TryFromIntError(LineLengthFromIntError),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for ParseLineWidthError {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
std::fmt::Display::fmt(self, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for ParseLineWidthError {
|
||||||
|
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
ParseLineWidthError::ParseError(err) => std::fmt::Display::fmt(err, fmt),
|
||||||
|
ParseLineWidthError::TryFromIntError(err) => std::fmt::Display::fmt(err, fmt),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Error for ParseLineWidthError {}
|
||||||
|
|
||||||
|
impl FromStr for LineLength {
|
||||||
|
type Err = ParseLineWidthError;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
let value = u16::from_str(s).map_err(ParseLineWidthError::ParseError)?;
|
||||||
|
let value = Self::try_from(value).map_err(ParseLineWidthError::TryFromIntError)?;
|
||||||
|
Ok(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Error type returned when converting a u16 to a [`LineLength`] fails
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub struct LineLengthFromIntError(pub u16);
|
||||||
|
|
||||||
|
impl TryFrom<u16> for LineLength {
|
||||||
|
type Error = LineLengthFromIntError;
|
||||||
|
|
||||||
|
fn try_from(value: u16) -> Result<Self, Self::Error> {
|
||||||
|
match NonZeroU16::try_from(value) {
|
||||||
|
Ok(value) if value.get() <= Self::MAX => Ok(LineLength(value)),
|
||||||
|
Ok(_) | Err(_) => Err(LineLengthFromIntError(value)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for LineLengthFromIntError {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
writeln!(
|
||||||
|
f,
|
||||||
|
"The line width must be a value between 1 and {}.",
|
||||||
|
LineLength::MAX
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<LineLength> for u16 {
|
||||||
|
fn from(value: LineLength) -> Self {
|
||||||
|
value.0.get()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<LineLength> for NonZeroU16 {
|
||||||
|
fn from(value: LineLength) -> Self {
|
||||||
|
value.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +114,7 @@ impl From<usize> for LineLength {
|
||||||
/// This is used to determine if a line is too long.
|
/// This is used to determine if a line is too long.
|
||||||
/// It should be compared to a [`LineLength`].
|
/// It should be compared to a [`LineLength`].
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub struct LineWidth {
|
pub struct LineWidthBuilder {
|
||||||
/// The width of the line.
|
/// The width of the line.
|
||||||
width: usize,
|
width: usize,
|
||||||
/// The column of the line.
|
/// The column of the line.
|
||||||
|
@ -43,40 +124,40 @@ pub struct LineWidth {
|
||||||
tab_size: TabSize,
|
tab_size: TabSize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for LineWidth {
|
impl Default for LineWidthBuilder {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::new(TabSize::default())
|
Self::new(TabSize::default())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for LineWidth {
|
impl PartialEq for LineWidthBuilder {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.width == other.width
|
self.width == other.width
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Eq for LineWidth {}
|
impl Eq for LineWidthBuilder {}
|
||||||
|
|
||||||
impl PartialOrd for LineWidth {
|
impl PartialOrd for LineWidthBuilder {
|
||||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||||
Some(self.cmp(other))
|
Some(self.cmp(other))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ord for LineWidth {
|
impl Ord for LineWidthBuilder {
|
||||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||||
self.width.cmp(&other.width)
|
self.width.cmp(&other.width)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LineWidth {
|
impl LineWidthBuilder {
|
||||||
pub fn get(&self) -> usize {
|
pub fn get(&self) -> usize {
|
||||||
self.width
|
self.width
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new `LineWidth` with the given tab size.
|
/// Creates a new `LineWidth` with the given tab size.
|
||||||
pub fn new(tab_size: TabSize) -> Self {
|
pub fn new(tab_size: TabSize) -> Self {
|
||||||
LineWidth {
|
LineWidthBuilder {
|
||||||
width: 0,
|
width: 0,
|
||||||
column: 0,
|
column: 0,
|
||||||
tab_size,
|
tab_size,
|
||||||
|
@ -119,7 +200,7 @@ impl LineWidth {
|
||||||
|
|
||||||
/// Adds the given width to the line width.
|
/// Adds the given width to the line width.
|
||||||
/// Also adds the given width to the column.
|
/// Also adds the given width to the column.
|
||||||
/// It is generally better to use [`LineWidth::add_str`] or [`LineWidth::add_char`].
|
/// It is generally better to use [`LineWidthBuilder::add_str`] or [`LineWidthBuilder::add_char`].
|
||||||
/// The width and column should be the same for the corresponding text.
|
/// The width and column should be the same for the corresponding text.
|
||||||
/// Currently, this is only used to add spaces.
|
/// Currently, this is only used to add spaces.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
@ -130,15 +211,15 @@ impl LineWidth {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq<LineLength> for LineWidth {
|
impl PartialEq<LineLength> for LineWidthBuilder {
|
||||||
fn eq(&self, other: &LineLength) -> bool {
|
fn eq(&self, other: &LineLength) -> bool {
|
||||||
self.width == other.0
|
self.width == (other.value() as usize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialOrd<LineLength> for LineWidth {
|
impl PartialOrd<LineLength> for LineWidthBuilder {
|
||||||
fn partial_cmp(&self, other: &LineLength) -> Option<std::cmp::Ordering> {
|
fn partial_cmp(&self, other: &LineLength) -> Option<std::cmp::Ordering> {
|
||||||
self.width.partial_cmp(&other.0)
|
self.width.partial_cmp(&(other.value() as usize))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ use ruff_text_size::{Ranged, TextRange, TextSize};
|
||||||
|
|
||||||
use crate::fs::relativize_path;
|
use crate::fs::relativize_path;
|
||||||
use crate::jupyter::{Notebook, NotebookIndex};
|
use crate::jupyter::{Notebook, NotebookIndex};
|
||||||
use crate::line_width::{LineWidth, TabSize};
|
use crate::line_width::{LineWidthBuilder, TabSize};
|
||||||
use crate::message::diff::Diff;
|
use crate::message::diff::Diff;
|
||||||
use crate::message::{Emitter, EmitterContext, Message};
|
use crate::message::{Emitter, EmitterContext, Message};
|
||||||
use crate::registry::AsRule;
|
use crate::registry::AsRule;
|
||||||
|
@ -292,7 +292,7 @@ fn replace_whitespace(source: &str, annotation_range: TextRange) -> SourceCode {
|
||||||
let mut result = String::new();
|
let mut result = String::new();
|
||||||
let mut last_end = 0;
|
let mut last_end = 0;
|
||||||
let mut range = annotation_range;
|
let mut range = annotation_range;
|
||||||
let mut line_width = LineWidth::new(TabSize::default());
|
let mut line_width = LineWidthBuilder::new(TabSize::default());
|
||||||
|
|
||||||
for (index, c) in source.char_indices() {
|
for (index, c) in source.char_indices() {
|
||||||
let old_width = line_width.get();
|
let old_width = line_width.get();
|
||||||
|
|
|
@ -15,7 +15,7 @@ use ruff_python_trivia::{SimpleTokenKind, SimpleTokenizer};
|
||||||
use ruff_source_file::{Locator, UniversalNewlines};
|
use ruff_source_file::{Locator, UniversalNewlines};
|
||||||
|
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
use crate::line_width::LineWidth;
|
use crate::line_width::LineWidthBuilder;
|
||||||
use crate::registry::AsRule;
|
use crate::registry::AsRule;
|
||||||
use crate::rules::flake8_simplify::rules::fix_if;
|
use crate::rules::flake8_simplify::rules::fix_if;
|
||||||
|
|
||||||
|
@ -414,7 +414,7 @@ pub(crate) fn nested_if_statements(
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.universal_newlines()
|
.universal_newlines()
|
||||||
.all(|line| {
|
.all(|line| {
|
||||||
LineWidth::new(checker.settings.tab_size).add_str(&line)
|
LineWidthBuilder::new(checker.settings.tab_size).add_str(&line)
|
||||||
<= checker.settings.line_length
|
<= checker.settings.line_length
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
|
@ -660,7 +660,7 @@ pub(crate) fn use_ternary_operator(checker: &mut Checker, stmt: &Stmt) {
|
||||||
|
|
||||||
// Don't flag if the resulting expression would exceed the maximum line length.
|
// Don't flag if the resulting expression would exceed the maximum line length.
|
||||||
let line_start = checker.locator().line_start(stmt.start());
|
let line_start = checker.locator().line_start(stmt.start());
|
||||||
if LineWidth::new(checker.settings.tab_size)
|
if LineWidthBuilder::new(checker.settings.tab_size)
|
||||||
.add_str(&checker.locator().contents()[TextRange::new(line_start, stmt.start())])
|
.add_str(&checker.locator().contents()[TextRange::new(line_start, stmt.start())])
|
||||||
.add_str(&contents)
|
.add_str(&contents)
|
||||||
> checker.settings.line_length
|
> checker.settings.line_length
|
||||||
|
@ -964,7 +964,7 @@ pub(crate) fn use_dict_get_with_default(checker: &mut Checker, stmt_if: &ast::St
|
||||||
|
|
||||||
// Don't flag if the resulting expression would exceed the maximum line length.
|
// Don't flag if the resulting expression would exceed the maximum line length.
|
||||||
let line_start = checker.locator().line_start(stmt_if.start());
|
let line_start = checker.locator().line_start(stmt_if.start());
|
||||||
if LineWidth::new(checker.settings.tab_size)
|
if LineWidthBuilder::new(checker.settings.tab_size)
|
||||||
.add_str(&checker.locator().contents()[TextRange::new(line_start, stmt_if.start())])
|
.add_str(&checker.locator().contents()[TextRange::new(line_start, stmt_if.start())])
|
||||||
.add_str(&contents)
|
.add_str(&contents)
|
||||||
> checker.settings.line_length
|
> checker.settings.line_length
|
||||||
|
|
|
@ -9,7 +9,7 @@ use ruff_source_file::UniversalNewlines;
|
||||||
use ruff_text_size::{Ranged, TextRange};
|
use ruff_text_size::{Ranged, TextRange};
|
||||||
|
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
use crate::line_width::LineWidth;
|
use crate::line_width::LineWidthBuilder;
|
||||||
use crate::registry::AsRule;
|
use crate::registry::AsRule;
|
||||||
|
|
||||||
use super::fix_with;
|
use super::fix_with;
|
||||||
|
@ -142,7 +142,7 @@ pub(crate) fn multiple_with_statements(
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.universal_newlines()
|
.universal_newlines()
|
||||||
.all(|line| {
|
.all(|line| {
|
||||||
LineWidth::new(checker.settings.tab_size).add_str(&line)
|
LineWidthBuilder::new(checker.settings.tab_size).add_str(&line)
|
||||||
<= checker.settings.line_length
|
<= checker.settings.line_length
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,7 +10,7 @@ use ruff_python_ast::traversal;
|
||||||
use ruff_python_codegen::Generator;
|
use ruff_python_codegen::Generator;
|
||||||
|
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
use crate::line_width::LineWidth;
|
use crate::line_width::LineWidthBuilder;
|
||||||
use crate::registry::AsRule;
|
use crate::registry::AsRule;
|
||||||
|
|
||||||
/// ## What it does
|
/// ## What it does
|
||||||
|
@ -98,7 +98,7 @@ pub(crate) fn convert_for_loop_to_any_all(checker: &mut Checker, stmt: &Stmt) {
|
||||||
|
|
||||||
// Don't flag if the resulting expression would exceed the maximum line length.
|
// Don't flag if the resulting expression would exceed the maximum line length.
|
||||||
let line_start = checker.locator().line_start(stmt.start());
|
let line_start = checker.locator().line_start(stmt.start());
|
||||||
if LineWidth::new(checker.settings.tab_size)
|
if LineWidthBuilder::new(checker.settings.tab_size)
|
||||||
.add_str(&checker.locator().contents()[TextRange::new(line_start, stmt.start())])
|
.add_str(&checker.locator().contents()[TextRange::new(line_start, stmt.start())])
|
||||||
.add_str(&contents)
|
.add_str(&contents)
|
||||||
> checker.settings.line_length
|
> checker.settings.line_length
|
||||||
|
@ -180,7 +180,7 @@ pub(crate) fn convert_for_loop_to_any_all(checker: &mut Checker, stmt: &Stmt) {
|
||||||
|
|
||||||
// Don't flag if the resulting expression would exceed the maximum line length.
|
// Don't flag if the resulting expression would exceed the maximum line length.
|
||||||
let line_start = checker.locator().line_start(stmt.start());
|
let line_start = checker.locator().line_start(stmt.start());
|
||||||
if LineWidth::new(checker.settings.tab_size)
|
if LineWidthBuilder::new(checker.settings.tab_size)
|
||||||
.add_str(&checker.locator().contents()[TextRange::new(line_start, stmt.start())])
|
.add_str(&checker.locator().contents()[TextRange::new(line_start, stmt.start())])
|
||||||
.add_str(&contents)
|
.add_str(&contents)
|
||||||
> checker.settings.line_length
|
> checker.settings.line_length
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use ruff_python_codegen::Stylist;
|
use ruff_python_codegen::Stylist;
|
||||||
|
|
||||||
use crate::line_width::{LineLength, LineWidth};
|
use crate::line_width::{LineLength, LineWidthBuilder};
|
||||||
|
|
||||||
use super::types::{AliasData, CommentSet, ImportFromData, Importable};
|
use super::types::{AliasData, CommentSet, ImportFromData, Importable};
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ pub(crate) fn format_import_from(
|
||||||
comments: &CommentSet,
|
comments: &CommentSet,
|
||||||
aliases: &[(AliasData, CommentSet)],
|
aliases: &[(AliasData, CommentSet)],
|
||||||
line_length: LineLength,
|
line_length: LineLength,
|
||||||
indentation_width: LineWidth,
|
indentation_width: LineWidthBuilder,
|
||||||
stylist: &Stylist,
|
stylist: &Stylist,
|
||||||
force_wrap_aliases: bool,
|
force_wrap_aliases: bool,
|
||||||
is_first: bool,
|
is_first: bool,
|
||||||
|
@ -103,8 +103,8 @@ fn format_single_line(
|
||||||
aliases: &[(AliasData, CommentSet)],
|
aliases: &[(AliasData, CommentSet)],
|
||||||
is_first: bool,
|
is_first: bool,
|
||||||
stylist: &Stylist,
|
stylist: &Stylist,
|
||||||
indentation_width: LineWidth,
|
indentation_width: LineWidthBuilder,
|
||||||
) -> (String, LineWidth) {
|
) -> (String, LineWidthBuilder) {
|
||||||
let mut output = String::with_capacity(CAPACITY);
|
let mut output = String::with_capacity(CAPACITY);
|
||||||
let mut line_width = indentation_width;
|
let mut line_width = indentation_width;
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ use sorting::cmp_either_import;
|
||||||
use types::EitherImport::{Import, ImportFrom};
|
use types::EitherImport::{Import, ImportFrom};
|
||||||
use types::{AliasData, EitherImport, TrailingComma};
|
use types::{AliasData, EitherImport, TrailingComma};
|
||||||
|
|
||||||
use crate::line_width::{LineLength, LineWidth};
|
use crate::line_width::{LineLength, LineWidthBuilder};
|
||||||
use crate::rules::isort::categorize::KnownModules;
|
use crate::rules::isort::categorize::KnownModules;
|
||||||
use crate::rules::isort::types::ImportBlock;
|
use crate::rules::isort::types::ImportBlock;
|
||||||
use crate::settings::types::PythonVersion;
|
use crate::settings::types::PythonVersion;
|
||||||
|
@ -69,7 +69,7 @@ pub(crate) fn format_imports(
|
||||||
comments: Vec<Comment>,
|
comments: Vec<Comment>,
|
||||||
locator: &Locator,
|
locator: &Locator,
|
||||||
line_length: LineLength,
|
line_length: LineLength,
|
||||||
indentation_width: LineWidth,
|
indentation_width: LineWidthBuilder,
|
||||||
stylist: &Stylist,
|
stylist: &Stylist,
|
||||||
src: &[PathBuf],
|
src: &[PathBuf],
|
||||||
package: Option<&Path>,
|
package: Option<&Path>,
|
||||||
|
@ -179,7 +179,7 @@ pub(crate) fn format_imports(
|
||||||
fn format_import_block(
|
fn format_import_block(
|
||||||
block: ImportBlock,
|
block: ImportBlock,
|
||||||
line_length: LineLength,
|
line_length: LineLength,
|
||||||
indentation_width: LineWidth,
|
indentation_width: LineWidthBuilder,
|
||||||
stylist: &Stylist,
|
stylist: &Stylist,
|
||||||
src: &[PathBuf],
|
src: &[PathBuf],
|
||||||
package: Option<&Path>,
|
package: Option<&Path>,
|
||||||
|
|
|
@ -12,7 +12,7 @@ use ruff_python_trivia::{leading_indentation, textwrap::indent, PythonWhitespace
|
||||||
use ruff_source_file::{Locator, UniversalNewlines};
|
use ruff_source_file::{Locator, UniversalNewlines};
|
||||||
use ruff_text_size::{Ranged, TextRange};
|
use ruff_text_size::{Ranged, TextRange};
|
||||||
|
|
||||||
use crate::line_width::LineWidth;
|
use crate::line_width::LineWidthBuilder;
|
||||||
use crate::registry::AsRule;
|
use crate::registry::AsRule;
|
||||||
use crate::settings::Settings;
|
use crate::settings::Settings;
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ pub(crate) fn organize_imports(
|
||||||
comments,
|
comments,
|
||||||
locator,
|
locator,
|
||||||
settings.line_length,
|
settings.line_length,
|
||||||
LineWidth::new(settings.tab_size).add_str(indentation),
|
LineWidthBuilder::new(settings.tab_size).add_str(indentation),
|
||||||
stylist,
|
stylist,
|
||||||
&settings.src,
|
&settings.src,
|
||||||
package,
|
package,
|
||||||
|
|
|
@ -6,7 +6,7 @@ use ruff_python_ast::{CmpOp, Expr};
|
||||||
use ruff_source_file::{Line, Locator};
|
use ruff_source_file::{Line, Locator};
|
||||||
use ruff_text_size::{Ranged, TextLen, TextRange};
|
use ruff_text_size::{Ranged, TextLen, TextRange};
|
||||||
|
|
||||||
use crate::line_width::{LineLength, LineWidth, TabSize};
|
use crate::line_width::{LineLength, LineWidthBuilder, TabSize};
|
||||||
|
|
||||||
pub(super) fn is_ambiguous_name(name: &str) -> bool {
|
pub(super) fn is_ambiguous_name(name: &str) -> bool {
|
||||||
name == "l" || name == "I" || name == "O"
|
name == "l" || name == "I" || name == "O"
|
||||||
|
@ -66,11 +66,11 @@ pub(super) fn is_overlong(
|
||||||
// worst-case scenario is that the line is all tabs). If the maximum width is less than the
|
// worst-case scenario is that the line is all tabs). If the maximum width is less than the
|
||||||
// limit, then the line is not overlong.
|
// limit, then the line is not overlong.
|
||||||
let max_width = line.len() * tab_size.as_usize();
|
let max_width = line.len() * tab_size.as_usize();
|
||||||
if max_width < limit.get() {
|
if max_width < limit.value() as usize {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut width = LineWidth::new(tab_size);
|
let mut width = LineWidthBuilder::new(tab_size);
|
||||||
width = width.add_str(line.as_str());
|
width = width.add_str(line.as_str());
|
||||||
if width <= limit {
|
if width <= limit {
|
||||||
return None;
|
return None;
|
||||||
|
@ -95,14 +95,14 @@ pub(super) fn is_overlong(
|
||||||
// begins before the limit.
|
// begins before the limit.
|
||||||
let last_chunk = chunks.last().unwrap_or(second_chunk);
|
let last_chunk = chunks.last().unwrap_or(second_chunk);
|
||||||
if last_chunk.contains("://") {
|
if last_chunk.contains("://") {
|
||||||
if width.get() - last_chunk.width() <= limit.get() {
|
if width.get() - last_chunk.width() <= limit.value() as usize {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtain the start offset of the part of the line that exceeds the limit
|
// Obtain the start offset of the part of the line that exceeds the limit
|
||||||
let mut start_offset = line.start();
|
let mut start_offset = line.start();
|
||||||
let mut start_width = LineWidth::new(tab_size);
|
let mut start_width = LineWidthBuilder::new(tab_size);
|
||||||
for c in line.chars() {
|
for c in line.chars() {
|
||||||
if start_width < limit {
|
if start_width < limit {
|
||||||
start_offset += c.text_len();
|
start_offset += c.text_len();
|
||||||
|
|
|
@ -10,6 +10,7 @@ mod tests {
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
|
||||||
use test_case::test_case;
|
use test_case::test_case;
|
||||||
|
|
||||||
use crate::line_width::LineLength;
|
use crate::line_width::LineLength;
|
||||||
|
@ -170,7 +171,7 @@ mod tests {
|
||||||
Path::new("pycodestyle/W505.py"),
|
Path::new("pycodestyle/W505.py"),
|
||||||
&settings::Settings {
|
&settings::Settings {
|
||||||
pycodestyle: Settings {
|
pycodestyle: Settings {
|
||||||
max_doc_length: Some(LineLength::from(50)),
|
max_doc_length: Some(LineLength::try_from(50).unwrap()),
|
||||||
..Settings::default()
|
..Settings::default()
|
||||||
},
|
},
|
||||||
..settings::Settings::for_rule(Rule::DocLineTooLong)
|
..settings::Settings::for_rule(Rule::DocLineTooLong)
|
||||||
|
@ -186,7 +187,7 @@ mod tests {
|
||||||
Path::new("pycodestyle/W505_utf_8.py"),
|
Path::new("pycodestyle/W505_utf_8.py"),
|
||||||
&settings::Settings {
|
&settings::Settings {
|
||||||
pycodestyle: Settings {
|
pycodestyle: Settings {
|
||||||
max_doc_length: Some(LineLength::from(50)),
|
max_doc_length: Some(LineLength::try_from(50).unwrap()),
|
||||||
..Settings::default()
|
..Settings::default()
|
||||||
},
|
},
|
||||||
..settings::Settings::for_rule(Rule::DocLineTooLong)
|
..settings::Settings::for_rule(Rule::DocLineTooLong)
|
||||||
|
@ -206,7 +207,7 @@ mod tests {
|
||||||
Path::new("pycodestyle/E501_2.py"),
|
Path::new("pycodestyle/E501_2.py"),
|
||||||
&settings::Settings {
|
&settings::Settings {
|
||||||
tab_size: NonZeroU8::new(tab_size).unwrap().into(),
|
tab_size: NonZeroU8::new(tab_size).unwrap().into(),
|
||||||
line_length: LineLength::from(6),
|
line_length: LineLength::try_from(6).unwrap(),
|
||||||
..settings::Settings::for_rule(Rule::LineTooLong)
|
..settings::Settings::for_rule(Rule::LineTooLong)
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
|
|
@ -78,7 +78,7 @@ pub(crate) fn doc_line_too_long(line: &Line, settings: &Settings) -> Option<Diag
|
||||||
)
|
)
|
||||||
.map(|overlong| {
|
.map(|overlong| {
|
||||||
Diagnostic::new(
|
Diagnostic::new(
|
||||||
DocLineTooLong(overlong.width(), limit.get()),
|
DocLineTooLong(overlong.width(), limit.value() as usize),
|
||||||
overlong.range(),
|
overlong.range(),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
|
@ -62,5 +62,10 @@ pub(crate) fn line_too_long(line: &Line, settings: &Settings) -> Option<Diagnost
|
||||||
&settings.task_tags,
|
&settings.task_tags,
|
||||||
settings.tab_size,
|
settings.tab_size,
|
||||||
)
|
)
|
||||||
.map(|overlong| Diagnostic::new(LineTooLong(overlong.width(), limit.get()), overlong.range()))
|
.map(|overlong| {
|
||||||
|
Diagnostic::new(
|
||||||
|
LineTooLong(overlong.width(), limit.value() as usize),
|
||||||
|
overlong.range(),
|
||||||
|
)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ use ruff_python_literal::format::{
|
||||||
FieldName, FieldNamePart, FieldType, FormatPart, FormatString, FromTemplate,
|
FieldName, FieldNamePart, FieldType, FormatPart, FormatString, FromTemplate,
|
||||||
};
|
};
|
||||||
use ruff_python_parser::{lexer, Mode, Tok};
|
use ruff_python_parser::{lexer, Mode, Tok};
|
||||||
|
|
||||||
use ruff_source_file::Locator;
|
use ruff_source_file::Locator;
|
||||||
use ruff_text_size::{Ranged, TextRange};
|
use ruff_text_size::{Ranged, TextRange};
|
||||||
|
|
||||||
|
@ -396,7 +397,7 @@ pub(crate) fn f_strings(
|
||||||
// """.format(0, 1) -> offset = 0
|
// """.format(0, 1) -> offset = 0
|
||||||
// ```
|
// ```
|
||||||
let offset = if idx == 0 { col_offset.to_usize() } else { 0 };
|
let offset = if idx == 0 { col_offset.to_usize() } else { 0 };
|
||||||
offset + line.chars().count() > line_length.get()
|
offset + line.chars().count() > line_length.value() as usize
|
||||||
}) {
|
}) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,9 @@ use std::str::FromStr;
|
||||||
|
|
||||||
use clap::{command, Parser};
|
use clap::{command, Parser};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
use ruff::line_width::LineLength;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
|
|
||||||
use ruff::line_width::LineLength;
|
|
||||||
use ruff::logging::LogLevel;
|
use ruff::logging::LogLevel;
|
||||||
use ruff::registry::Rule;
|
use ruff::registry::Rule;
|
||||||
use ruff::settings::types::{
|
use ruff::settings::types::{
|
||||||
|
@ -256,7 +256,7 @@ pub struct CheckArgs {
|
||||||
/// Set the line-length for length-associated rules and automatic
|
/// Set the line-length for length-associated rules and automatic
|
||||||
/// formatting.
|
/// formatting.
|
||||||
#[arg(long, help_heading = "Rule configuration", hide = true)]
|
#[arg(long, help_heading = "Rule configuration", hide = true)]
|
||||||
pub line_length: Option<usize>,
|
pub line_length: Option<LineLength>,
|
||||||
/// Regular expression matching the name of dummy variables.
|
/// Regular expression matching the name of dummy variables.
|
||||||
#[arg(long, help_heading = "Rule configuration", hide = true)]
|
#[arg(long, help_heading = "Rule configuration", hide = true)]
|
||||||
pub dummy_variable_rgx: Option<Regex>,
|
pub dummy_variable_rgx: Option<Regex>,
|
||||||
|
@ -497,7 +497,7 @@ pub struct Overrides {
|
||||||
pub extend_unfixable: Option<Vec<RuleSelector>>,
|
pub extend_unfixable: Option<Vec<RuleSelector>>,
|
||||||
pub fixable: Option<Vec<RuleSelector>>,
|
pub fixable: Option<Vec<RuleSelector>>,
|
||||||
pub ignore: Option<Vec<RuleSelector>>,
|
pub ignore: Option<Vec<RuleSelector>>,
|
||||||
pub line_length: Option<usize>,
|
pub line_length: Option<LineLength>,
|
||||||
pub per_file_ignores: Option<Vec<PatternPrefixPair>>,
|
pub per_file_ignores: Option<Vec<PatternPrefixPair>>,
|
||||||
pub respect_gitignore: Option<bool>,
|
pub respect_gitignore: Option<bool>,
|
||||||
pub select: Option<Vec<RuleSelector>>,
|
pub select: Option<Vec<RuleSelector>>,
|
||||||
|
@ -560,7 +560,7 @@ impl ConfigProcessor for Overrides {
|
||||||
config.force_exclude = Some(*force_exclude);
|
config.force_exclude = Some(*force_exclude);
|
||||||
}
|
}
|
||||||
if let Some(line_length) = &self.line_length {
|
if let Some(line_length) = &self.line_length {
|
||||||
config.line_length = Some(LineLength::from(*line_length));
|
config.line_length = Some(*line_length);
|
||||||
}
|
}
|
||||||
if let Some(per_file_ignores) = &self.per_file_ignores {
|
if let Some(per_file_ignores) = &self.per_file_ignores {
|
||||||
config.per_file_ignores = Some(collect_per_file_ignores(per_file_ignores.clone()));
|
config.per_file_ignores = Some(collect_per_file_ignores(per_file_ignores.clone()));
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use std::io;
|
use std::io;
|
||||||
|
use std::num::NonZeroU16;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
@ -49,12 +50,8 @@ pub(crate) fn format(cli: &Arguments, overrides: &Overrides) -> Result<ExitStatu
|
||||||
}
|
}
|
||||||
|
|
||||||
let line_length = resolver.resolve(path, &pyproject_config).line_length;
|
let line_length = resolver.resolve(path, &pyproject_config).line_length;
|
||||||
// TODO(konstin): Unify `LineWidth` and `LineLength`
|
let options = PyFormatOptions::from_extension(path)
|
||||||
let line_width = LineWidth::try_from(
|
.with_line_width(LineWidth::from(NonZeroU16::from(line_length)));
|
||||||
u16::try_from(line_length.get()).expect("Line shouldn't be larger than 2**16"),
|
|
||||||
)
|
|
||||||
.expect("Configured line length is too large for the formatter");
|
|
||||||
let options = PyFormatOptions::from_extension(path).with_line_width(line_width);
|
|
||||||
|
|
||||||
format_path(path, options)
|
format_path(path, options)
|
||||||
})
|
})
|
||||||
|
|
|
@ -21,6 +21,7 @@ use similar::{ChangeTag, TextDiff};
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{BufWriter, Write};
|
use std::io::{BufWriter, Write};
|
||||||
|
use std::num::NonZeroU16;
|
||||||
use std::ops::{Add, AddAssign};
|
use std::ops::{Add, AddAssign};
|
||||||
use std::panic::catch_unwind;
|
use std::panic::catch_unwind;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
@ -838,7 +839,7 @@ struct PyprojectTomlTool {
|
||||||
struct BlackOptions {
|
struct BlackOptions {
|
||||||
// Black actually allows both snake case and kebab case
|
// Black actually allows both snake case and kebab case
|
||||||
#[serde(alias = "line-length")]
|
#[serde(alias = "line-length")]
|
||||||
line_length: u16,
|
line_length: NonZeroU16,
|
||||||
#[serde(alias = "skip-magic-trailing-comma")]
|
#[serde(alias = "skip-magic-trailing-comma")]
|
||||||
skip_magic_trailing_comma: bool,
|
skip_magic_trailing_comma: bool,
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
|
@ -849,7 +850,7 @@ struct BlackOptions {
|
||||||
impl Default for BlackOptions {
|
impl Default for BlackOptions {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
line_length: 88,
|
line_length: NonZeroU16::new(88).unwrap(),
|
||||||
skip_magic_trailing_comma: false,
|
skip_magic_trailing_comma: false,
|
||||||
force_exclude: None,
|
force_exclude: None,
|
||||||
}
|
}
|
||||||
|
@ -893,9 +894,7 @@ impl BlackOptions {
|
||||||
|
|
||||||
fn to_py_format_options(&self, file: &Path) -> PyFormatOptions {
|
fn to_py_format_options(&self, file: &Path) -> PyFormatOptions {
|
||||||
PyFormatOptions::from_extension(file)
|
PyFormatOptions::from_extension(file)
|
||||||
.with_line_width(
|
.with_line_width(LineWidth::from(self.line_length))
|
||||||
LineWidth::try_from(self.line_length).expect("Invalid line length limit"),
|
|
||||||
)
|
|
||||||
.with_magic_trailing_comma(if self.skip_magic_trailing_comma {
|
.with_magic_trailing_comma(if self.skip_magic_trailing_comma {
|
||||||
MagicTrailingComma::Ignore
|
MagicTrailingComma::Ignore
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1703,7 +1703,6 @@ impl<Context> Format<Context> for ExpandParent {
|
||||||
/// ```
|
/// ```
|
||||||
/// use ruff_formatter::{format_args, format, LineWidth, SimpleFormatOptions};
|
/// use ruff_formatter::{format_args, format, LineWidth, SimpleFormatOptions};
|
||||||
/// use ruff_formatter::prelude::*;
|
/// use ruff_formatter::prelude::*;
|
||||||
/// use ruff_formatter::printer::PrintWidth;
|
|
||||||
///
|
///
|
||||||
/// fn main() -> FormatResult<()> {
|
/// fn main() -> FormatResult<()> {
|
||||||
/// let context = SimpleFormatContext::new(SimpleFormatOptions {
|
/// let context = SimpleFormatContext::new(SimpleFormatOptions {
|
||||||
|
|
|
@ -7,10 +7,9 @@ use crate::format_element::tag::{Condition, DedentMode};
|
||||||
use crate::prelude::tag::GroupMode;
|
use crate::prelude::tag::GroupMode;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::source_code::SourceCode;
|
use crate::source_code::SourceCode;
|
||||||
use crate::{format, write, TabWidth};
|
|
||||||
use crate::{
|
use crate::{
|
||||||
BufferExtensions, Format, FormatContext, FormatElement, FormatOptions, FormatResult, Formatter,
|
format, write, BufferExtensions, Format, FormatContext, FormatElement, FormatOptions,
|
||||||
IndentStyle, LineWidth, PrinterOptions,
|
FormatResult, Formatter, IndentStyle, LineWidth, PrinterOptions, TabWidth,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::tag::Tag;
|
use super::tag::Tag;
|
||||||
|
@ -222,12 +221,12 @@ impl FormatOptions for IrFormatOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn line_width(&self) -> LineWidth {
|
fn line_width(&self) -> LineWidth {
|
||||||
LineWidth(80)
|
LineWidth::try_from(80).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_print_options(&self) -> PrinterOptions {
|
fn as_print_options(&self) -> PrinterOptions {
|
||||||
PrinterOptions {
|
PrinterOptions {
|
||||||
print_width: self.line_width().into(),
|
line_width: self.line_width(),
|
||||||
indent_style: IndentStyle::Space(2),
|
indent_style: IndentStyle::Space(2),
|
||||||
..PrinterOptions::default()
|
..PrinterOptions::default()
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ use crate::group_id::UniqueGroupIdBuilder;
|
||||||
use crate::prelude::TagKind;
|
use crate::prelude::TagKind;
|
||||||
use std::fmt::{Debug, Display};
|
use std::fmt::{Debug, Display};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
use std::num::{NonZeroU16, NonZeroU8, TryFromIntError};
|
||||||
|
|
||||||
use crate::format_element::document::Document;
|
use crate::format_element::document::Document;
|
||||||
use crate::printer::{Printer, PrinterOptions, SourceMapGeneration};
|
use crate::printer::{Printer, PrinterOptions, SourceMapGeneration};
|
||||||
|
@ -51,7 +52,6 @@ pub use crate::diagnostics::{ActualStart, FormatError, InvalidDocumentError, Pri
|
||||||
pub use format_element::{normalize_newlines, FormatElement, LINE_TERMINATORS};
|
pub use format_element::{normalize_newlines, FormatElement, LINE_TERMINATORS};
|
||||||
pub use group_id::GroupId;
|
pub use group_id::GroupId;
|
||||||
use ruff_text_size::{TextRange, TextSize};
|
use ruff_text_size::{TextRange, TextSize};
|
||||||
use std::num::{NonZeroU8, ParseIntError, TryFromIntError};
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, Clone, Copy, Hash)]
|
#[derive(Debug, Eq, PartialEq, Clone, Copy, Hash)]
|
||||||
|
@ -135,92 +135,48 @@ impl TryFrom<u8> for TabWidth {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Validated value for the `line_width` formatter options
|
/// The maximum visual width to which the formatter should try to limit a line.
|
||||||
///
|
|
||||||
/// The allowed range of values is 1..=320
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||||
pub struct LineWidth(u16);
|
pub struct LineWidth(NonZeroU16);
|
||||||
|
|
||||||
impl LineWidth {
|
impl LineWidth {
|
||||||
/// Maximum allowed value for a valid [`LineWidth`]
|
|
||||||
pub const MAX: u16 = 320;
|
|
||||||
|
|
||||||
/// Return the numeric value for this [`LineWidth`]
|
/// Return the numeric value for this [`LineWidth`]
|
||||||
pub fn value(&self) -> u16 {
|
pub const fn value(&self) -> u16 {
|
||||||
self.0
|
self.0.get()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for LineWidth {
|
impl Default for LineWidth {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self(80)
|
Self(NonZeroU16::new(80).unwrap())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Error type returned when parsing a [`LineWidth`] from a string fails
|
|
||||||
pub enum ParseLineWidthError {
|
|
||||||
/// The string could not be parsed as a valid [u16]
|
|
||||||
ParseError(ParseIntError),
|
|
||||||
/// The [u16] value of the string is not a valid [LineWidth]
|
|
||||||
TryFromIntError(LineWidthFromIntError),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Debug for ParseLineWidthError {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
std::fmt::Display::fmt(self, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::fmt::Display for ParseLineWidthError {
|
|
||||||
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
match self {
|
|
||||||
ParseLineWidthError::ParseError(err) => std::fmt::Display::fmt(err, fmt),
|
|
||||||
ParseLineWidthError::TryFromIntError(err) => std::fmt::Display::fmt(err, fmt),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FromStr for LineWidth {
|
|
||||||
type Err = ParseLineWidthError;
|
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
||||||
let value = u16::from_str(s).map_err(ParseLineWidthError::ParseError)?;
|
|
||||||
let value = Self::try_from(value).map_err(ParseLineWidthError::TryFromIntError)?;
|
|
||||||
Ok(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Error type returned when converting a u16 to a [`LineWidth`] fails
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
|
||||||
pub struct LineWidthFromIntError(pub u16);
|
|
||||||
|
|
||||||
impl TryFrom<u16> for LineWidth {
|
impl TryFrom<u16> for LineWidth {
|
||||||
type Error = LineWidthFromIntError;
|
type Error = TryFromIntError;
|
||||||
|
|
||||||
fn try_from(value: u16) -> Result<Self, Self::Error> {
|
fn try_from(value: u16) -> Result<LineWidth, Self::Error> {
|
||||||
if value > 0 && value <= Self::MAX {
|
NonZeroU16::try_from(value).map(LineWidth)
|
||||||
Ok(Self(value))
|
|
||||||
} else {
|
|
||||||
Err(LineWidthFromIntError(value))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::fmt::Display for LineWidthFromIntError {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
writeln!(
|
|
||||||
f,
|
|
||||||
"The line width exceeds the maximum value ({})",
|
|
||||||
LineWidth::MAX
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<LineWidth> for u16 {
|
impl From<LineWidth> for u16 {
|
||||||
fn from(value: LineWidth) -> Self {
|
fn from(value: LineWidth) -> Self {
|
||||||
value.0
|
value.0.get()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<LineWidth> for u32 {
|
||||||
|
fn from(value: LineWidth) -> Self {
|
||||||
|
u32::from(value.0.get())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<NonZeroU16> for LineWidth {
|
||||||
|
fn from(value: NonZeroU16) -> Self {
|
||||||
|
Self(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,7 +268,7 @@ impl FormatOptions for SimpleFormatOptions {
|
||||||
|
|
||||||
fn as_print_options(&self) -> PrinterOptions {
|
fn as_print_options(&self) -> PrinterOptions {
|
||||||
PrinterOptions {
|
PrinterOptions {
|
||||||
print_width: self.line_width.into(),
|
line_width: self.line_width,
|
||||||
indent_style: self.indent_style,
|
indent_style: self.indent_style,
|
||||||
source_map_generation: SourceMapGeneration::Enabled,
|
source_map_generation: SourceMapGeneration::Enabled,
|
||||||
..PrinterOptions::default()
|
..PrinterOptions::default()
|
||||||
|
@ -489,7 +445,7 @@ pub type FormatResult<F> = Result<F, FormatError>;
|
||||||
/// Implementing `Format` for a custom struct
|
/// Implementing `Format` for a custom struct
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use ruff_formatter::{format, write, IndentStyle, LineWidth};
|
/// use ruff_formatter::{format, write, IndentStyle};
|
||||||
/// use ruff_formatter::prelude::*;
|
/// use ruff_formatter::prelude::*;
|
||||||
/// use ruff_text_size::TextSize;
|
/// use ruff_text_size::TextSize;
|
||||||
///
|
///
|
||||||
|
|
|
@ -1194,7 +1194,7 @@ impl<'a, 'print> FitsMeasurer<'a, 'print> {
|
||||||
|
|
||||||
FormatElement::Tag(StartLineSuffix { reserved_width }) => {
|
FormatElement::Tag(StartLineSuffix { reserved_width }) => {
|
||||||
self.state.line_width += reserved_width;
|
self.state.line_width += reserved_width;
|
||||||
if self.state.line_width > self.options().print_width.into() {
|
if self.state.line_width > self.options().line_width.into() {
|
||||||
return Ok(Fits::No);
|
return Ok(Fits::No);
|
||||||
}
|
}
|
||||||
self.queue.skip_content(TagKind::LineSuffix);
|
self.queue.skip_content(TagKind::LineSuffix);
|
||||||
|
@ -1320,7 +1320,7 @@ impl<'a, 'print> FitsMeasurer<'a, 'print> {
|
||||||
self.state.line_width += char_width;
|
self.state.line_width += char_width;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.state.line_width > self.options().print_width.into() {
|
if self.state.line_width > self.options().line_width.into() {
|
||||||
return Fits::No;
|
return Fits::No;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1437,10 +1437,11 @@ impl From<BestFittingMode> for MeasureMode {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::printer::{LineEnding, PrintWidth, Printer, PrinterOptions};
|
use crate::printer::{LineEnding, Printer, PrinterOptions};
|
||||||
use crate::source_code::SourceCode;
|
use crate::source_code::SourceCode;
|
||||||
use crate::{
|
use crate::{
|
||||||
format_args, write, Document, FormatState, IndentStyle, Printed, TabWidth, VecBuffer,
|
format_args, write, Document, FormatState, IndentStyle, LineWidth, Printed, TabWidth,
|
||||||
|
VecBuffer,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn format(root: &dyn Format<SimpleFormatContext>) -> Printed {
|
fn format(root: &dyn Format<SimpleFormatContext>) -> Printed {
|
||||||
|
@ -1592,7 +1593,7 @@ two lines`,
|
||||||
let options = PrinterOptions {
|
let options = PrinterOptions {
|
||||||
indent_style: IndentStyle::Tab,
|
indent_style: IndentStyle::Tab,
|
||||||
tab_width: TabWidth::try_from(4).unwrap(),
|
tab_width: TabWidth::try_from(4).unwrap(),
|
||||||
print_width: PrintWidth::new(19),
|
line_width: LineWidth::try_from(19).unwrap(),
|
||||||
..PrinterOptions::default()
|
..PrinterOptions::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1697,7 +1698,7 @@ two lines`,
|
||||||
|
|
||||||
let printed = Printer::new(
|
let printed = Printer::new(
|
||||||
SourceCode::default(),
|
SourceCode::default(),
|
||||||
PrinterOptions::default().with_print_width(PrintWidth::new(10)),
|
PrinterOptions::default().with_line_width(LineWidth::try_from(10).unwrap()),
|
||||||
)
|
)
|
||||||
.print(&document)
|
.print(&document)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
|
@ -7,7 +7,7 @@ pub struct PrinterOptions {
|
||||||
pub tab_width: TabWidth,
|
pub tab_width: TabWidth,
|
||||||
|
|
||||||
/// What's the max width of a line. Defaults to 80
|
/// What's the max width of a line. Defaults to 80
|
||||||
pub print_width: PrintWidth,
|
pub line_width: LineWidth,
|
||||||
|
|
||||||
/// The type of line ending to apply to the printed input
|
/// The type of line ending to apply to the printed input
|
||||||
pub line_ending: LineEnding,
|
pub line_ending: LineEnding,
|
||||||
|
@ -27,14 +27,14 @@ where
|
||||||
fn from(options: &'a O) -> Self {
|
fn from(options: &'a O) -> Self {
|
||||||
PrinterOptions::default()
|
PrinterOptions::default()
|
||||||
.with_indent(options.indent_style())
|
.with_indent(options.indent_style())
|
||||||
.with_print_width(options.line_width().into())
|
.with_line_width(options.line_width())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PrinterOptions {
|
impl PrinterOptions {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn with_print_width(mut self, width: PrintWidth) -> Self {
|
pub fn with_line_width(mut self, width: LineWidth) -> Self {
|
||||||
self.print_width = width;
|
self.line_width = width;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,10 +66,10 @@ impl PrinterOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||||
pub struct PrintWidth(u32);
|
pub struct PrintWidth(u16);
|
||||||
|
|
||||||
impl PrintWidth {
|
impl PrintWidth {
|
||||||
pub fn new(width: u32) -> Self {
|
pub fn new(width: u16) -> Self {
|
||||||
Self(width)
|
Self(width)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,17 +82,17 @@ impl Default for PrintWidth {
|
||||||
|
|
||||||
impl From<LineWidth> for PrintWidth {
|
impl From<LineWidth> for PrintWidth {
|
||||||
fn from(width: LineWidth) -> Self {
|
fn from(width: LineWidth) -> Self {
|
||||||
Self(u32::from(u16::from(width)))
|
Self(u16::from(width))
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<PrintWidth> for usize {
|
|
||||||
fn from(width: PrintWidth) -> Self {
|
|
||||||
width.0 as usize
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<PrintWidth> for u32 {
|
impl From<PrintWidth> for u32 {
|
||||||
|
fn from(width: PrintWidth) -> Self {
|
||||||
|
u32::from(width.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<PrintWidth> for u16 {
|
||||||
fn from(width: PrintWidth) -> Self {
|
fn from(width: PrintWidth) -> Self {
|
||||||
width.0
|
width.0
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,7 +135,7 @@ impl FormatOptions for PyFormatOptions {
|
||||||
fn as_print_options(&self) -> PrinterOptions {
|
fn as_print_options(&self) -> PrinterOptions {
|
||||||
PrinterOptions {
|
PrinterOptions {
|
||||||
tab_width: self.tab_width,
|
tab_width: self.tab_width,
|
||||||
print_width: self.line_width.into(),
|
line_width: self.line_width,
|
||||||
line_ending: LineEnding::LineFeed,
|
line_ending: LineEnding::LineFeed,
|
||||||
indent_style: self.indent_style,
|
indent_style: self.indent_style,
|
||||||
source_map_generation: self.source_map_generation,
|
source_map_generation: self.source_map_generation,
|
||||||
|
|
|
@ -6,8 +6,8 @@ edition = "2021"
|
||||||
rust-version = "1.67.1"
|
rust-version = "1.67.1"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde = { version="1.0.152", optional = true, default_features = false }
|
serde = { workspace = true, optional = true }
|
||||||
schemars = { version = "0.8.12", optional = true }
|
schemars = { workspace = true, optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serde_test = { version = "1.0.152" }
|
serde_test = { version = "1.0.152" }
|
||||||
|
@ -19,4 +19,4 @@ serde = ["dep:serde"]
|
||||||
[[test]]
|
[[test]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
path = "tests/serde.rs"
|
path = "tests/serde.rs"
|
||||||
required-features = ["serde"]
|
required-features = ["serde"]
|
||||||
|
|
|
@ -199,7 +199,7 @@ line-length = 79
|
||||||
pyproject.tool,
|
pyproject.tool,
|
||||||
Some(Tools {
|
Some(Tools {
|
||||||
ruff: Some(Options {
|
ruff: Some(Options {
|
||||||
line_length: Some(LineLength::from(79)),
|
line_length: Some(LineLength::try_from(79).unwrap()),
|
||||||
..Options::default()
|
..Options::default()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -299,7 +299,7 @@ other-attribute = 1
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
config,
|
config,
|
||||||
Options {
|
Options {
|
||||||
line_length: Some(LineLength::from(88)),
|
line_length: Some(LineLength::try_from(88).unwrap()),
|
||||||
extend_exclude: Some(vec![
|
extend_exclude: Some(vec![
|
||||||
"excluded_file.py".to_string(),
|
"excluded_file.py".to_string(),
|
||||||
"migrations".to_string(),
|
"migrations".to_string(),
|
||||||
|
|
6
ruff.schema.json
generated
6
ruff.schema.json
generated
|
@ -1386,10 +1386,10 @@
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
},
|
},
|
||||||
"LineLength": {
|
"LineLength": {
|
||||||
"description": "The length of a line of text that is considered too long.",
|
"description": "The length of a line of text that is considered too long.\n\nThe allowed range of values is 1..=320",
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"format": "uint",
|
"format": "uint16",
|
||||||
"minimum": 0.0
|
"minimum": 1.0
|
||||||
},
|
},
|
||||||
"McCabeOptions": {
|
"McCabeOptions": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue