1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
15 # `nitpretty` is a tool able to pretty print Nit files.
17 # See `man nitpretty` for more infos.
20 redef class ToolContext
21 # The working directory used to store temp files.
22 var opt_dir
= new OptionString("Working directory (default is '.nitpretty')", "--dir")
24 # Output pretty printed code with this filename.
25 var opt_output
= new OptionString("Output name (default is pretty.nit)", "-o",
28 # Show diff between source and pretty printed code.
29 var opt_diff
= new OptionBool("Show diff between source and output", "--diff")
31 # Show diff between source and pretty printed code using meld.
32 var opt_meld
= new OptionBool("Show diff between source and output using meld",
36 var opt_line_width
= new OptionInt("Maximum length of lines (use 0 to disable automatic line breaks)", 80, "--line-width")
39 var opt_no_inline
= new OptionBool("Disable automatic one-liners", "--no-inline")
41 # Break too long string literals.
42 var opt_break_str
= new OptionBool("Break too long string literals", "--break-strings")
44 # Force `do` on the same line as the method signature.
45 var opt_inline_do
= new OptionBool("Force do keyword on the same line as the method signature",
48 # Force formatting on empty lines.
50 # By default empty lines are kept as they were typed in the file.
51 # When enabling this option, `nitpretty` will decide where to break lines
52 # and will put empty lines to separate properties and code blocks.
53 var opt_skip_empty
= new OptionBool("Force formatting of empty lines", "--skip-empty")
55 # Check formatting instead of pretty printing.
57 # This option creates a temporary pretty printed file then checks if the
58 # output of the diff command on the source file and the pretty printed one is
60 var opt_check
= new OptionBool("Check format of Nit source files", "--check")
63 # Return result from diff between `file1` and `file2`.
64 private fun diff
(file1
, file2
: String): String do
65 var p
= new ProcessReader("diff", "-u", file1
, file2
)
73 var toolcontext
= new ToolContext
75 var opts
= toolcontext
.option_context
76 opts
.add_option
(toolcontext
.opt_dir
, toolcontext
.opt_output
)
77 opts
.add_option
(toolcontext
.opt_diff
, toolcontext
.opt_meld
, toolcontext
.opt_check
)
78 opts
.add_option
(toolcontext
.opt_line_width
, toolcontext
.opt_break_str
, toolcontext
.opt_inline_do
)
79 opts
.add_option
(toolcontext
.opt_no_inline
)
80 opts
.add_option
(toolcontext
.opt_skip_empty
)
82 toolcontext
.tooldescription
= "Usage: nitpretty [OPTION]... <file.nit>\n" +
83 "Pretty print Nit code from Nit source files."
85 toolcontext
.process_options args
86 var arguments
= toolcontext
.option_context
.rest
89 var mbuilder
= new ModelBuilder(model
, toolcontext
)
90 var mmodules
= mbuilder
.parse_full
(arguments
)
93 if mmodules
.is_empty
then
94 print
"Error: no module to pretty print"
98 if not toolcontext
.opt_check
.value
and mmodules
.length
> 1 then
99 print
"Error: only --check option allow multiple modules"
103 var dir
= toolcontext
.opt_dir
.value
or else ".nitpretty"
104 if not dir
.file_exists
then dir
.mkdir
105 var v
= new PrettyPrinterVisitor
107 v
.max_size
= toolcontext
.opt_line_width
.value
108 if toolcontext
.opt_break_str
.value
then
109 v
.break_strings
= true
111 if toolcontext
.opt_inline_do
.value
then
114 if toolcontext
.opt_skip_empty
.value
then
117 if toolcontext
.opt_no_inline
.value
then
121 for mmodule
in mmodules
do
122 var nmodule
= mbuilder
.mmodule2node
(mmodule
)
123 if nmodule
== null then
124 print
" Error: no source file for module {mmodule}"
127 var file
= "{dir}/{mmodule.name}.nit"
128 var tpl
= v
.pretty_nmodule
(nmodule
)
129 tpl
.write_to_file file
131 if toolcontext
.opt_check
.value
then
132 var res
= diff
(nmodule
.location
.file
.filename
, file
)
134 if not res
.is_empty
then
135 print
"Wrong formating for module {nmodule.location.file.filename}"
136 toolcontext
.info
(res
, 1)
138 if toolcontext
.opt_meld
.value
then
139 sys
.system
"meld {nmodule.location.file.filename} {file}"
142 toolcontext
.info
("[OK] {nmodule.location.file.filename}", 1)
146 var out
= toolcontext
.opt_output
.value
147 if out
!= null then sys
.system
"cp {file} {out}"
150 if toolcontext
.opt_meld
.value
then
151 sys
.system
"meld {arguments.first} {file}"
156 if toolcontext
.opt_diff
.value
then
157 var res
= diff
(arguments
.first
, file
)
158 if not res
.is_empty
then print res
163 if not toolcontext
.opt_quiet
.value
then tpl
.write_to sys
.stdout