Skip to content
Draft
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
3 changes: 3 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,6 @@ indent_size = 4

[*.{js,mjs,cjs,jsx,ts,tsx,json,yml}]
indent_size = 2

[*.{md}]
indent_size = 2
10 changes: 10 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ convert_case = "0.10.0" # Case conversion
cow-utils = "0.1.3" # Copy-on-write utilities
criterion2 = { version = "3.0.2", default-features = false } # Benchmarking
dragonbox_ecma = "0.0.5" # Fast float formatting
editorconfig-parser = "0.0.2" # .editorconfig parser
encoding_rs = "0.8.35" # Character encoding
encoding_rs_io = "0.1.7" # Encoding I/O
env_logger = { version = "0.11.8", default-features = false } # Logging implementation
Expand Down
1 change: 1 addition & 0 deletions apps/oxfmt/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ oxc_span = { workspace = true }

bpaf = { workspace = true, features = ["autocomplete", "bright-color", "derive"] }
cow-utils = { workspace = true }
editorconfig-parser = { workspace = true }
ignore = { workspace = true, features = ["simd-accel"] }
json-strip-comments = { workspace = true }
miette = { workspace = true }
Expand Down
6 changes: 4 additions & 2 deletions apps/oxfmt/src/cli/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use super::{
service::{FormatService, SuccessResult},
walk::Walk,
};
use crate::core::{SourceFormatter, utils};
use crate::core::{SourceFormatter, editorconfig::find_root_editorconfig, utils};

#[derive(Debug)]
pub struct FormatRunner {
Expand Down Expand Up @@ -129,6 +129,8 @@ impl FormatRunner {
}
};

let editorconfig = find_root_editorconfig(&cwd);

// Get the receiver for streaming entries
let rx_entry = walker.stream_entries();
// Collect format results (changed paths or unchanged count)
Expand All @@ -143,7 +145,7 @@ impl FormatRunner {
}

// Create `SourceFormatter` instance
let source_formatter = SourceFormatter::new(num_of_threads, format_options);
let source_formatter = SourceFormatter::new(num_of_threads, format_options, editorconfig);
#[cfg(feature = "napi")]
let source_formatter = source_formatter
.with_external_formatter(self.external_formatter, oxfmt_options.is_sort_package_json);
Expand Down
21 changes: 21 additions & 0 deletions apps/oxfmt/src/core/editorconfig.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use std::path::Path;

use editorconfig_parser::{EditorConfig, EditorConfigProperties};
use oxc_formatter::FormatOptions;

use crate::core::utils::read_to_string;

/// Find root `.editorconfig`.
/// <https://github.com/prettier/prettier/blob/v3.7/src/config/editorconfig/index.js>
pub fn find_root_editorconfig(cwd: &Path) -> Option<EditorConfig> {
let root =
cwd.ancestors().find(|path| path.join(".git").exists() || path.join(".hg").exists())?;
let source = read_to_string(&root.join(".editorconfig")).ok()?;
Some(EditorConfig::parse(&source))
}

pub fn merge_editorconfig_and_format_options(
properties: EditorConfigProperties,
options: &FormatOptions,
) -> FormatOptions {
}
23 changes: 19 additions & 4 deletions apps/oxfmt/src/core/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ use oxc_formatter::{FormatOptions, Formatter, enable_jsx_source_type, get_parse_
use oxc_parser::Parser;
use oxc_span::SourceType;

use super::FormatFileStrategy;
use editorconfig_parser::EditorConfig;

use super::{FormatFileStrategy, editorconfig::merge_editorconfig_and_format_options};

pub enum FormatResult {
Success { is_changed: bool, code: String },
Expand All @@ -18,17 +20,23 @@ pub enum FormatResult {
pub struct SourceFormatter {
allocator_pool: AllocatorPool,
format_options: FormatOptions,
editorconfig: Option<EditorConfig>,
#[cfg(feature = "napi")]
pub is_sort_package_json: bool,
#[cfg(feature = "napi")]
external_formatter: Option<super::ExternalFormatter>,
}

impl SourceFormatter {
pub fn new(num_of_threads: usize, format_options: FormatOptions) -> Self {
pub fn new(
num_of_threads: usize,
format_options: FormatOptions,
editorconfig: Option<EditorConfig>,
) -> Self {
Self {
allocator_pool: AllocatorPool::new(num_of_threads),
format_options,
editorconfig,
#[cfg(feature = "napi")]
is_sort_package_json: false,
#[cfg(feature = "napi")]
Expand Down Expand Up @@ -93,11 +101,18 @@ impl SourceFormatter {
return Err(ret.errors.into_iter().next().unwrap());
}

let base_formatter = Formatter::new(&allocator, self.format_options.clone());
let format_options = if let Some(editorconfig) = &self.editorconfig {
let properties = editorconfig.resolve(path);
// TODO: create default options, override by editorconfig, then override by config options.
merge_editorconfig_and_format_options(properties)
} else {
self.format_options.clone()
};
let base_formatter = Formatter::new(&allocator, format_options.clone());

#[cfg(feature = "napi")]
let formatted = {
if self.format_options.embedded_language_formatting.is_off() {
if format_options.embedded_language_formatting.is_off() {
base_formatter.format(&ret.program)
} else {
let embedded_formatter = self
Expand Down
1 change: 1 addition & 0 deletions apps/oxfmt/src/core/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod editorconfig;
mod format;
mod support;
pub mod utils;
Expand Down
2 changes: 1 addition & 1 deletion justfile
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ oxfmt:

# watch oxfmt, e.g. `just watch-oxfmt test.js`
watch-oxfmt *args='':
just watch 'cargo run -p oxfmt -- {{args}}'
just watch 'cargo run -p oxfmt --no-default-features -- -c ./oxfmtrc.jsonc {{args}}'

# Build oxfmt in release build
oxfmt-node:
Expand Down
Loading