/**
* Copyright (c) 2005-2017, KoLmafia development team
* http://kolmafia.sourceforge.net/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* [1] Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* [2] Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* [3] Neither the name "KoLmafia" nor the names of its contributors may
* be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION ) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package net.sourceforge.kolmafia.textui.command;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.java.dev.spellcast.utilities.DataUtilities;
import net.sourceforge.kolmafia.KoLmafia;
import net.sourceforge.kolmafia.KoLmafiaCLI;
import net.sourceforge.kolmafia.RequestLogger;
import net.sourceforge.kolmafia.utilities.PrefixMap;
public class CliRefCommand
extends AbstractCommand
{
public CliRefCommand()
{
this.usage = " [<filter>] - list CLI commands [that match filter].";
}
static private Pattern PLACEHOLDER = Pattern.compile( "<(.+?)>" );
@Override
public void run( final String cmd, String filter )
{
filter = filter.toLowerCase();
if ( filter.equals( "help" ) )
{
RequestLogger.printLine( "Square brackets [ ] enclose optional elements of " + "commands. In command descriptions, they may also enclose the effects of " + "using those optional elements." );
RequestLogger.printLine();
RequestLogger.printLine( "Vertical bars | separate alternative elements - " + "choose any one. (But note that || is an actual part of a few commands.)" );
RequestLogger.printLine();
RequestLogger.printLine( "An ellipsis ... after an element means that it " + "can be repeated as many times as needed." );
RequestLogger.printLine();
RequestLogger.printLine( "Elements in <i>italics</i> are placeholders - " + "replace them with an actual name you want the command to operate on." );
RequestLogger.printLine();
RequestLogger.printLine( "Commands with an asterisk * after the name are " + "abbreviations - you can type them in a longer form if desired." );
RequestLogger.printLine();
RequestLogger.printLine( "Some command names can be followed by a question " + "mark (shown as [?] ), in which case the command will just display what it " + "would do, rather than actually doing it." );
RequestLogger.printLine();
RequestLogger.printLine( "When adventuring, or using an item or skill, the " + "name can be preceded by a number specifying how many times to do it. An " + "asterisk in place of this number means \"as many as possible\" or \"the " + "current quantity in inventory\", depending on context. Negative numbers " + "mean to do that many less than the maximum." );
RequestLogger.printLine();
RequestLogger.printLine( "Usually, multiple commands can be given on the " + "same line, separated by semicolons. The exceptions (" + AbstractCommand.fullLineCmds + ") treat the entire remainder of the line as a parameter." );
RequestLogger.printLine();
RequestLogger.printLine( "A few commands (" + AbstractCommand.flowControlCmds + ") treat at least one following command as a block that is executed " + "conditionally or repetitively. The block consists of the remainder of the " + "line, or the entire next line if that's empty. The block is extended by " + "additional lines if it would otherwise end with one of these special " + "commands." );
return;
}
boolean anymatches = false;
HashMap alreadySeen = new HashMap(); // usage => name of cmd already printed out
Iterator i = AbstractCommand.lookup.entrySet().iterator();
while ( i.hasNext() )
{
Map.Entry e = (Map.Entry) i.next();
String name = (String) e.getKey();
int type = AbstractCommand.lookup.getKeyType( name );
if ( type == PrefixMap.NOT_A_KEY )
{
continue;
}
AbstractCommand handler = (AbstractCommand) e.getValue();
if ( handler == null ) // shouldn't happen
{
continue;
}
String usage = handler.getUsage( name );
if ( usage == null || name.indexOf( filter ) == -1 && usage.toLowerCase().indexOf( filter ) == -1 )
{
continue;
}
if ( type == PrefixMap.PREFIX_KEY )
{
name += "*";
}
if ( KoLmafiaCLI.isExecutingCheckOnlyCommand )
{
RequestLogger.printLine( DataUtilities.convertToHTML( name ) + " @ " + handler.getClass().getName() );
anymatches = true;
continue;
}
String previouslySeen = (String) alreadySeen.get( usage );
if ( previouslySeen == null )
{
// This isn't turning out very useful
// alreadySeen.put( usage, name );
}
else
{
usage = " => " + previouslySeen;
}
anymatches = true;
Matcher m = CliRefCommand.PLACEHOLDER.matcher( usage );
while ( m.find() )
{
usage = Pattern.compile( "<?(\\Q" + m.group( 1 ) + "\\E)>?" ).matcher( usage ).replaceAll( "<i>$1</i>" );
}
RequestLogger.printLine( DataUtilities.convertToHTML( name ) + usage );
}
if ( !anymatches )
{
KoLmafia.updateDisplay( "No matching commands found!" );
}
}
}