001/*
002 * (C) Copyright 2006-2010 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     bstefanescu
018 */
019package org.nuxeo.shell.cmds;
020
021import java.util.ArrayList;
022import java.util.List;
023import java.util.Map;
024import java.util.Set;
025
026import jline.ANSIBuffer;
027
028import org.nuxeo.shell.Command;
029import org.nuxeo.shell.CommandType;
030import org.nuxeo.shell.Context;
031import org.nuxeo.shell.Shell;
032import org.nuxeo.shell.ShellConsole;
033
034/**
035 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
036 */
037@Command(name = "commands", aliases = "cmds", help = "Print a list of available commands")
038public class Commands implements Runnable {
039
040    @Context
041    protected Shell shell;
042
043    public void run() {
044        ShellConsole console = shell.getConsole();
045        int termWidth = 0;
046        if (console instanceof Interactive) {
047            termWidth = ((Interactive) console).getConsole().getTermwidth();
048        }
049        ANSIBuffer buf = shell.newANSIBuffer();
050        Map<String, Set<CommandType>> cmds = shell.getActiveRegistry().getCommandTypesByNamespace();
051        for (Map.Entry<String, Set<CommandType>> entry : cmds.entrySet()) {
052            buf.bold(entry.getKey());
053            buf.append(ShellConsole.CRLF);
054            int i = 0;
055            for (CommandType type : entry.getValue()) {
056                int len = type.getName().length();
057                if (len > i) {
058                    i = len;
059                }
060            }
061            for (CommandType type : entry.getValue()) {
062                int len = i - type.getName().length();
063                StringBuilder sb = new StringBuilder();
064                sb.append("    ").append(type.getName());
065                for (int k = 0; k < len; k++) {
066                    sb.append(" ");
067                }
068                sb.append("    ");
069                String prefix = sb.toString();
070                buf.append(prefix);
071                prefix = makePrefix(sb.length());
072                wrap(buf, type.getHelp(), prefix, termWidth);
073            }
074            buf.append(ShellConsole.CRLF);
075        }
076        console.println(buf.toString());
077    }
078
079    public void wrap(ANSIBuffer buf, String text, String prefix, int termWidth) {
080        if (text == null) {
081            buf.append(ShellConsole.CRLF);
082        } else if (termWidth == 0) {
083            buf.append(text);
084            buf.append(ShellConsole.CRLF);
085        } else {
086            List<String> lines = split(text, termWidth - prefix.length());
087            if (lines.isEmpty()) {
088                buf.append(ShellConsole.CRLF);
089                return;
090            }
091            buf.append(lines.get(0));
092            buf.append(ShellConsole.CRLF);
093            for (int i = 1, len = lines.size(); i < len; i++) {
094                buf.append(prefix);
095                buf.append(lines.get(i));
096                buf.append(ShellConsole.CRLF);
097            }
098        }
099    }
100
101    protected List<String> split(String text, int width) {
102        ArrayList<String> lines = new ArrayList<String>();
103        int len = text.length();
104        if (len <= width) {
105            lines.add(text);
106        } else {
107            String r = text;
108            while (r.length() > width) {
109                int p = r.lastIndexOf(' ', width);
110                if (p == -1) {
111                    lines.add(r.substring(0, width));
112                    r = r.substring(width);
113                } else {
114                    lines.add(r.substring(0, p));
115                    r = r.substring(p + 1);
116                }
117            }
118            if (r.length() > 0) {
119                lines.add(r);
120            }
121        }
122        return lines;
123    }
124
125    protected String makePrefix(int len) {
126        StringBuilder buf = new StringBuilder();
127        for (int i = 0; i < len; i++) {
128            buf.append(' ');
129        }
130        return buf.toString();
131    }
132}