diff options
author | Bartek IwaĆczuk <biwanczuk@gmail.com> | 2021-09-13 20:19:10 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-09-13 20:19:10 +0200 |
commit | 0dbeb774ba9ea618ff1e92b63ab31e5caf3003dd (patch) | |
tree | 592244102cf046716acbb144233586c312ee7a7e /cli/lsp/language_server.rs | |
parent | a655a0f3e4201840eda94938fc8d6222c2b94a99 (diff) |
feat(fmt): add support for configuration file (#11944)
This commit adds support for configuration file for "deno fmt"
subcommand. It is also respected by LSP when formatting
files.
Example configuration:
{
"fmt": {
"files": {
"include": ["src/"],
"exclude": ["src/testdata/"]
},
"options": {
"useTabs": true,
"lineWidth": 80,
"indentWidth": 4,
"singleQuote": true,
"textWrap": "preserve"
}
}
}
Diffstat (limited to 'cli/lsp/language_server.rs')
-rw-r--r-- | cli/lsp/language_server.rs | 104 |
1 files changed, 69 insertions, 35 deletions
diff --git a/cli/lsp/language_server.rs b/cli/lsp/language_server.rs index 3f1bfc923..87fc5f7e5 100644 --- a/cli/lsp/language_server.rs +++ b/cli/lsp/language_server.rs @@ -336,15 +336,15 @@ impl Inner { Ok(navigation_tree) } - fn merge_user_tsconfig( - &mut self, - maybe_config: &Option<String>, - maybe_root_uri: &Option<Url>, - tsconfig: &mut TsConfig, - ) -> Result<(), AnyError> { - self.maybe_config_file = None; - self.maybe_config_uri = None; - if let Some(config_str) = maybe_config { + /// Returns a tuple with parsed `ConfigFile` and `Url` pointing to that file. + /// If there's no config file specified in settings returns `None`. + fn get_config_file_and_url( + &self, + ) -> Result<Option<(ConfigFile, Url)>, AnyError> { + let workspace_settings = self.config.get_workspace_settings(); + let maybe_root_uri = self.config.root_uri.clone(); + let maybe_config = workspace_settings.config; + if let Some(config_str) = &maybe_config { if !config_str.is_empty() { info!("Setting TypeScript configuration from: \"{}\"", config_str); let config_url = if let Ok(url) = Url::from_file_path(config_str) { @@ -374,18 +374,34 @@ impl Inner { .ok_or_else(|| anyhow!("Bad uri: \"{}\"", config_url))?; ConfigFile::read(path)? }; - let (value, maybe_ignored_options) = - config_file.to_compiler_options()?; - tsconfig.merge(&value); - self.maybe_config_file = Some(config_file); - self.maybe_config_uri = Some(config_url); - if let Some(ignored_options) = maybe_ignored_options { - // TODO(@kitsonk) turn these into diagnostics that can be sent to the - // client - warn!("{}", ignored_options); - } + return Ok(Some((config_file, config_url))); + } + } + + Ok(None) + } + + fn merge_user_tsconfig( + &mut self, + tsconfig: &mut TsConfig, + ) -> Result<(), AnyError> { + self.maybe_config_file = None; + self.maybe_config_uri = None; + + let maybe_file_and_url = self.get_config_file_and_url()?; + + if let Some((config_file, config_url)) = maybe_file_and_url { + let (value, maybe_ignored_options) = config_file.to_compiler_options()?; + tsconfig.merge(&value); + self.maybe_config_file = Some(config_file); + self.maybe_config_uri = Some(config_url); + if let Some(ignored_options) = maybe_ignored_options { + // TODO(@kitsonk) turn these into diagnostics that can be sent to the + // client + warn!("{}", ignored_options); } } + Ok(()) } @@ -575,20 +591,15 @@ impl Inner { // TODO(@kitsonk) remove for Deno 1.15 "useUnknownInCatchVariables": false, })); - let (maybe_config, maybe_root_uri) = { - let config = &self.config; - let workspace_settings = config.get_workspace_settings(); - if workspace_settings.unstable { - let unstable_libs = json!({ - "lib": ["deno.ns", "deno.window", "deno.unstable"] - }); - tsconfig.merge(&unstable_libs); - } - (workspace_settings.config, config.root_uri.clone()) - }; - if let Err(err) = - self.merge_user_tsconfig(&maybe_config, &maybe_root_uri, &mut tsconfig) - { + let config = &self.config; + let workspace_settings = config.get_workspace_settings(); + if workspace_settings.unstable { + let unstable_libs = json!({ + "lib": ["deno.ns", "deno.window", "deno.unstable"] + }); + tsconfig.merge(&unstable_libs); + } + if let Err(err) = self.merge_user_tsconfig(&mut tsconfig) { self.client.show_message(MessageType::Warning, err).await; } let _ok: bool = self @@ -1015,14 +1026,37 @@ impl Inner { PathBuf::from(params.text_document.uri.path()) }; + let maybe_file_and_url = self.get_config_file_and_url().map_err(|err| { + error!("Unable to parse configuration file: {}", err); + LspError::internal_error() + })?; + + let fmt_options = if let Some((config_file, _)) = maybe_file_and_url { + config_file + .to_fmt_config() + .map_err(|err| { + error!("Unable to parse fmt configuration: {}", err); + LspError::internal_error() + })? + .unwrap_or_default() + } else { + Default::default() + }; + let source = document_data.source().clone(); let text_edits = tokio::task::spawn_blocking(move || { let format_result = match source.module() { - Some(Ok(parsed_module)) => Ok(format_parsed_module(parsed_module)), + Some(Ok(parsed_module)) => { + Ok(format_parsed_module(parsed_module, fmt_options.options)) + } Some(Err(err)) => Err(err.to_string()), None => { // it's not a js/ts file, so attempt to format its contents - format_file(&file_path, source.text_info().text_str()) + format_file( + &file_path, + source.text_info().text_str(), + fmt_options.options, + ) } }; |