001/*
002 * (C) Copyright 2006-2010 Nuxeo SAS (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     bstefanescu
016 */
017package org.nuxeo.shell.cmds;
018
019import java.util.ArrayList;
020import java.util.List;
021import java.util.Map;
022import java.util.Set;
023
024import jline.ANSIBuffer;
025
026import org.nuxeo.shell.Command;
027import org.nuxeo.shell.CommandType;
028import org.nuxeo.shell.Context;
029import org.nuxeo.shell.Shell;
030import org.nuxeo.shell.ShellConsole;
031
032/**
033 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
034 */
035@Command(name = "commands", aliases = "cmds", help = "Print a list of available commands")
036public class Commands implements Runnable {
037
038    @Context
039    protected Shell shell;
040
041    public void run() {
042        ShellConsole console = shell.getConsole();
043        int termWidth = 0;
044        if (console instanceof Interactive) {
045            termWidth = ((Interactive) console).getConsole().getTermwidth();
046        }
047        ANSIBuffer buf = shell.newANSIBuffer();
048        Map<String, Set<CommandType>> cmds = shell.getActiveRegistry().getCommandTypesByNamespace();
049        for (Map.Entry<String, Set<CommandType>> entry : cmds.entrySet()) {
050            buf.bold(entry.getKey());
051            buf.append(ShellConsole.CRLF);
052            int i = 0;
053            for (CommandType type : entry.getValue()) {
054                int len = type.getName().length();
055                if (len > i) {
056                    i = len;
057                }
058            }
059            for (CommandType type : entry.getValue()) {
060                int len = i - type.getName().length();
061                StringBuilder sb = new StringBuilder();
062                sb.append("    ").append(type.getName());
063                for (int k = 0; k < len; k++) {
064                    sb.append(" ");
065                }
066                sb.append("    ");
067                String prefix = sb.toString();
068                buf.append(prefix);
069                prefix = makePrefix(sb.length());
070                wrap(buf, type.getHelp(), prefix, termWidth);
071            }
072            buf.append(ShellConsole.CRLF);
073        }
074        console.println(buf.toString());
075    }
076
077    public void wrap(ANSIBuffer buf, String text, String prefix, int termWidth) {
078        if (text == null) {
079            buf.append(ShellConsole.CRLF);
080        } else if (termWidth == 0) {
081            buf.append(text);
082            buf.append(ShellConsole.CRLF);
083        } else {
084            List<String> lines = split(text, termWidth - prefix.length());
085            if (lines.isEmpty()) {
086                buf.append(ShellConsole.CRLF);
087                return;
088            }
089            buf.append(lines.get(0));
090            buf.append(ShellConsole.CRLF);
091            for (int i = 1, len = lines.size(); i < len; i++) {
092                buf.append(prefix);
093                buf.append(lines.get(i));
094                buf.append(ShellConsole.CRLF);
095            }
096        }
097    }
098
099    protected List<String> split(String text, int width) {
100        ArrayList<String> lines = new ArrayList<String>();
101        int len = text.length();
102        if (len <= width) {
103            lines.add(text);
104        } else {
105            String r = text;
106            while (r.length() > width) {
107                int p = r.lastIndexOf(' ', width);
108                if (p == -1) {
109                    lines.add(r.substring(0, width));
110                    r = r.substring(width);
111                } else {
112                    lines.add(r.substring(0, p));
113                    r = r.substring(p + 1);
114                }
115            }
116            if (r.length() > 0) {
117                lines.add(r);
118            }
119        }
120        return lines;
121    }
122
123    protected String makePrefix(int len) {
124        StringBuilder buf = new StringBuilder();
125        for (int i = 0; i < len; i++) {
126            buf.append(' ');
127        }
128        return buf.toString();
129    }
130}