From dc8dd9946837105e23af521bc52031b035a76867 Mon Sep 17 00:00:00 2001 From: "Ilya.Kazakevich" Date: Tue, 24 Mar 2015 19:52:09 +0300 Subject: [PATCH] External URL help added for PY-11855 --- .../commandLine/psi/CommandLineArgument.java | 3 +- .../psi/impl/CommandLineArgumentImpl.java | 5 +- .../commandInterface/command/Argument.java | 16 ++-- .../commandInterface/command/Command.java | 4 +- .../commandInterface/command/Help.java | 63 ++++++++++++ .../commandInterface/command/Option.java | 6 +- .../command/UnknownArgumentsInfo.java | 4 +- .../CommandLineArgumentReference.java | 7 +- .../CommandLineCommandReference.java | 5 +- .../CommandLineDocumentationProvider.java | 95 ++++++++++++------- .../CommandLineOptionReference.java | 2 +- .../commandLine/command_line.bnf | 2 +- .../psi/impl/CommandLinePsiImplUtils.java | 9 +- .../console/ArgumentHintLayer.java | 2 +- .../commandLine/CommandLineArgsTest.java | 2 +- .../commandLine/CommandTestTools.java | 14 +-- 16 files changed, 167 insertions(+), 72 deletions(-) create mode 100644 python/src/com/jetbrains/commandInterface/command/Help.java diff --git a/python/gen/com/jetbrains/commandInterface/commandLine/psi/CommandLineArgument.java b/python/gen/com/jetbrains/commandInterface/commandLine/psi/CommandLineArgument.java index 1bae201e6ba5..cdc637d698cf 100644 --- a/python/gen/com/jetbrains/commandInterface/commandLine/psi/CommandLineArgument.java +++ b/python/gen/com/jetbrains/commandInterface/commandLine/psi/CommandLineArgument.java @@ -6,6 +6,7 @@ import org.jetbrains.annotations.*; import com.intellij.psi.PsiElement; import com.jetbrains.commandInterface.commandLine.CommandLinePart; import com.jetbrains.commandInterface.command.Argument; +import com.jetbrains.commandInterface.command.Help; import com.jetbrains.commandInterface.command.Option; public interface CommandLineArgument extends CommandLinePart { @@ -23,6 +24,6 @@ public interface CommandLineArgument extends CommandLinePart { Argument findRealArgument(); @Nullable - String findBestHelpText(); + Help findBestHelp(); } diff --git a/python/gen/com/jetbrains/commandInterface/commandLine/psi/impl/CommandLineArgumentImpl.java b/python/gen/com/jetbrains/commandInterface/commandLine/psi/impl/CommandLineArgumentImpl.java index 555d78259a6b..d8e8404ffcbc 100644 --- a/python/gen/com/jetbrains/commandInterface/commandLine/psi/impl/CommandLineArgumentImpl.java +++ b/python/gen/com/jetbrains/commandInterface/commandLine/psi/impl/CommandLineArgumentImpl.java @@ -11,6 +11,7 @@ import static com.jetbrains.commandInterface.commandLine.CommandLineElementTypes import com.jetbrains.commandInterface.commandLine.CommandLineElement; import com.jetbrains.commandInterface.commandLine.psi.*; import com.jetbrains.commandInterface.command.Argument; +import com.jetbrains.commandInterface.command.Help; import com.jetbrains.commandInterface.command.Option; public class CommandLineArgumentImpl extends CommandLineElement implements CommandLineArgument { @@ -47,8 +48,8 @@ public class CommandLineArgumentImpl extends CommandLineElement implements Comma } @Nullable - public String findBestHelpText() { - return CommandLinePsiImplUtils.findBestHelpText(this); + public Help findBestHelp() { + return CommandLinePsiImplUtils.findBestHelp(this); } } diff --git a/python/src/com/jetbrains/commandInterface/command/Argument.java b/python/src/com/jetbrains/commandInterface/command/Argument.java index 4bc8df656656..28105c32e85e 100644 --- a/python/src/com/jetbrains/commandInterface/command/Argument.java +++ b/python/src/com/jetbrains/commandInterface/command/Argument.java @@ -35,7 +35,7 @@ public final class Argument { * Argument help user-readable text */ @NotNull - private final String myHelpText; + private final Help myHelpText; /** * List of values argument may have. Null if any value is possible. */ @@ -48,7 +48,7 @@ public final class Argument { /** * @param helpText Argument help user-readable text */ - public Argument(@NotNull final String helpText) { + public Argument(@NotNull final Help helpText) { this(helpText, null, null); } @@ -56,14 +56,14 @@ public final class Argument { * @param type Argument value type. Null if any type is possible. */ public Argument(@NotNull final ArgumentType type) { - this("", type); + this(new Help(""), type); } /** * @param helpText Argument help user-readable text * @param type Argument value type. Null if any type is possible. */ - public Argument(@NotNull final String helpText, + public Argument(@NotNull final Help helpText, @Nullable final ArgumentType type) { this(helpText, null, type); } @@ -72,14 +72,14 @@ public final class Argument { * @param availableValues List of values argument may have. Null if any value is possible. */ public Argument(@Nullable final List availableValues) { - this("", availableValues, null); + this(new Help(""), availableValues, null); } /** * @param helpText Argument help user-readable text * @param availableValues List of values argument may have. Null if any value is possible. */ - public Argument(@NotNull final String helpText, @Nullable final List availableValues) { + public Argument(@NotNull final Help helpText, @Nullable final List availableValues) { this(helpText, availableValues, null); } @@ -89,7 +89,7 @@ public final class Argument { * @param availableValues List of values argument may have. Null if any value is possible. * @param type Argument value type. Null if any type is possible. */ - public Argument(@NotNull final String helpText, + public Argument(@NotNull final Help helpText, @Nullable final List availableValues, @Nullable final ArgumentType type) { myHelpText = helpText; @@ -101,7 +101,7 @@ public final class Argument { * @return Argument help user-readable text */ @NotNull - public String getHelpText() { + public Help getHelp() { return myHelpText; } diff --git a/python/src/com/jetbrains/commandInterface/command/Command.java b/python/src/com/jetbrains/commandInterface/command/Command.java index e2ab9e7192fd..44edea8aad73 100644 --- a/python/src/com/jetbrains/commandInterface/command/Command.java +++ b/python/src/com/jetbrains/commandInterface/command/Command.java @@ -39,10 +39,10 @@ public interface Command { * @param tryCutOutArguments Try to remove information about arguments from help text (i.e. "[file] removes file" -> "removes file"). * Command may or may not support it. * It should ignore argument if it does not know how to cut out argument info. - * @return Command readable help text + * @return Command help */ @Nullable - String getHelp(boolean tryCutOutArguments); + Help getHelp(boolean tryCutOutArguments); /** diff --git a/python/src/com/jetbrains/commandInterface/command/Help.java b/python/src/com/jetbrains/commandInterface/command/Help.java new file mode 100644 index 000000000000..f7154fe9e3c0 --- /dev/null +++ b/python/src/com/jetbrains/commandInterface/command/Help.java @@ -0,0 +1,63 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * 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 com.jetbrains.commandInterface.command; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * Covers element help: text and external url (if exists) + * + * @author Ilya.Kazakevich + */ +public final class Help { + @NotNull + private final String myHelpString; + @Nullable + private final String myExternalHelpUrl; + + /** + * @param helpString help text (no external url provided) + */ + public Help(@NotNull final String helpString) { + this(helpString, null); + } + + /** + * @param helpString help text + * @param externalHelpUrl external help url (if any) + */ + public Help(@NotNull final String helpString, @Nullable final String externalHelpUrl) { + myHelpString = helpString; + myExternalHelpUrl = externalHelpUrl; + } + + /** + * @return help text + */ + @NotNull + public String getHelpString() { + return myHelpString; + } + + /** + * @return external help url (if any) + */ + @Nullable + public String getExternalHelpUrl() { + return myExternalHelpUrl; + } +} diff --git a/python/src/com/jetbrains/commandInterface/command/Option.java b/python/src/com/jetbrains/commandInterface/command/Option.java index c652d1cd951c..e9614cf3a8b2 100644 --- a/python/src/com/jetbrains/commandInterface/command/Option.java +++ b/python/src/com/jetbrains/commandInterface/command/Option.java @@ -39,7 +39,7 @@ public final class Option { @Nullable private final Pair myArgumentAndQuantity; @NotNull - private final String myHelp; + private final Help myHelp; /** * @param argumentAndQuantity if option accepts argument, there should be pair of [argument_quantity, its_type_info] @@ -48,7 +48,7 @@ public final class Option { * @param longNames option long names */ public Option(@Nullable final Pair argumentAndQuantity, - @NotNull final String help, + @NotNull final Help help, @NotNull final Collection shortNames, @NotNull final Collection longNames) { Preconditions @@ -99,7 +99,7 @@ public final class Option { * @return Option help */ @NotNull - public String getHelp() { + public Help getHelp() { return myHelp; } } diff --git a/python/src/com/jetbrains/commandInterface/command/UnknownArgumentsInfo.java b/python/src/com/jetbrains/commandInterface/command/UnknownArgumentsInfo.java index f6b75ea0d3f9..fce1fb291f32 100644 --- a/python/src/com/jetbrains/commandInterface/command/UnknownArgumentsInfo.java +++ b/python/src/com/jetbrains/commandInterface/command/UnknownArgumentsInfo.java @@ -30,12 +30,12 @@ public final class UnknownArgumentsInfo implements ArgumentsInfo { * Argument help text */ @NotNull - private final String myHelp; + private final Help myHelp; /** * @param allArgumentsHelpText argument help text */ - public UnknownArgumentsInfo(@NotNull final String allArgumentsHelpText) { + public UnknownArgumentsInfo(@NotNull final Help allArgumentsHelpText) { myHelp = allArgumentsHelpText; } diff --git a/python/src/com/jetbrains/commandInterface/commandLine/CommandLineArgumentReference.java b/python/src/com/jetbrains/commandInterface/commandLine/CommandLineArgumentReference.java index 9e2c0e76fce3..e5bf7fd6555d 100644 --- a/python/src/com/jetbrains/commandInterface/commandLine/CommandLineArgumentReference.java +++ b/python/src/com/jetbrains/commandInterface/commandLine/CommandLineArgumentReference.java @@ -18,6 +18,7 @@ package com.jetbrains.commandInterface.commandLine; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.psi.PsiElement; import com.jetbrains.commandInterface.command.Argument; +import com.jetbrains.commandInterface.command.Help; import com.jetbrains.commandInterface.command.Option; import com.jetbrains.commandInterface.commandLine.psi.CommandLineArgument; import org.jetbrains.annotations.NotNull; @@ -53,7 +54,9 @@ public final class CommandLineArgumentReference extends CommandLineElementRefere // priority is used to display args before options if (argumentValues != null) { for (final String value : argumentValues) { - builder.addElement(LookupElementBuilder.create(value).withBoldness(true), getElement().findBestHelpText(), 1); + final Help help = getElement().findBestHelp(); + final String helpText = (help != null ? help.getHelpString() : null); + builder.addElement(LookupElementBuilder.create(value).withBoldness(true), helpText, 1); } } @@ -66,7 +69,7 @@ public final class CommandLineArgumentReference extends CommandLineElementRefere if (argumentOption == null) { // If not option argument for (final Option option : validationResult.getUnusedOptions()) { for (final String value : option.getAllNames()) { - builder.addElement(LookupElementBuilder.create(value), option.getHelp(), 0); + builder.addElement(LookupElementBuilder.create(value), option.getHelp().getHelpString(), 0); } } } diff --git a/python/src/com/jetbrains/commandInterface/commandLine/CommandLineCommandReference.java b/python/src/com/jetbrains/commandInterface/commandLine/CommandLineCommandReference.java index ddf220258872..cca893ce0b81 100644 --- a/python/src/com/jetbrains/commandInterface/commandLine/CommandLineCommandReference.java +++ b/python/src/com/jetbrains/commandInterface/commandLine/CommandLineCommandReference.java @@ -18,6 +18,7 @@ package com.jetbrains.commandInterface.commandLine; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.psi.PsiElement; import com.jetbrains.commandInterface.command.Command; +import com.jetbrains.commandInterface.command.Help; import com.jetbrains.commandInterface.commandLine.psi.CommandLineCommand; import com.jetbrains.commandInterface.commandLine.psi.CommandLineFile; import org.jetbrains.annotations.NotNull; @@ -58,8 +59,8 @@ public final class CommandLineCommandReference extends CommandLineElementReferen for (final Command command : commands) { final LookupElementBuilder lookupElementBuilder = LookupElementBuilder.create(command.getName()); - final String help = command.getHelp(true); - result.addElement(lookupElementBuilder, help); + final Help help = command.getHelp(true); + result.addElement(lookupElementBuilder, (help != null ? help.getHelpString(): null)); } diff --git a/python/src/com/jetbrains/commandInterface/commandLine/CommandLineDocumentationProvider.java b/python/src/com/jetbrains/commandInterface/commandLine/CommandLineDocumentationProvider.java index 64957fca9d2a..7c41e3d3b252 100644 --- a/python/src/com/jetbrains/commandInterface/commandLine/CommandLineDocumentationProvider.java +++ b/python/src/com/jetbrains/commandInterface/commandLine/CommandLineDocumentationProvider.java @@ -22,12 +22,16 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiTreeUtil; import com.jetbrains.commandInterface.command.Command; +import com.jetbrains.commandInterface.command.Help; import com.jetbrains.commandInterface.command.Option; import com.jetbrains.commandInterface.commandLine.psi.*; import com.jetbrains.python.psi.PyUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Collections; +import java.util.List; + /** * Provides quick help for arguments * @@ -37,34 +41,27 @@ public final class CommandLineDocumentationProvider extends DocumentationProvide @Nullable @Override public String generateDoc(final PsiElement element, @Nullable final PsiElement originalElement) { - if (!(element instanceof CommandLinePart)) { + final Help help = findHelp(element); + if (help == null) { return null; } - - final CommandLinePart commandLinePart = (CommandLinePart)element; - final Command realCommand = commandLinePart.findRealCommand(); - if (realCommand == null) { - return null; - } - - if (element instanceof CommandLineFile) { - return realCommand.getHelp(false); // We do not need arguments info in help text - } - - final CommandLineElement commandLineElement = PyUtil.as(element, CommandLineElement.class); - if (commandLineElement == null) { - return null; - } - - - final MyCommandHelpObtainer helpObtainer = new MyCommandHelpObtainer(realCommand); - commandLineElement.accept(helpObtainer); - - final String help = helpObtainer.myResultText; - // For some reason we can't return empty sting (leads to "fetchig doc" string) - return (StringUtil.isEmptyOrSpaces(help) ? null : help); + final String helpText = help.getHelpString(); + // For some reason we can't return empty sting (leads to "fetching doc" string) + return (StringUtil.isEmptyOrSpaces(helpText) ? null : helpText); } + @Override + public List getUrlFor(final PsiElement element, final PsiElement originalElement) { + final Help help = findHelp(element); + if (help == null) { + return null; + } + final String externalHelpUrl = help.getExternalHelpUrl(); + if (externalHelpUrl != null) { + return Collections.singletonList(externalHelpUrl); + } + return null; + } @Nullable @Override @@ -78,27 +75,55 @@ public final class CommandLineDocumentationProvider extends DocumentationProvide return PyUtil.as(file, CommandLineFile.class); } + /** + * Searches for help text for certain element + * @param element element to search help for + * @return help or + * + */ + @Nullable + private static Help findHelp(@NotNull final PsiElement element) { + if (!(element instanceof CommandLinePart)) { + return null; + } + + final CommandLinePart commandLinePart = (CommandLinePart)element; + final Command realCommand = commandLinePart.findRealCommand(); + if (realCommand == null) { + return null; + } + + final CommandLineElement commandLineElement = PyUtil.as(element, CommandLineElement.class); + if (commandLineElement == null) { + return null; + } + + + final MyCommandHelpObtainer helpObtainer = new MyCommandHelpObtainer(); + commandLineElement.accept(helpObtainer); + + return helpObtainer.myResultHelp; + } + /** * Fetches text from command line part as visitor */ private static final class MyCommandHelpObtainer extends CommandLineVisitor { - private String myResultText; - private final Command myRealCommand; - - private MyCommandHelpObtainer(@NotNull final Command realCommand) { - myRealCommand = realCommand; - } + private Help myResultHelp; @Override public void visitArgument(@NotNull final CommandLineArgument o) { super.visitArgument(o); - myResultText = o.findBestHelpText(); + myResultHelp = o.findBestHelp(); } @Override - public void visitCommand(@NotNull final CommandLineCommand o) { + public void visitCommand(@NotNull CommandLineCommand o) { super.visitCommand(o); - myResultText = myRealCommand.getHelp(false); + final Command realCommand = o.findRealCommand(); + if (realCommand != null) { + myResultHelp = realCommand.getHelp(false); // Arguments are ok to display here; + } } @Override @@ -108,7 +133,7 @@ public final class CommandLineDocumentationProvider extends DocumentationProvide if (option == null) { return; } - myResultText = option.getHelp(); + myResultHelp = option.getHelp(); } } -} +} \ No newline at end of file diff --git a/python/src/com/jetbrains/commandInterface/commandLine/CommandLineOptionReference.java b/python/src/com/jetbrains/commandInterface/commandLine/CommandLineOptionReference.java index 7f40960d231a..ee43d063ec49 100644 --- a/python/src/com/jetbrains/commandInterface/commandLine/CommandLineOptionReference.java +++ b/python/src/com/jetbrains/commandInterface/commandLine/CommandLineOptionReference.java @@ -55,7 +55,7 @@ public final class CommandLineOptionReference extends CommandLineElementReferenc // Suggest long options for -- and short for - final List names = getElement().isLong() ? option.getLongNames() : option.getShortNames(); for (final String optionName : names) { - builder.addElement(LookupElementBuilder.create(optionName), option.getHelp()); + builder.addElement(LookupElementBuilder.create(optionName), option.getHelp().getHelpString()); } } diff --git a/python/src/com/jetbrains/commandInterface/commandLine/command_line.bnf b/python/src/com/jetbrains/commandInterface/commandLine/command_line.bnf index c26d14cffdc3..6d80c455abce 100644 --- a/python/src/com/jetbrains/commandInterface/commandLine/command_line.bnf +++ b/python/src/com/jetbrains/commandInterface/commandLine/command_line.bnf @@ -41,6 +41,6 @@ methods=[ getOptionName isLong findRealOption ] private short_option_name ::= SHORT_OPTION_NAME_TOKEN private long_option_name ::= LONG_OPTION_NAME_TOKEN argument ::= LITERAL_STARTS_FROM_LETTER | LITERAL_STARTS_FROM_DIGIT { -methods=[ findOptionForOptionArgument findRealArgument findBestHelpText ] +methods=[ findOptionForOptionArgument findRealArgument findBestHelp ] } diff --git a/python/src/com/jetbrains/commandInterface/commandLine/psi/impl/CommandLinePsiImplUtils.java b/python/src/com/jetbrains/commandInterface/commandLine/psi/impl/CommandLinePsiImplUtils.java index a42883ca3eaa..8d7948360a6d 100644 --- a/python/src/com/jetbrains/commandInterface/commandLine/psi/impl/CommandLinePsiImplUtils.java +++ b/python/src/com/jetbrains/commandInterface/commandLine/psi/impl/CommandLinePsiImplUtils.java @@ -17,6 +17,7 @@ package com.jetbrains.commandInterface.commandLine.psi.impl; import com.intellij.psi.PsiElement; import com.jetbrains.commandInterface.command.Argument; +import com.jetbrains.commandInterface.command.Help; import com.jetbrains.commandInterface.command.Option; import com.jetbrains.commandInterface.commandLine.CommandLinePart; import com.jetbrains.commandInterface.commandLine.ValidationResult; @@ -66,20 +67,20 @@ final class CommandLinePsiImplUtils { /** - * Tries to find appropriate help text for argument. It can be argument help string for positional argument or option help + * Tries to find appropriate help for argument. It can be argument help for positional argument or option help * for option argument. * * @param argument argument to search help for - * @return help string for argument or null if not found + * @return help for argument or null if not found */ @Nullable - static String findBestHelpText(@NotNull final CommandLineArgument argument) { + static Help findBestHelp(@NotNull final CommandLineArgument argument) { final Option option = argument.findOptionForOptionArgument(); if (option != null) { return option.getHelp(); } final Argument realArgument = argument.findRealArgument(); - return (realArgument != null ? realArgument.getHelpText() : null); + return (realArgument != null ? realArgument.getHelp() : null); } diff --git a/python/src/com/jetbrains/commandInterface/console/ArgumentHintLayer.java b/python/src/com/jetbrains/commandInterface/console/ArgumentHintLayer.java index b0f6f4924e26..dcf51bf8b839 100644 --- a/python/src/com/jetbrains/commandInterface/console/ArgumentHintLayer.java +++ b/python/src/com/jetbrains/commandInterface/console/ArgumentHintLayer.java @@ -166,7 +166,7 @@ final class ArgumentHintLayer extends JPanel implements Listener { final int x = (myPromptWidthPx + (myCharWidthPx * myDocumentLengthInChars)) + spaceToRight; final boolean required = nextArg.first; - final String argumentText = nextArg.second.getHelpText(); + final String argumentText = nextArg.second.getHelp().getHelpString(); g.setColor(required ? myRequiredColor : myOptionalColor); diff --git a/python/testSrc/com/jetbrains/commandInterface/commandLine/CommandLineArgsTest.java b/python/testSrc/com/jetbrains/commandInterface/commandLine/CommandLineArgsTest.java index dc9be94ac4a4..073dbd831e50 100644 --- a/python/testSrc/com/jetbrains/commandInterface/commandLine/CommandLineArgsTest.java +++ b/python/testSrc/com/jetbrains/commandInterface/commandLine/CommandLineArgsTest.java @@ -69,6 +69,6 @@ public final class CommandLineArgsTest extends PyTestCase { final Pair arg = validationResult.getNextArg(); Assert.assertNotNull("No argument returned, but should", arg); Assert.assertTrue("Required argument is not marked as required", arg.first); - Assert.assertEquals("Wrong argument text", expectedArgumentText, arg.second.getHelpText()); + Assert.assertEquals("Wrong argument text", expectedArgumentText, arg.second.getHelp().getHelpString()); } } diff --git a/python/testSrc/com/jetbrains/commandInterface/commandLine/CommandTestTools.java b/python/testSrc/com/jetbrains/commandInterface/commandLine/CommandTestTools.java index 8df8c0864d23..98681eda4f4f 100644 --- a/python/testSrc/com/jetbrains/commandInterface/commandLine/CommandTestTools.java +++ b/python/testSrc/com/jetbrains/commandInterface/commandLine/CommandTestTools.java @@ -53,17 +53,17 @@ final class CommandTestTools { //command positional_argument --available-option=available_argument final Command command = EasyMock.createMock(Command.class); EasyMock.expect(command.getName()).andReturn("command").anyTimes(); - EasyMock.expect(command.getHelp(true)).andReturn("some_text").anyTimes(); - EasyMock.expect(command.getHelp(false)).andReturn("some_text").anyTimes(); + EasyMock.expect(command.getHelp(true)).andReturn(new Help("some_text")).anyTimes(); + EasyMock.expect(command.getHelp(false)).andReturn(new Help("some_text")).anyTimes(); final List