diff --git a/src/formatter.jl b/src/formatter.jl index 750d47cb..dd558f27 100644 --- a/src/formatter.jl +++ b/src/formatter.jl @@ -1,39 +1,61 @@ using JuliaFormatter +@static if isdefined(JuliaFormatter, :CONFIG_FILE_NAME) && + isdefined(JuliaFormatter, :kwargs) && + isdefined(JuliaFormatter, :parse_config) && + isdefined(JuliaFormatter, :overwrite_options) + using JuliaFormatter: CONFIG_FILE_NAME, kwargs, parse_config, overwrite_options +else + const CONFIG_FILE_NAME = ".JuliaFormatter.toml" + + function kwargs(dict) + ns = (Symbol.(keys(dict))...,) + vs = (collect(values(dict))...,) + return pairs(NamedTuple{ns}(vs)) + end + + function parse_config(tomlfile) + config_dict = Pkg.TOML.parsefile(tomlfile) + if (style = get(config_dict, "style", nothing)) !== nothing + @assert (style == "default" || style == "yas") "currently $(CONFIG_FILE_NAME) accepts only \"default\" or \"yas\" for the style configuration" + if style == "yas" && isdefined(JuliaFormatter, :YASStyle) + config_dict["style"] = JuliaFormatter.YASStyle() + end + end + return kwargs(config_dict) + end + + overwrite_options(options, config) = kwargs(merge(options, config)) +end + handle("format") do data @destruct [ text, + dir, indent || 4, margin || 92, - always_for_in || false, - whitespace_typedefs || false, - whitespace_ops_in_indices || false, - remove_extra_newlines || false, - import_to_using || false, - pipe_to_function_call || false, - short_to_long_function_def || false, - always_use_return || false, - use_YAS_style || false ] = data - style = (use_YAS_style && isdefined(JuliaFormatter, :YASStyle)) ? - JuliaFormatter.YASStyle() : - JuliaFormatter.DefaultStyle() - - return Dict(:formattedtext => format_text′( - text; - indent = indent, - margin = margin, - always_for_in = always_for_in, - whitespace_typedefs = whitespace_typedefs, - whitespace_ops_in_indices = whitespace_ops_in_indices, - remove_extra_newlines = remove_extra_newlines, - import_to_using = import_to_using, - pipe_to_function_call = pipe_to_function_call, - short_to_long_function_def = short_to_long_function_def, - always_use_return = always_use_return, - style = style - )) + options = if (config_path = search_up_file(CONFIG_FILE_NAME, dir)) === nothing + kwargs((indent = indent, margin = margin)) # fallback + else + kwargs(parse_config(config_path)) + end + + try + return (formattedtext = format_text′(text; options...),) + catch err + if err isa ErrorException && startswith(err.msg, "Parsing error") + return (error = """ + Juno's formatter expects a text that can be parsed into a valid Julia expression. + The given text below couldn't be parsed correctly: + ``` + $(replace(strip(text), "```" => "\`\`\`")) + ``` + """,) + end + return (error = """\n$(string(err))\n""",) + end end # HACK: extract keyword arguments of `format_text`; `Base.kwarg_decl` isn't available as of v1.0 @@ -48,10 +70,5 @@ function format_text′(text; kwargs...) valid_kwargs_dict = filter(kwargs) do (k, _) @static isempty(FORMAT_TEXT_KWARGS) ? false : in(k,FORMAT_TEXT_KWARGS) end - ks = (collect(keys(valid_kwargs_dict))...,) - vs = (collect(values(valid_kwargs_dict))...,) - valid_kwargs_nt = NamedTuple{ks}(vs) - valid_kwargs = pairs(valid_kwargs_nt) - - format_text(text; valid_kwargs...) + return format_text(text; kwargs(valid_kwargs_dict)...) end diff --git a/src/misc.jl b/src/misc.jl index 35521e64..db3110f2 100644 --- a/src/misc.jl +++ b/src/misc.jl @@ -29,7 +29,7 @@ end handle("activateParentProject") do dir hideprompt() do - if (path = find_project_file(dir)) === nothing + if (path = search_up_file("Project.toml", dir)) === nothing @warn "No project file found for `$dir`" return end @@ -37,19 +37,6 @@ handle("activateParentProject") do dir end end -function find_project_file(dir) - while true - next_dir = dirname(dir) - ( - next_dir == dir || # ensure to escape infinite recursion - isempty(dir) # reached to the system root - ) && return nothing - path = joinpath(dir, "Project.toml") - isfile(path) && return path - dir = next_dir - end -end - handle("activateDefaultProject") do hideprompt() do Pkg.activate() diff --git a/src/utils.jl b/src/utils.jl index c01c6c70..4a653576 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -12,6 +12,17 @@ end iswritablefile(file) = Base.uperm(file) == 0x06 nonwritablefiles(files) = filter(!iswritablefile, files) +function search_up_file(basename, dir) + parent_dir = dirname(dir) + return if (parent_dir == dir || # ensure to escape infinite recursion + isempty(dir)) # reached to the system root + nothing + else + path = joinpath(dir, basename) + isfile(path) ? path : search_up_file(basename, parent_dir) + end +end + # path utilities # --------------