blob: 6befcc80b370d04269af9bcbebd588137e3b829d [file] [log] [blame]
/*
* Copyright 2003-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.codehaus.groovy.tools.shell.util
import jline.Terminal
import org.apache.commons.cli.Options
//
// NOTE: Some code duplicated and augumented from commons-cli (1.0) sources to
// properly render options w/arguments.
//
/**
* Custom CLI help formatter to render things correctly.
*
* @version $Id$
* @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
*/
class HelpFormatter
extends org.apache.commons.cli.HelpFormatter
{
HelpFormatter() {
defaultLeftPad = 2
defaultDescPad = 4
}
// Detect the terminal width late
public int getDefaultWidth() {
return Terminal.terminal.terminalWidth - 1
}
protected StringBuffer renderOptions(final StringBuffer sb, final int width, final Options options, final int leftPad, final int descPad) {
assert sb != null
assert options
List prefixes = []
String lpad = ' ' * leftPad
List opts = options.shortOpts.values().sort { a, b ->
return (a.opt == ' ' ? a.longOpt : a.opt) <=> (b.opt == ' ' ? b.longOpt : b.opt)
}
// Render the prefixes (-X,--xxxx muck)
opts.each { option ->
def buff = new StringBuffer(8)
if (option.opt == ' ') {
buff << "${lpad} ${defaultLongOptPrefix}${option.longOpt}"
}
else {
buff << "${lpad}${defaultOptPrefix}${option.opt}"
if (option.hasLongOpt()) {
buff << ", ${defaultLongOptPrefix}${option.longOpt}"
}
}
if (option.hasArg()) {
if (option.hasArgName()) {
if (option.hasOptionalArg()) {
buff << "[=${option.argName}]"
}
else {
buff << "=${option.argName}"
}
}
else {
buff << ' '
}
}
prefixes << buff
}
// Figure out how long the biggest prefix is
int maxPrefix = prefixes.max { a, b -> a.size() <=> b.size() }.size()
String dpad = ' ' * descPad
// And then render each option's prefix with its description
opts.eachWithIndex { option, i ->
def buff = new StringBuffer(prefixes[i].toString())
if (buff.size() < maxPrefix) {
buff << ' ' * (maxPrefix - buff.size())
}
buff << dpad
int nextLineTabStop = maxPrefix + descPad
String text = buff << option.description
renderWrappedText(sb, width, nextLineTabStop, text)
if (i < opts.size() - 1) {
sb << defaultNewLine
}
}
return sb
}
}