diff --git a/compiler/src/dotty/tools/dotc/config/CliCommand.scala b/compiler/src/dotty/tools/dotc/config/CliCommand.scala index 1a48fbfdf131..e361519bb54d 100644 --- a/compiler/src/dotty/tools/dotc/config/CliCommand.scala +++ b/compiler/src/dotty/tools/dotc/config/CliCommand.scala @@ -66,9 +66,39 @@ trait CliCommand: /** Creates a help message for a subset of options based on cond */ protected def availableOptionsMsg(cond: Setting[?] => Boolean)(using settings: ConcreteSettings)(using SettingsState): String = - val ss = (settings.allSettings filter cond).toList sortBy (_.name) - val width = (ss map (_.name.length)).max - def format(s: String) = ("%-" + width + "s") format s + val ss = (settings.allSettings filter cond).toList sortBy (_.name) + val maxNameWidth = 30 + val nameWidths = ss.map(_.name.length).partition(_ < maxNameWidth)._1 + val width = if nameWidths.nonEmpty then nameWidths.max else maxNameWidth + val terminalWidth = settings.pageWidth.value + val (nameWidth, descriptionWidth) = { + val w1 = + if width < maxNameWidth then width + else maxNameWidth + val w2 = + if terminalWidth < w1 + maxNameWidth then 0 + else terminalWidth - w1 - 1 + (w1, w2) + } + def formatName(name: String) = + if name.length <= nameWidth then ("%-" + nameWidth + "s") format name + else (name + "\n%-" + nameWidth + "s") format "" + def formatDescription(text: String): String = + if descriptionWidth == 0 then text + else if text.length < descriptionWidth then text + else { + val inx = text.substring(0, descriptionWidth).lastIndexOf(" ") + if inx < 0 then text + else + val str = text.substring(0, inx) + s"${str}\n${formatName("")} ${formatDescription(text.substring(inx + 1))}" + } + def formatSetting(name: String, value: String) = + if (value.nonEmpty) + // the format here is helping to make empty padding and put the additional information exactly under the description. + s"\n${formatName("")} $name: $value." + else + "" def helpStr(s: Setting[?]) = def defaultValue = s.default match case _: Int | _: String => s.default.toString @@ -76,16 +106,8 @@ trait CliCommand: // For now, skip the default values that do not make sense for the end user. // For example 'false' for the version command. "" - - def formatSetting(name: String, value: String) = - if (value.nonEmpty) - // the format here is helping to make empty padding and put the additional information exactly under the description. - s"\n${format("")} $name: $value." - else - "" - s"${format(s.name)} ${s.description}${formatSetting("Default", defaultValue)}${formatSetting("Choices", s.legalChoices)}" - - ss.map(helpStr).mkString("", "\n", s"\n${format("@")} A text file containing compiler arguments (options and source files).\n") + s"${formatName(s.name)} ${formatDescription(s.description)}${formatSetting("Default", defaultValue)}${formatSetting("Choices", s.legalChoices)}" + ss.map(helpStr).mkString("", "\n", s"\n${formatName("@")} ${formatDescription("A text file containing compiler arguments (options and source files).")}\n") protected def shortUsage: String = s"Usage: $cmdName " diff --git a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala index 7506976fa212..19e5a4cea229 100644 --- a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala +++ b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala @@ -11,6 +11,18 @@ import Settings.Setting trait CommonScalaSettings { self: Settings.SettingGroup => protected def defaultClasspath: String = sys.env.getOrElse("CLASSPATH", ".") + protected def defaultPageWidth: Int = { + val defaultWidth = 80 + val columnsVar = System.getenv("COLUMNS") + if columnsVar != null then columnsVar.toInt + else if Properties.isWin then + val ansiconVar = System.getenv("ANSICON") // eg. "142x32766 (142x26)" + if ansiconVar != null && ansiconVar.matches("[0-9]+x.*") then + ansiconVar.substring(0, ansiconVar.indexOf("x")).toInt + else defaultWidth + else defaultWidth + } + /** Path related settings */ val bootclasspath: Setting[String] = PathSetting("-bootclasspath", "Override location of bootstrap class files.", Defaults.scalaBootClassPath, aliases = List("--boot-class-path")) val extdirs: Setting[String] = PathSetting("-extdirs", "Override location of installed extensions.", Defaults.scalaExtDirs, aliases = List("--extension-directories")) @@ -26,7 +38,7 @@ trait CommonScalaSettings { self: Settings.SettingGroup => val verbose: Setting[Boolean] = BooleanSetting("-verbose", "Output messages about what the compiler is doing.", aliases = List("--verbose")) val version: Setting[Boolean] = BooleanSetting("-version", "Print product version and exit.", aliases = List("--version")) val help: Setting[Boolean] = BooleanSetting("-help", "Print a synopsis of standard options.", aliases = List("--help")) - val pageWidth: Setting[Int] = IntSetting("-pagewidth", "Set page width", 80, aliases = List("--page-width")) + val pageWidth: Setting[Int] = IntSetting("-pagewidth", "Set page width", defaultPageWidth, aliases = List("--page-width")) val silentWarnings: Setting[Boolean] = BooleanSetting("-nowarn", "Silence all warnings.", aliases = List("--no-warnings")) /** Other settings */ diff --git a/dist/bin/common b/dist/bin/common index da5ae4aeff66..a3847b2b1dbd 100755 --- a/dist/bin/common +++ b/dist/bin/common @@ -27,6 +27,12 @@ function onExit() { trap onExit INT TERM EXIT unset cygwin mingw msys darwin conemu + +# COLUMNS is used together with command line option '-pageWidth'. +if command -v tput >/dev/null 2>&1; then + export COLUMNS="$(tput -Tdumb cols)" +fi + case "`uname`" in CYGWIN*) cygwin=true ;;