diff --git a/.gitignore b/.gitignore index abab0fa64..c011ebff8 100644 --- a/.gitignore +++ b/.gitignore @@ -53,3 +53,4 @@ biome-main/ .review/ pglinter_repo/ .review/ +.opencode-session-id diff --git a/crates/pgls_configuration/src/format.rs b/crates/pgls_configuration/src/format.rs index 4c1e40d9e..022341f7c 100644 --- a/crates/pgls_configuration/src/format.rs +++ b/crates/pgls_configuration/src/format.rs @@ -101,6 +101,9 @@ pub struct FormatConfiguration { /// Data type casing (text, varchar, int): "upper" or "lower". Default: "lower". #[partial(bpaf(long("type-case")))] pub type_case: KeywordCase, + /// If `true`, skip formatting of SQL function bodies (keep them verbatim). Default: `false`. + #[partial(bpaf(long("skip-fn-bodies")))] + pub skip_fn_bodies: bool, /// A list of Unix shell style patterns. The formatter will ignore files/folders that will match these patterns. #[partial(bpaf(hide))] pub ignore: StringSet, @@ -119,6 +122,7 @@ impl Default for FormatConfiguration { keyword_case: KeywordCase::default(), constant_case: KeywordCase::default(), type_case: KeywordCase::default(), + skip_fn_bodies: false, ignore: Default::default(), include: Default::default(), } diff --git a/crates/pgls_workspace/src/settings.rs b/crates/pgls_workspace/src/settings.rs index 29ffad294..0cdf76408 100644 --- a/crates/pgls_workspace/src/settings.rs +++ b/crates/pgls_workspace/src/settings.rs @@ -376,6 +376,7 @@ fn to_formatter_settings( keyword_case: conf.keyword_case, constant_case: conf.constant_case, type_case: conf.type_case, + skip_fn_bodies: conf.skip_fn_bodies, ignored_files: to_matcher(working_directory.clone(), Some(&conf.ignore))?, included_files: to_matcher(working_directory.clone(), Some(&conf.include))?, }) @@ -566,6 +567,9 @@ pub struct FormatterSettings { /// Data type casing (text, varchar, int): upper or lower. Default: lower. pub type_case: KeywordCase, + /// If true, skip formatting of SQL function bodies (keep them verbatim). Default: false. + pub skip_fn_bodies: bool, + /// List of ignored paths/files to match pub ignored_files: Matcher, @@ -583,6 +587,7 @@ impl Default for FormatterSettings { keyword_case: KeywordCase::default(), constant_case: KeywordCase::default(), type_case: KeywordCase::default(), + skip_fn_bodies: false, ignored_files: Matcher::empty(), included_files: Matcher::empty(), } diff --git a/crates/pgls_workspace/src/workspace/server.rs b/crates/pgls_workspace/src/workspace/server.rs index ba61fdebc..ae3282e4a 100644 --- a/crates/pgls_workspace/src/workspace/server.rs +++ b/crates/pgls_workspace/src/workspace/server.rs @@ -892,24 +892,27 @@ impl Workspace for WorkspaceServer { let format_candidates: Vec<_> = doc.iter(FormatStatementMapper).collect(); let mut formatted_sql_fn_bodies = HashMap::new(); - for (id, _stmt_range, _text, ast_result) in &format_candidates { - if !id.is_child() { - continue; - } + // Only format SQL function bodies if skip_fn_bodies is false + if !settings.formatter.skip_fn_bodies { + for (id, _stmt_range, _text, ast_result) in &format_candidates { + if !id.is_child() { + continue; + } - let Some(parent_id) = id.parent() else { - continue; - }; + let Some(parent_id) = id.parent() else { + continue; + }; - let Ok(ast) = ast_result else { - continue; - }; + let Ok(ast) = ast_result else { + continue; + }; - let Ok(result) = pgls_pretty_print::format_statement(ast, &config) else { - continue; - }; + let Ok(result) = pgls_pretty_print::format_statement(ast, &config) else { + continue; + }; - formatted_sql_fn_bodies.insert(parent_id, result.formatted); + formatted_sql_fn_bodies.insert(parent_id, result.formatted); + } } for (id, stmt_range, text, ast_result) in format_candidates { diff --git a/docs/schema.json b/docs/schema.json index 3f08dd4d9..d43c461ab 100644 --- a/docs/schema.json +++ b/docs/schema.json @@ -534,6 +534,13 @@ "format": "uint16", "minimum": 0.0 }, + "skipFnBodies": { + "description": "If `true`, skip formatting of SQL function bodies (keep them verbatim). Default: `false`.", + "type": [ + "boolean", + "null" + ] + }, "typeCase": { "description": "Data type casing (text, varchar, int): \"upper\" or \"lower\". Default: \"lower\".", "anyOf": [ diff --git a/packages/@postgres-language-server/backend-jsonrpc/src/workspace.ts b/packages/@postgres-language-server/backend-jsonrpc/src/workspace.ts index 9f135f169..8bd384ab8 100644 --- a/packages/@postgres-language-server/backend-jsonrpc/src/workspace.ts +++ b/packages/@postgres-language-server/backend-jsonrpc/src/workspace.ts @@ -452,6 +452,10 @@ export interface PartialFormatConfiguration { * Maximum line width before breaking. Default: 100. */ lineWidth?: number; + /** + * If `true`, skip formatting of SQL function bodies (keep them verbatim). Default: `false`. + */ + skipFnBodies?: boolean; /** * Data type casing (text, varchar, int): "upper" or "lower". Default: "lower". */ diff --git a/packages/@postgrestools/backend-jsonrpc/src/workspace.ts b/packages/@postgrestools/backend-jsonrpc/src/workspace.ts index 9f135f169..8bd384ab8 100644 --- a/packages/@postgrestools/backend-jsonrpc/src/workspace.ts +++ b/packages/@postgrestools/backend-jsonrpc/src/workspace.ts @@ -452,6 +452,10 @@ export interface PartialFormatConfiguration { * Maximum line width before breaking. Default: 100. */ lineWidth?: number; + /** + * If `true`, skip formatting of SQL function bodies (keep them verbatim). Default: `false`. + */ + skipFnBodies?: boolean; /** * Data type casing (text, varchar, int): "upper" or "lower". Default: "lower". */