Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce FormatterSettings #7545

Merged
merged 1 commit into from
Sep 21, 2023
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
6 changes: 6 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 25 additions & 7 deletions crates/ruff_cache/src/cache_key.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use std::borrow::Cow;
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::hash::{Hash, Hasher};
use std::num::NonZeroU8;
use std::num::{
NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroU128, NonZeroU16,
NonZeroU32, NonZeroU64, NonZeroU8,
};
use std::path::{Path, PathBuf};

use glob::Pattern;
Expand Down Expand Up @@ -177,14 +180,29 @@ impl CacheKey for i8 {
state.write_i8(*self);
}
}

impl CacheKey for NonZeroU8 {
#[inline]
fn cache_key(&self, state: &mut CacheKeyHasher) {
state.write_u8(self.get());
}
macro_rules! impl_cache_key_non_zero {
($name:ident) => {
impl CacheKey for $name {
#[inline]
fn cache_key(&self, state: &mut CacheKeyHasher) {
self.get().cache_key(state)
}
}
};
}

impl_cache_key_non_zero!(NonZeroU8);
impl_cache_key_non_zero!(NonZeroU16);
impl_cache_key_non_zero!(NonZeroU32);
impl_cache_key_non_zero!(NonZeroU64);
impl_cache_key_non_zero!(NonZeroU128);

impl_cache_key_non_zero!(NonZeroI8);
impl_cache_key_non_zero!(NonZeroI16);
impl_cache_key_non_zero!(NonZeroI32);
impl_cache_key_non_zero!(NonZeroI64);
impl_cache_key_non_zero!(NonZeroI128);

macro_rules! impl_cache_key_tuple {
() => (
impl CacheKey for () {
Expand Down
17 changes: 2 additions & 15 deletions crates/ruff_cli/src/commands/format.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::fmt::{Display, Formatter};
use std::io;
use std::num::NonZeroU16;
use std::path::{Path, PathBuf};
use std::time::Instant;

Expand All @@ -10,12 +9,10 @@ use log::error;
use rayon::iter::Either::{Left, Right};
use rayon::iter::{IntoParallelIterator, ParallelIterator};
use thiserror::Error;
use tracing::{debug, warn};
use tracing::debug;

use ruff_formatter::LineWidth;
use ruff_linter::fs;
use ruff_linter::logging::LogLevel;
use ruff_linter::settings::types::PreviewMode;
use ruff_linter::warn_user_once;
use ruff_python_ast::{PySourceType, SourceType};
use ruff_python_formatter::{format_module, FormatModuleError, PyFormatOptions};
Expand Down Expand Up @@ -76,17 +73,7 @@ pub(crate) fn format(
};

let resolved_settings = resolver.resolve(path, &pyproject_config);

// TODO(micha): Use `formatter` settings instead
let preview = match resolved_settings.linter.preview {
PreviewMode::Enabled => ruff_python_formatter::PreviewMode::Enabled,
PreviewMode::Disabled => ruff_python_formatter::PreviewMode::Disabled,
};
let line_length = resolved_settings.linter.line_length;

let options = PyFormatOptions::from_source_type(source_type)
.with_line_width(LineWidth::from(NonZeroU16::from(line_length)))
.with_preview(preview);
let options = resolved_settings.formatter.to_format_options(source_type);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All just for this 😆

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's beautiful

debug!("Formatting {} with {:?}", path.display(), options);

Some(match catch_unwind(|| format_path(path, options, mode)) {
Expand Down
20 changes: 5 additions & 15 deletions crates/ruff_cli/src/commands/format_stdin.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
use std::io::{stdout, Write};
use std::num::NonZeroU16;
use std::path::Path;

use anyhow::Result;
use log::warn;
use ruff_formatter::LineWidth;
use ruff_linter::settings::types::PreviewMode;

use ruff_python_ast::PySourceType;
use ruff_python_formatter::{format_module, PyFormatOptions};
use ruff_workspace::resolver::python_file_at_path;

Expand Down Expand Up @@ -39,18 +37,10 @@ pub(crate) fn format_stdin(cli: &FormatArguments, overrides: &CliOverrides) -> R
// Format the file.
let path = cli.stdin_filename.as_deref();

// TODO(micha): Use Formatter settings
let preview = match pyproject_config.settings.linter.preview {
PreviewMode::Enabled => ruff_python_formatter::PreviewMode::Enabled,
PreviewMode::Disabled => ruff_python_formatter::PreviewMode::Disabled,
};
let line_length = pyproject_config.settings.linter.line_length;

let options = path
.map(PyFormatOptions::from_extension)
.unwrap_or_default()
.with_line_width(LineWidth::from(NonZeroU16::from(line_length)))
.with_preview(preview);
let options = pyproject_config
.settings
.formatter
.to_format_options(path.map(PySourceType::from).unwrap_or_default());

match format_source(path, options, mode) {
Ok(result) => match mode {
Expand Down
7 changes: 2 additions & 5 deletions crates/ruff_dev/src/format_dev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ use imara_diff::{diff, Algorithm};
use indicatif::ProgressStyle;
#[cfg_attr(feature = "singlethreaded", allow(unused_imports))]
use rayon::iter::{IntoParallelIterator, ParallelIterator};
use ruff_linter::line_width::LineLength;
use serde::Deserialize;
use similar::{ChangeTag, TextDiff};
use tempfile::NamedTempFile;
Expand Down Expand Up @@ -551,10 +550,8 @@ fn format_dir_entry(
let settings = resolver.resolve(&path, pyproject_config);
// That's a bad way of doing this but it's not worth doing something better for format_dev
// TODO(micha) use formatter settings instead
if settings.linter.line_length != LineLength::default() {
options = options.with_line_width(LineWidth::from(NonZeroU16::from(
settings.linter.line_length,
)));
if settings.formatter.line_width != LineWidth::default() {
options = options.with_line_width(settings.formatter.line_width);
}

// Handle panics (mostly in `debug_assert!`)
Expand Down
2 changes: 2 additions & 0 deletions crates/ruff_formatter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ repository = { workspace = true }
license = { workspace = true }

[dependencies]
ruff_cache = { path = "../ruff_cache" }
ruff_macros = { path = "../ruff_macros" }
ruff_text_size = { path = "../ruff_text_size" }

drop_bomb = { version = "0.1.5" }
Expand Down
11 changes: 9 additions & 2 deletions crates/ruff_formatter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,10 @@ pub use source_code::{SourceCode, SourceCodeSlice};
pub use crate::diagnostics::{ActualStart, FormatError, InvalidDocumentError, PrintError};
pub use format_element::{normalize_newlines, FormatElement, LINE_TERMINATORS};
pub use group_id::GroupId;
use ruff_macros::CacheKey;
use ruff_text_size::{TextRange, TextSize};

#[derive(Debug, Eq, PartialEq, Clone, Copy, Hash)]
#[derive(Debug, Eq, PartialEq, Clone, Copy, Hash, CacheKey)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Default)]
Expand Down Expand Up @@ -116,8 +117,14 @@ impl TryFrom<u8> for IndentWidth {
}
}

impl From<NonZeroU8> for IndentWidth {
fn from(value: NonZeroU8) -> Self {
Self(value)
}
}

/// The maximum visual width to which the formatter should try to limit a line.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[derive(Clone, Copy, Debug, Eq, PartialEq, CacheKey)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct LineWidth(NonZeroU16);
Expand Down
3 changes: 2 additions & 1 deletion crates/ruff_formatter/src/printer/printer_options/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::{FormatOptions, IndentStyle, IndentWidth, LineWidth};
use ruff_macros::CacheKey;

/// Options that affect how the [`crate::Printer`] prints the format tokens
#[derive(Clone, Debug, Eq, PartialEq, Default)]
Expand Down Expand Up @@ -120,7 +121,7 @@ impl SourceMapGeneration {
}
}

#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Default, CacheKey)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum LineEnding {
/// Line Feed only (\n), common on Linux and macOS as well as inside git repos
Expand Down
2 changes: 2 additions & 0 deletions crates/ruff_python_formatter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ repository = { workspace = true }
license = { workspace = true }

[dependencies]
ruff_cache = { path = "../ruff_cache" }
ruff_formatter = { path = "../ruff_formatter" }
ruff_macros = { path = "../ruff_macros" }
ruff_python_trivia = { path = "../ruff_python_trivia" }
ruff_source_file = { path = "../ruff_source_file" }
ruff_python_ast = { path = "../ruff_python_ast" }
Expand Down
2 changes: 2 additions & 0 deletions crates/ruff_python_formatter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use crate::comments::{
pub use crate::context::PyFormatContext;
pub use crate::options::{MagicTrailingComma, PreviewMode, PyFormatOptions, QuoteStyle};
use crate::verbatim::suppressed_node;
pub use settings::FormatterSettings;

pub(crate) mod builders;
pub mod cli;
Expand All @@ -29,6 +30,7 @@ mod options;
pub(crate) mod other;
pub(crate) mod pattern;
mod prelude;
mod settings;
pub(crate) mod statement;
pub(crate) mod type_param;
mod verbatim;
Expand Down
9 changes: 6 additions & 3 deletions crates/ruff_python_formatter/src/options.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
use ruff_formatter::printer::{LineEnding, PrinterOptions, SourceMapGeneration};
use ruff_formatter::{FormatOptions, IndentStyle, IndentWidth, LineWidth};
use ruff_macros::CacheKey;
use ruff_python_ast::PySourceType;
use std::path::Path;
use std::str::FromStr;

/// Resolved options for formatting one individual file. This is different from [`crate::FormatterSettings`] which
/// represents the formatting settings for multiple files (the whole project, a subdirectory, ...)
#[derive(Clone, Debug)]
#[cfg_attr(
feature = "serde",
Expand Down Expand Up @@ -176,7 +179,7 @@ impl FormatOptions for PyFormatOptions {
}
}

#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, CacheKey)]
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde::Deserialize),
Expand Down Expand Up @@ -230,7 +233,7 @@ impl FromStr for QuoteStyle {
}
}

#[derive(Copy, Clone, Debug, Default)]
#[derive(Copy, Clone, Debug, Default, CacheKey)]
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde::Deserialize),
Expand Down Expand Up @@ -261,7 +264,7 @@ impl FromStr for MagicTrailingComma {
}
}

#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Default, CacheKey)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
pub enum PreviewMode {
Expand Down
49 changes: 49 additions & 0 deletions crates/ruff_python_formatter/src/settings.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use std::path::PathBuf;

use ruff_formatter::{FormatOptions, IndentStyle, LineWidth};
use ruff_macros::CacheKey;
use ruff_python_ast::PySourceType;

use crate::{MagicTrailingComma, PreviewMode, PyFormatOptions, QuoteStyle};

#[derive(CacheKey, Clone, Debug)]
pub struct FormatterSettings {
/// The files that are excluded from formatting (but may be linted).
pub exclude: Vec<PathBuf>,

pub preview: PreviewMode,

pub line_width: LineWidth,

pub indent_style: IndentStyle,

pub quote_style: QuoteStyle,

pub magic_trailing_comma: MagicTrailingComma,
}

impl FormatterSettings {
pub fn to_format_options(&self, source_type: PySourceType) -> PyFormatOptions {
PyFormatOptions::from_source_type(source_type)
.with_indent_style(self.indent_style)
.with_quote_style(self.quote_style)
.with_magic_trailing_comma(self.magic_trailing_comma)
.with_preview(self.preview)
.with_line_width(self.line_width)
}
}

impl Default for FormatterSettings {
fn default() -> Self {
let default_options = PyFormatOptions::default();

Self {
exclude: Vec::default(),
preview: PreviewMode::Disabled,
line_width: default_options.line_width(),
indent_style: default_options.indent_style(),
quote_style: default_options.quote_style(),
magic_trailing_comma: default_options.magic_trailing_comma(),
}
}
}
19 changes: 6 additions & 13 deletions crates/ruff_wasm/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
use std::num::NonZeroU16;
use std::path::Path;

use js_sys::Error;
use serde::{Deserialize, Serialize};
use wasm_bindgen::prelude::*;

use ruff_formatter::{FormatResult, Formatted, LineWidth};
use ruff_formatter::{FormatResult, Formatted};
use ruff_linter::directives;
use ruff_linter::line_width::{LineLength, TabSize};
use ruff_linter::linter::{check_path, LinterResult};
use ruff_linter::registry::AsRule;
use ruff_linter::settings::types::{PreviewMode, PythonVersion};
use ruff_linter::settings::types::PythonVersion;
use ruff_linter::settings::{flags, DUMMY_VARIABLE_RGX, PREFIXES};
use ruff_linter::source_kind::SourceKind;
use ruff_python_ast::{Mod, PySourceType};
use ruff_python_codegen::Stylist;
use ruff_python_formatter::{format_node, pretty_comments, PyFormatContext, PyFormatOptions};
use ruff_python_formatter::{format_node, pretty_comments, PyFormatContext};
use ruff_python_index::{CommentRangesBuilder, Indexer};
use ruff_python_parser::lexer::LexResult;
use ruff_python_parser::{parse_tokens, AsMode, Mode};
Expand Down Expand Up @@ -302,15 +301,9 @@ impl<'a> ParsedModule<'a> {

fn format(&self, settings: &Settings) -> FormatResult<Formatted<PyFormatContext>> {
// TODO(konstin): Add an options for py/pyi to the UI (2/2)
// TODO(micha): Use formatter settings instead
let options = PyFormatOptions::from_source_type(PySourceType::default())
.with_preview(match settings.linter.preview {
PreviewMode::Disabled => ruff_python_formatter::PreviewMode::Disabled,
PreviewMode::Enabled => ruff_python_formatter::PreviewMode::Enabled,
})
.with_line_width(LineWidth::from(NonZeroU16::from(
settings.linter.line_length,
)));
let options = settings
.formatter
.to_format_options(PySourceType::default());

format_node(
&self.module,
Expand Down
2 changes: 2 additions & 0 deletions crates/ruff_workspace/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ license = { workspace = true }

[dependencies]
ruff_linter = { path = "../ruff_linter" }
ruff_formatter = { path = "../ruff_formatter" }
ruff_python_formatter = { path = "../ruff_python_formatter" }
ruff_cache = { path = "../ruff_cache" }
ruff_macros = { path = "../ruff_macros" }

Expand Down
Loading
Loading