Generation based on Grammar-Kit, see .bnf file, do not edit parser nor lexer manually.
+ * When parsed, {@link com.jetbrains.commandInterface.gnuCommandLine.psi.CommandLineFile} is root element for
+ * {@link com.jetbrains.commandInterface.gnuCommandLine.CommandLineLanguage}.
+ * Warning: always fill {@link com.jetbrains.commandInterface.gnuCommandLine.psi.CommandLineFile#setCommands(java.util.List)}
+ * if possible.
+ *
+ *
Extension points
+ *
This package has a a lot of extension points (language, inspection etc). Make sure all of them are registered
+ *
+ *
+ * @author Ilya.Kazakevich
+ */
+package com.jetbrains.commandInterface.gnuCommandLine;
\ No newline at end of file
diff --git a/python/src/com/jetbrains/commandInterface/gnuCommandLine/psi/CommandLineFile.java b/python/src/com/jetbrains/commandInterface/gnuCommandLine/psi/CommandLineFile.java
new file mode 100644
index 000000000000..aff97816cc54
--- /dev/null
+++ b/python/src/com/jetbrains/commandInterface/gnuCommandLine/psi/CommandLineFile.java
@@ -0,0 +1,130 @@
+/*
+ * 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.gnuCommandLine.psi;
+
+import com.intellij.extapi.psi.PsiFileBase;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.util.Key;
+import com.intellij.psi.FileViewProvider;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.jetbrains.commandInterface.gnuCommandLine.CommandLineLanguage;
+import com.jetbrains.commandInterface.command.Command;
+import com.jetbrains.commandInterface.gnuCommandLine.ValidationResult;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+import java.util.List;
+
+
+/**
+ * Gnu command line file (topmost element).
+ *
+ * @author Ilya.Kazakevich
+ */
+public final class CommandLineFile extends PsiFileBase {
+ private static final Key> COMMANDS = Key.create("COMMANDS");
+
+ public CommandLineFile(final FileViewProvider provider) {
+ super(provider, CommandLineLanguage.INSTANCE);
+ }
+
+ @NotNull
+ @Override
+ public FileType getFileType() {
+
+ return getViewProvider().getVirtualFile().getFileType();
+ }
+
+ /**
+ * @return list of commands, available for this file
+ * @see #setCommands(List)
+ */
+ @Nullable
+ public List getCommands() {
+ return getCopyableUserData(COMMANDS);
+ }
+
+
+ /**
+ * @param commands list of commands, available for this file. Better to provide one, if you know
+ */
+ public void setCommands(@NotNull final List commands) {
+ putCopyableUserData(COMMANDS, commands);
+ }
+
+
+ /**
+ * Tries to find real command used in this file.
+ * You need to first inject list of commands {@link #setCommands(List)}.
+ *
+ * @return Command if found and available, or null if command can't be parsed or bad command.
+ */
+ @Nullable
+ public Command findRealCommand() {
+ final String command = getCommand();
+ final List realCommands = getCommands();
+ if (realCommands == null) {
+ return null;
+ }
+
+ for (final Command realCommand : realCommands) {
+ if (realCommand.getName().equals(command)) {
+ return realCommand;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Tries to validate file.
+ *
+ * @return file validation info or null if file is junk or list of commands is unknown (see {@link #setCommands(List)})
+ */
+ @Nullable
+ public ValidationResult getValidationResult() {
+ return ValidationResultImpl.create(this);
+ }
+
+ /**
+ * @return command (text) typed by user. I.e "my_command" in "my_command --foo --bar"
+ */
+ @Nullable
+ public String getCommand() {
+ final CommandLineCommand command = PsiTreeUtil.getChildOfType(this, CommandLineCommand.class);
+ if (command != null) {
+ return command.getText();
+ }
+ return null;
+ }
+
+ /**
+ * @return all arguments from file
+ */
+ @NotNull
+ public Collection getArguments() {
+ return PsiTreeUtil.findChildrenOfType(this, CommandLineArgument.class);
+ }
+
+ /**
+ * @return all options from file
+ */
+ @NotNull
+ public Collection getOptions() {
+ return PsiTreeUtil.findChildrenOfType(this, CommandLineOption.class);
+ }
+}
diff --git a/python/src/com/jetbrains/commandInterface/gnuCommandLine/psi/ValidationResultImpl.java b/python/src/com/jetbrains/commandInterface/gnuCommandLine/psi/ValidationResultImpl.java
new file mode 100644
index 000000000000..902bd74fa9ae
--- /dev/null
+++ b/python/src/com/jetbrains/commandInterface/gnuCommandLine/psi/ValidationResultImpl.java
@@ -0,0 +1,215 @@
+/*
+ * 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.gnuCommandLine.psi;
+
+import com.intellij.openapi.util.Pair;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiWhiteSpace;
+import com.intellij.util.containers.hash.HashMap;
+import com.jetbrains.commandInterface.gnuCommandLine.ValidationResult;
+import com.jetbrains.commandInterface.command.Argument;
+import com.jetbrains.commandInterface.command.Command;
+import com.jetbrains.commandInterface.command.Option;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Validation result provider and holder implemented as visitor.
+ * @author Ilya.Kazakevich
+ */
+final class ValidationResultImpl extends CommandLineVisitor implements ValidationResult {
+ /**
+ * List of options with names
+ */
+ @NotNull
+ private final HashMap myOptions = new HashMap();
+ /**
+ * We always need command to validate args
+ */
+ @NotNull
+ private final Command myCommand;
+ /**
+ * Number of next positional argument. I.e. will be 3 for "my_arg arg_1 arg_2"
+ */
+ private int myCurrentPositionArgument;
+ /**
+ * If next arg is supposed to be option arg, then option and number of expected args stored here.
+ * Null stored otherwise.
+ */
+ @Nullable
+ private Pair
myCurrentOptionAndArgsLeft;
+ /**
+ * List of elements whose values are known to be bad
+ */
+ @NotNull
+ private final Collection myBadValues = new ArrayList();
+ /**
+ * List of elements which is known to be excess
+ */
+ @NotNull
+ private final Collection myExcessArguments = new ArrayList();
+ /**
+ * Possible values for argument
+ */
+ @NotNull
+ private final Map> myPossibleValues = new HashMap>();
+ /**
+ * List of arguments known to be option arguments
+ */
+ @NotNull
+ private final Collection myOptionArguments = new ArrayList();
+
+ private ValidationResultImpl(@NotNull final Command command) {
+ for (final Option option : command.getOptions()) {
+ for (final String optionName : option.getAllNames()) {
+ myOptions.put(optionName, option);
+ }
+ }
+ myCommand = command;
+ }
+
+ @Override
+ public boolean isBadValue(@NotNull final PsiElement element) {
+ return myBadValues.contains(element);
+ }
+
+ @Override
+ public boolean isExcessArgument(@NotNull final CommandLineArgument argument) {
+ return myExcessArguments.contains(argument);
+ }
+
+ @Override
+ @NotNull
+ public Collection
getUnusedOptions() {
+ return myOptions.values();
+ }
+
+
+ @Override
+ public boolean isOptionArgument(@NotNull final CommandLineArgument argument) {
+ return myOptionArguments.contains(argument);
+ }
+
+ @Override
+ @Nullable
+ public Collection getPossibleArgumentValues(@NotNull final CommandLineArgument argument) {
+ return myPossibleValues.get(argument);
+ }
+
+ /**
+ * Creates validation result by file
+ * @param file file to validate
+ * @return validation result or null if file has no command or command is unknown
+ */
+ @Nullable
+ static ValidationResult create(final CommandLineFile file) {
+ final Command command = file.findRealCommand();
+ if (command == null) {
+ return null;
+ }
+ final ValidationResultImpl validationLayout = new ValidationResultImpl(command);
+ file.acceptChildren(validationLayout);
+ return validationLayout;
+ }
+
+ @Override
+ public void visitArgument(@NotNull final CommandLineArgument o) {
+ super.visitArgument(o);
+ if (myCurrentOptionAndArgsLeft != null) {
+ processOptionArgument(o);
+ return;
+ }
+
+ // Process as positional
+ processPositionalArgument(o);
+ }
+
+ private void processPositionalArgument(@NotNull final CommandLineArgument o) {
+ final Pair argumentPair = myCommand.getArgumentsInfo().getArgument(myCurrentPositionArgument++);
+ if (argumentPair == null) {
+ myExcessArguments.add(o);
+ }
+ else {
+ processArgument(o, argumentPair.second);
+ }
+ }
+
+ private void processOptionArgument(@NotNull final CommandLineArgument o) {
+ assert myCurrentOptionAndArgsLeft != null: "Method can't be called if no current option exist";
+ if (myCurrentOptionAndArgsLeft.second > 0) {
+ myCurrentOptionAndArgsLeft = Pair.create(myCurrentOptionAndArgsLeft.first, myCurrentOptionAndArgsLeft.second - 1);
+ final Pair argumentAndQuantity = myCurrentOptionAndArgsLeft.first.getArgumentAndQuantity();
+ // TODO: Use class instead of pair to prevent such a stupid checks
+ assert argumentAndQuantity != null: "Option has arguments left but no argument info";
+ final Argument argumentInfo = argumentAndQuantity.getSecond();
+ processArgument(o, argumentInfo);
+
+ myOptionArguments.add(o);
+ }
+ else if (myCurrentOptionAndArgsLeft.second == 0) {
+ myCurrentOptionAndArgsLeft = null;
+ myExcessArguments.add(o);
+ }
+ }
+
+ private void processArgument(@NotNull final CommandLineArgument o, final Argument argumentInfo) {
+ final List availableValues = argumentInfo.getAvailableValues();
+ if (availableValues != null) {
+ myPossibleValues.put(o, availableValues);
+ }
+ if (!argumentInfo.isValid(o.getText())) {
+ myBadValues.add(o);
+ }
+ }
+
+
+ @Override
+ public void visitWhiteSpace(final PsiWhiteSpace space) {
+ super.visitWhiteSpace(space);
+ // -aSHORT_OPT_ARGUMENT, but -a NEW_POSITION_ARGUMENT, so whitespace makes sense
+ if (myCurrentOptionAndArgsLeft != null && myCurrentOptionAndArgsLeft.second == 0) {
+ myCurrentOptionAndArgsLeft = null;
+ }
+ }
+
+ @Override
+ public void visitOption(@NotNull final CommandLineOption o) {
+ super.visitOption(o);
+ if (myOptions.containsKey(o.getOptionName())) {
+ // Remove from list of available options
+ final Option option = myOptions.remove(o.getOptionName());
+ for (final String optionName : option.getAllNames()) {
+ myOptions.remove(optionName);
+ }
+
+ final Pair argumentAndQuantity = option.getArgumentAndQuantity();
+ if (argumentAndQuantity != null) {
+ myCurrentOptionAndArgsLeft = Pair.create(option, argumentAndQuantity.first);
+ }
+ else {
+ myCurrentOptionAndArgsLeft = new Pair
(option, 0);
+ }
+ }
+ else {
+ myBadValues.add(o); //No such option available
+ }
+ }
+}
diff --git a/python/src/com/jetbrains/commandInterface/gnuCommandLine/psi/impl/CommandLinePsiImplUtils.java b/python/src/com/jetbrains/commandInterface/gnuCommandLine/psi/impl/CommandLinePsiImplUtils.java
new file mode 100644
index 000000000000..fe206c750857
--- /dev/null
+++ b/python/src/com/jetbrains/commandInterface/gnuCommandLine/psi/impl/CommandLinePsiImplUtils.java
@@ -0,0 +1,64 @@
+/*
+ * 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.gnuCommandLine.psi.impl;
+
+import com.intellij.psi.PsiElement;
+import com.jetbrains.commandInterface.gnuCommandLine.psi.CommandLineOption;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Class to be used by autogenerated PSI elements to delegate logic
+ *
+ * @author Ilya.Kazakevich
+ */
+final class CommandLinePsiImplUtils {
+
+
+ private CommandLinePsiImplUtils() {
+ }
+
+ /**
+ * Checks if option is long (--long-option vs -s)
+ *
+ * @param o option
+ * @return true if long
+ */
+ static boolean isLong(@NotNull final CommandLineOption o) {
+ return o.getLongOptionNameToken() != null;
+ }
+
+ /**
+ * Returns option name regardless it is long or short.
+ *
+ * @param o option
+ * @return name (if any)
+ */
+ @Nullable
+ @NonNls
+ static String getOptionName(@NotNull final CommandLineOption o) {
+ final PsiElement longNameToken = o.getLongOptionNameToken();
+ if (longNameToken != null) {
+ return longNameToken.getText();
+ }
+ final PsiElement shortOptionNameToken = o.getShortOptionNameToken();
+ if (shortOptionNameToken != null) {
+ return shortOptionNameToken.getText();
+ }
+ return null;
+ }
+}
diff --git a/python/src/com/jetbrains/python/commandInterface/command/package-info.java b/python/src/com/jetbrains/commandInterface/gnuCommandLine/psi/impl/package-info.java
similarity index 64%
rename from python/src/com/jetbrains/python/commandInterface/command/package-info.java
rename to python/src/com/jetbrains/commandInterface/gnuCommandLine/psi/impl/package-info.java
index 2993f12ca968..7b45d7642752 100644
--- a/python/src/com/jetbrains/python/commandInterface/command/package-info.java
+++ b/python/src/com/jetbrains/commandInterface/gnuCommandLine/psi/impl/package-info.java
@@ -15,9 +15,10 @@
*/
/**
- * Command with arguments and options.
- * Each {@link com.jetbrains.python.commandInterface.command.Command} may have one or more positional {@link com.jetbrains.python.commandInterface.command.Argument arguments}
- * and several {@link com.jetbrains.python.commandInterface.command.Option options}.
+ * Gnu command line language PSI implementation.
+ * Do not use this package directly, consider using interfaces from {@link com.jetbrains.commandInterface.gnuCommandLine.psi} instead.
+ * Warning: most files in this package is autogenerated. Do not touch them directly.
+ *
* @author Ilya.Kazakevich
*/
-package com.jetbrains.python.commandInterface.command;
\ No newline at end of file
+package com.jetbrains.commandInterface.gnuCommandLine.psi.impl;
\ No newline at end of file
diff --git a/python/src/com/jetbrains/python/commandLineParser/optParse/package-info.java b/python/src/com/jetbrains/commandInterface/gnuCommandLine/psi/package-info.java
similarity index 68%
rename from python/src/com/jetbrains/python/commandLineParser/optParse/package-info.java
rename to python/src/com/jetbrains/commandInterface/gnuCommandLine/psi/package-info.java
index 1a7a6e1b7b42..488377e0eae0 100644
--- a/python/src/com/jetbrains/python/commandLineParser/optParse/package-info.java
+++ b/python/src/com/jetbrains/commandInterface/gnuCommandLine/psi/package-info.java
@@ -15,8 +15,9 @@
*/
/**
- * {@link com.jetbrains.python.commandLineParser.CommandLineParser} based on OptParse
- * See {@link com.jetbrains.python.commandLineParser.optParse.OptParseCommandLineParser}
+ * Gnu command line public PSI interfaces: Command, option, argument etc.
+ *
+ * Warning: most files in this package is autogenerated. Do not touch them directly.
* @author Ilya.Kazakevich
*/
-package com.jetbrains.python.commandLineParser.optParse;
\ No newline at end of file
+package com.jetbrains.commandInterface.gnuCommandLine.psi;
\ No newline at end of file
diff --git a/python/src/com/jetbrains/commandInterface/package-info.java b/python/src/com/jetbrains/commandInterface/package-info.java
new file mode 100644
index 000000000000..072fcc6b32d0
--- /dev/null
+++ b/python/src/com/jetbrains/commandInterface/package-info.java
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+/**
+ *
Command-line interface
+ *
What is the purpose of this package?
+ *
+ * This package is based on ideas of command-line with command, positional arguments, options and their arguments.
+ * Initial idea is taken from POSIX
+ * and enhanced by GNU.
+ * It also supported by Python in optparse package.
+ * Command-line is something like
+ *
+ * and this package helps you to parse command lines, highlight errors, display a console-like interface and execute commands.
+ *
+ *
What this package consists of?
+ *
+ * This package has 3 subpackages:
+ *
+ *
{@link com.jetbrains.commandInterface.command} contains classes to describe commands, arguments and options.
+ * It is up to you where to obtain list of available commands, but you should implement {@link com.jetbrains.commandInterface.command.Command}
+ * first, and create list of it with arguments and options. See package info for more details
+ *
{@link com.jetbrains.commandInterface.gnuCommandLine} is language based on
+ * GNU command line representation.
+ * It has PSI, so it parses command lines into tree of PsiElements. But this package is not only for parsing:
+ * If you provide list of
+ * {@link com.jetbrains.commandInterface.command.Command commands} to {@link com.jetbrains.commandInterface.gnuCommandLine.psi.CommandLineFile}
+ * (see {@link com.jetbrains.commandInterface.gnuCommandLine.psi.CommandLineFile#setCommands(java.util.List)}), it will inject references
+ * (to provide autocompletion) and activate inspection to validate options and arguments.
+ *
{@link com.jetbrains.commandInterface.console} displays console-like interface at the bottom of the screen to give user
+ * ability to wotk with your command-line.
Create list of {@link com.jetbrains.commandInterface.command.Command commands}
+ *
Provide it to {@link com.jetbrains.commandInterface.console.CommandLineConsole#createConsole(com.intellij.openapi.module.Module, java.lang.String, java.util.List)}
+ *
+ * @author Ilya.Kazakevich
+ */
+package com.jetbrains.commandInterface;
\ No newline at end of file
diff --git a/python/src/com/jetbrains/python/PyBundle.properties b/python/src/com/jetbrains/python/PyBundle.properties
index 9cc1d7bc52d8..bd25c9c31b04 100644
--- a/python/src/com/jetbrains/python/PyBundle.properties
+++ b/python/src/com/jetbrains/python/PyBundle.properties
@@ -864,16 +864,9 @@ remote.interpreter.configure.temp.files.path.label=PyCharm helpers path:
custom.type.mimic.name=Dynamic class based on {0}
-# Values for command argument value validation
-commandLine.validation.badCommand=Unknown command
-commandLine.validation.argMissing=Required argument value is missing
-commandLine.validation.optArgMissing=Option argument value is missing
-commandLine.validation.argBadValue=Argument can't have this value
-commandLine.validation.excessArg=Excess argument value
-commandLine.validation.badOption=Bad option or option already set
-commandLine.validation.noArgAllowed=No argument allowed for this option
-# And for labels
-commandLine.subText.key.complete=Use {0} to complete selected variant
-commandLine.subText.key.suggestions=Use {0} to view available values
-commandLine.subText.key.executeUnknown=Click {0} to execute
-commandLine.subText.key.executeCommand=Click {0} to execute "{1}"
+# CommandLine
+commandLine.inspection.name=Command-line inspection
+commandLine.inspection.badCommand=Bad or unknown command. make sure this command really exists.
+commandLine.inspection.badOption=Bad or unknown option. make sure this option really exists.
+commandLine.inspection.badArgument=Argument can't have this value. use autocompletion to check list of possible values.
+commandLine.inspection.excessArgument=Excess argument or argument is not possible here
diff --git a/python/src/com/jetbrains/python/WordWithPosition.java b/python/src/com/jetbrains/python/WordWithPosition.java
deleted file mode 100644
index 0c8043b53a87..000000000000
--- a/python/src/com/jetbrains/python/WordWithPosition.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * 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.python;
-
-import com.intellij.util.Range;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-/**
- * Word with range position. To be used to mark some part of text or split it.
- *
- * @author Ilya.Kazakevich
- */
-public final class WordWithPosition extends Range {
- @NotNull
- private final String myWord;
-
- /**
- * Creates word with beam (it has start, but it is infinite)
- *
- * @param word word
- * @param from start
- */
- public WordWithPosition(@NotNull final String word, final int from) {
- this(word, from, Integer.MAX_VALUE);
- }
-
- /**
- * @param word text
- * @param from from where
- * @param to to where
- */
- public WordWithPosition(@NotNull final String word, final int from, final int to) {
- super(from, to);
- myWord = word;
- }
-
- /**
- * Creates instance with certain text and range (start/end)
- * @param word text
- * @param range range
- */
- public WordWithPosition(@NotNull final String word, @NotNull final Range range) {
- this(word, range.getFrom(), range.getTo());
- }
-
- @NotNull
- public String getText() {
- return myWord;
- }
-
- /**
- * Returns texts only from collection of instances of this class
- *
- * @param words collection of instances of this class
- * @return collection of strings (text)
- */
- @NotNull
- public static List fetchText(@NotNull final Collection words) {
- final List result = new ArrayList(words.size());
- for (final WordWithPosition word : words) {
- result.add(word.myWord);
- }
- return result;
- }
-
- /**
- * Creates new instance with all fields copied but text
- *
- * @param newText new test to add
- * @return new instance
- */
- @NotNull
- public WordWithPosition copyWithDifferentText(@NotNull final String newText) {
- return new WordWithPosition(newText, getFrom(), getTo());
- }
-
- @Override
- public String toString() {
- return "WordWithPosition{" +
- "myWord='" + myWord + '\'' +
- ", myFrom=" + getFrom() +
- ", myTo=" + getTo() +
- '}';
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- WordWithPosition position = (WordWithPosition)o;
-
- if (!getFrom().equals(position.getFrom())) return false;
- if (!getTo().equals(position.getTo())) return false;
- if (!myWord.equals(position.myWord)) return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = myWord.hashCode();
- result = 31 * result + getFrom();
- result = 31 * result + getTo();
- return result;
- }
-
-
- /**
- * Tool that splits text into parts using one or more whitespace as delimiter.
- * Each part contains text and boundaries (from and to)
- *
- * @param text text to split
- * @return parse result
- */
- @NotNull
- public static List splitText(@NotNull final String text) {
- // TODO: Rewrite using regex or scanner?
- int position = 0;
- int wordStart = -1;
- final List parts = new ArrayList();
- for (final char c : text.toCharArray()) {
- if (Character.isWhitespace(c) && wordStart != -1) {
- // Close word
- parts.add(new WordWithPosition(text.substring(wordStart, position), wordStart, position));
- wordStart = -1;
- }
- else if (!Character.isWhitespace(c) && wordStart == -1) {
- // Start word
- wordStart = position;
- }
-
- position++;
- }
- if (wordStart != -1) {
- // Adding last word
- parts.add(new WordWithPosition(text.substring(wordStart), wordStart, position));
- }
- return parts;
- }
-}
diff --git a/python/src/com/jetbrains/python/commandInterface/CommandInterfacePresenter.java b/python/src/com/jetbrains/python/commandInterface/CommandInterfacePresenter.java
deleted file mode 100644
index 1eeecac550e5..000000000000
--- a/python/src/com/jetbrains/python/commandInterface/CommandInterfacePresenter.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2000-2014 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.python.commandInterface;
-
-import com.jetbrains.python.vp.Presenter;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * Presenter for command-line interface to be paired with view.
- *
- * @author Ilya.Kazakevich
- */
-public interface CommandInterfacePresenter extends Presenter {
- /**
- * Called by view when user types new text or text changed by some other reason
- *
- */
- void textChanged();
-
- /**
- * Called by view when user requests for completion (like tab)
- *
- * @param valueFromSuggestionList value selected from suggestion list (if any selected)
- */
- void completionRequested(@Nullable String valueFromSuggestionList);
-
- /**
- * Called by view when user asks for suggestions (like CTRL+Space)
- */
- void suggestionRequested();
-
- /**
- * Called by view when user wants to execute command (like enter)
- *
- */
- void executionRequested();
-}
diff --git a/python/src/com/jetbrains/python/commandInterface/CommandInterfacePresenterAdapter.java b/python/src/com/jetbrains/python/commandInterface/CommandInterfacePresenterAdapter.java
deleted file mode 100644
index 8983e38f1c10..000000000000
--- a/python/src/com/jetbrains/python/commandInterface/CommandInterfacePresenterAdapter.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2000-2014 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.python.commandInterface;
-
-import org.jetbrains.annotations.NotNull;
-
-/**
- * Adapter that holds view.
- * @author Ilya.Kazakevich
- */
-
-public abstract class CommandInterfacePresenterAdapter implements CommandInterfacePresenter {
- @NotNull
- protected final CommandInterfaceView myView;
-
- protected CommandInterfacePresenterAdapter(@NotNull final CommandInterfaceView view) {
- myView = view;
- }
-
- @Override
- public void launch() {
- myView.show();
- }
-
-}
diff --git a/python/src/com/jetbrains/python/commandInterface/CommandInterfaceView.java b/python/src/com/jetbrains/python/commandInterface/CommandInterfaceView.java
deleted file mode 100644
index 317d4caeed49..000000000000
--- a/python/src/com/jetbrains/python/commandInterface/CommandInterfaceView.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright 2000-2014 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.python.commandInterface;
-
-import com.intellij.util.Range;
-import com.jetbrains.python.WordWithPosition;
-import com.jetbrains.python.suggestionList.SuggestionsBuilder;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.Collection;
-import java.util.List;
-
-/**
- * View for command-line interface to be paired with view.
- *
- * @author Ilya.Kazakevich
- */
-public interface CommandInterfaceView {
-
- /**
- * Special place in command line that represents "after the last character" place.
- * To be used in methods like {@link #setInfoAndErrors(java.util.Collection, java.util.Collection)} to mark it.
- */
- @NotNull
- Range AFTER_LAST_CHARACTER_RANGE = new Range(Integer.MAX_VALUE, Integer.MAX_VALUE);
-
- /**
- * Launches view
- */
- void show();
-
- /**
- * Suggests user some elements (for completion reason)
- *
- * @param suggestions what to suggest (see {@link com.jetbrains.python.suggestionList.SuggestionsBuilder})
- * @param absolute display list in its main position, or directly near the caret
- * @param toSelect word to select in list (if any)
- */
- void displaySuggestions(@NotNull SuggestionsBuilder suggestions, boolean absolute, @Nullable String toSelect);
-
-
- /**
- * Each time caret meets certain place, view should check whether some subtext has to be displayed.
- * There are 2 types of subtext to be displayed:
- *
- *
Suggestion Text: View says something like "click FOO to see list of suggestions". Only presenter knows exact places where
- * suggestions are available, so it should provide them
- *
Default text: In all other cases view displays default text (if available).
- *
- *
- * Presenter provides view list of special places
- *
- * @param defaultSubText default text
- * @param suggestionAvailablePlaces list of places where suggestions are available in format [from, to].
- */
- void configureSubTexts(@Nullable String defaultSubText,
- @NotNull List> suggestionAvailablePlaces);
-
- /**
- * Hide suggestion list
- */
- void removeSuggestions();
-
-
- /**
- * @return text, entered by user
- */
- @NotNull
- String getText();
-
-
- /**
- * When caret meets certain place, view may display some info and some errors.
- * Errors, how ever, may always be emphasized (with something like red line).
- * This function configures view with pack of ranges and texts to display.
- * Special place {@link #AFTER_LAST_CHARACTER_RANGE} may also be used.
- * Each place is described as start-end position (in chars) where it should be enabled.
- * Each call removes previously enabled information.
- *
- * @param errors places to be marked as errors with error text.
- * @param infoBalloons places to display info balloon
- * @see #AFTER_LAST_CHARACTER_RANGE
- */
- void setInfoAndErrors(@NotNull final Collection infoBalloons, @NotNull final Collection errors);
-
-
- /**
- * Inserts text after caret moving next chars to the right
- *
- * @param text text to insert
- */
- void insertTextAfterCaret(@NotNull String text);
-
- /**
- * Replaces current text with another one.
- *
- * @param from from
- * @param to to
- * @param newText text to replace
- */
- void replaceText(final int from, final int to, @NotNull String newText);
-
- /**
- * @return position of caret (in chars)
- */
- int getCaretPosition();
-}
diff --git a/python/src/com/jetbrains/python/commandInterface/command/Argument.java b/python/src/com/jetbrains/python/commandInterface/command/Argument.java
deleted file mode 100644
index 4e33c3b585e9..000000000000
--- a/python/src/com/jetbrains/python/commandInterface/command/Argument.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright 2000-2014 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.python.commandInterface.command;
-
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-// TODO: Support regex validation as well
-
-/**
- * Command positional, not named argument (not option!).
- * This class represents command argument, not its value.
- *
- *
- * @author Ilya.Kazakevich
- */
-public final class Argument {
- /**
- * Argument help user-readable text
- */
- @NotNull
- private final String myHelpText;
- /**
- * List of values argument may have. Null if any value is possible.
- */
- @Nullable
- private final List myAvailableValues;
-
-
- /**
- * @param helpText Argument help user-readable text
- */
- public Argument(@NotNull final String helpText) {
- this(helpText, 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) {
- myHelpText = helpText;
- myAvailableValues = (availableValues == null ? null : new ArrayList(availableValues));
- }
-
- /**
- * @return Argument help user-readable text
- */
- @NotNull
- public String getHelpText() {
- return myHelpText;
- }
-
- /**
- * @return List of values argument may have. Null if any value is possible.
- */
- @Nullable
- public List getAvailableValues() {
- return (myAvailableValues == null ? null : Collections.unmodifiableList(myAvailableValues));
- }
-}
diff --git a/python/src/com/jetbrains/python/commandInterface/command/OptionArgumentInfo.java b/python/src/com/jetbrains/python/commandInterface/command/OptionArgumentInfo.java
deleted file mode 100644
index 33382333a18d..000000000000
--- a/python/src/com/jetbrains/python/commandInterface/command/OptionArgumentInfo.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.python.commandInterface.command;
-
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.List;
-
-/**
- * Information about option argument
- *
- * @author Ilya.Kazakevich
- */
-public interface OptionArgumentInfo {
- /**
- * Validates argument value
- *
- * @param value value to validate
- * @return true if valid
- */
- boolean isValid(@NotNull String value);
-
- /**
- * @return list of available values (if argument is based on list of choices), or null if any value is accepted (but should be validated)
- */
- @Nullable
- List getAvailableValues();
-}
diff --git a/python/src/com/jetbrains/python/commandInterface/command/OptionChoiceBasedArgumentInfo.java b/python/src/com/jetbrains/python/commandInterface/command/OptionChoiceBasedArgumentInfo.java
deleted file mode 100644
index 7c037980f1aa..000000000000
--- a/python/src/com/jetbrains/python/commandInterface/command/OptionChoiceBasedArgumentInfo.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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.python.commandInterface.command;
-
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * For options, whose argument is based on list of choices
- * @author Ilya.Kazakevich
- */
-public final class OptionChoiceBasedArgumentInfo implements OptionArgumentInfo {
- @NotNull
- private final List myChoices = new ArrayList();
-
- /**
- * @param choices available choices
- */
- public OptionChoiceBasedArgumentInfo(@NotNull final Collection choices) {
- myChoices.addAll(choices);
- }
-
- @Override
- public boolean isValid(@NotNull final String value) {
- return myChoices.contains(value);
- }
-
- @Nullable
- @Override
- public List getAvailableValues() {
- return Collections.unmodifiableList(myChoices);
- }
-}
diff --git a/python/src/com/jetbrains/python/commandInterface/command/OptionTypedArgumentInfo.java b/python/src/com/jetbrains/python/commandInterface/command/OptionTypedArgumentInfo.java
deleted file mode 100644
index 42cadf0c5c81..000000000000
--- a/python/src/com/jetbrains/python/commandInterface/command/OptionTypedArgumentInfo.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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.python.commandInterface.command;
-
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.List;
-
-/**
- * For options, whose argument is based on certain type.
- *
- * @author Ilya.Kazakevich
- * @see OptionArgumentType
- */
-public final class OptionTypedArgumentInfo implements OptionArgumentInfo {
- @NotNull
- private final OptionArgumentType myType;
-
- /**
- * @param type type argument(s) of this option may have
- */
- public OptionTypedArgumentInfo(@NotNull final OptionArgumentType type) {
- myType = type;
- }
-
- @Override
- public boolean isValid(@NotNull final String value) {
- // We only check integer for now
- if (myType == OptionArgumentType.INTEGER) {
- try {
- // We just getCommandLineInfo it to get exception
- //noinspection ResultOfMethodCallIgnored
- Integer.parseInt(value);
- }
- catch (final NumberFormatException ignored) {
- return false;
- }
- }
- return true;
- }
-
- @Nullable
- @Override
- public List getAvailableValues() {
- return null;
- }
-}
diff --git a/python/src/com/jetbrains/python/commandInterface/commandBasedRangeDriver/CommandBasedRangeInfoDriver.java b/python/src/com/jetbrains/python/commandInterface/commandBasedRangeDriver/CommandBasedRangeInfoDriver.java
deleted file mode 100644
index a35fd4b8f621..000000000000
--- a/python/src/com/jetbrains/python/commandInterface/commandBasedRangeDriver/CommandBasedRangeInfoDriver.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * 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.python.commandInterface.commandBasedRangeDriver;
-
-import com.intellij.openapi.module.Module;
-import com.intellij.openapi.util.Pair;
-import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.util.Range;
-import com.jetbrains.python.PyBundle;
-import com.jetbrains.python.commandInterface.command.Argument;
-import com.jetbrains.python.commandInterface.command.Command;
-import com.jetbrains.python.commandInterface.command.Option;
-import com.jetbrains.python.commandInterface.command.OptionArgumentInfo;
-import com.jetbrains.python.commandInterface.rangeBasedPresenter.Executor;
-import com.jetbrains.python.commandInterface.rangeBasedPresenter.RangeInfo;
-import com.jetbrains.python.commandInterface.rangeBasedPresenter.RangeInfoDriver;
-import com.jetbrains.python.commandInterface.rangeBasedPresenter.SuggestionInfo;
-import com.jetbrains.python.commandLineParser.CommandLine;
-import com.jetbrains.python.commandLineParser.CommandLineParser;
-import com.jetbrains.python.commandLineParser.CommandLinePart;
-import com.jetbrains.python.commandLineParser.MalformedCommandLineException;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.*;
-
-/**
- * Driver that returns pack of range infos for certain command line
- *
- * @author Ilya.Kazakevich
- */
-public final class CommandBasedRangeInfoDriver implements RangeInfoDriver {
- @NotNull
- private final Map myCommands = new TreeMap(); // To sort commands by name
- @NotNull
- private final Module myModule;
- @NotNull
- private final CommandLineParser myCommandLineParser;
-
- /**
- *
- * @param module module (to be used in execution)
- * @param commandLineParser parser to parse command lines
- * @param commands available commands
- */
- public CommandBasedRangeInfoDriver(
- @NotNull final Module module,
- @NotNull final CommandLineParser commandLineParser,
- @NotNull final Collection extends Command> commands) {
- for (final Command command : commands) {
- myCommands.put(command.getName(), command);
- }
- myModule = module;
- myCommandLineParser = commandLineParser;
- }
-
- @NotNull
- @Override
- public Pair> getCommandLineInfo(@NotNull final String commandLineText) {
- // TODO: Copty/paste with exceptiojn
- if (StringUtil.isEmpty(commandLineText)) {
- final RangeInfo info = new RangeInfo(null, "", new SuggestionInfo(
- true, true, myCommands.keySet()
- ), RangeInfo.TERMINATION_RANGE, false
- );
- return new Pair>(null, Collections.singletonList(info));
- }
- final CommandLine commandLine;
- try {
- commandLine = myCommandLineParser.parse(commandLineText);
- }
- catch (final MalformedCommandLineException ignored) {
- return new Pair>(null, Collections.singletonList(
- new RangeInfo(null, PyBundle.message("commandLine.validation.badCommand"), new SuggestionInfo(
- false, true, myCommands.keySet()
- ), new Range(0, commandLineText.length()), false)
- ));
- }
-
- final Command command = getExistingCommand(commandLine);
- final List commandLineParts = commandLine.getParts();
- if (command == null) {
- // Bad command inserted
- return createBadCommandInfo(commandLine);
- }
-
- final UnusedOptionsCollector unusedOptionsCollector = UnusedOptionsCollector.create(command, commandLineParts);
- final RangeInfoCollector rangeInfoCollector = RangeInfoCollector.create(command, commandLineParts, unusedOptionsCollector);
-
-
-
- final SuggestionInfo commandSuggestions = new SuggestionInfo(false, true, myCommands.keySet());
- // Add command as first range info
- final List rangeInfos =
- new ArrayList(Collections.singletonList(new RangeInfo(null, null, commandSuggestions, commandLine.getCommand(), false)));
- // Then add collected infos
- rangeInfos.addAll(rangeInfoCollector.getRangeInfos());
-
-
- /////// What about "after the caret" ?
- final Pair unsatisfiedArgument = rangeInfoCollector.getUnsatisfiedPositionalArgument();
- final OptionArgumentInfo unsatisfiedOptionArgument = rangeInfoCollector.getUnsatisfiedOptionArgument();
-
-
- // TODO: Move to collector after test
- if (unsatisfiedOptionArgument != null) {
- final List availableValues = unsatisfiedOptionArgument.getAvailableValues();
- final SuggestionInfo suggestionInfo;
- if (availableValues != null) {
-
- suggestionInfo =
- new SuggestionInfo(false, false, availableValues);
- }
- else {
- suggestionInfo = null;
- }
- rangeInfos
- .add(new RangeInfo(null, PyBundle.message("commandLine.validation.optArgMissing"), suggestionInfo, RangeInfo.TERMINATION_RANGE,
- false));
- }
- else if (unsatisfiedArgument != null) {
- final boolean required = unsatisfiedArgument.first;
- final Argument argument = unsatisfiedArgument.second;
- // Only add error if required
- final String error = required ? PyBundle.message("commandLine.validation.argMissing") : null;
- final List availableValues = unusedOptionsCollector.addUnusedOptions(argument.getAvailableValues());
- final RangeInfo lastArgInfo =
- new RangeInfo(argument.getHelpText(), error,
- (availableValues != null ? new SuggestionInfo(false, false, availableValues) : null), RangeInfo.TERMINATION_RANGE,
- false);
- rangeInfos.add(lastArgInfo);
- }
- else {
- // Looks like all arguments are satisfied. Adding empty chunk to prevent completion etc.
- // This is a hack, but with out of it last range info will always be used, even 200 chars after last place
- rangeInfos.add(new RangeInfo(null, null, rangeInfoCollector.getCurrentSuggestions(false, null), RangeInfo.TERMINATION_RANGE, false));
- }
-
- assert rangeInfos.size() >= commandLineParts.size() : "Contract broken: not enough chunks";
- return Pair.>create(new CommandExecutor(command, myModule, commandLine.getPartsAsText()), rangeInfos);
- }
-
- @Nullable
- private Command getExistingCommand(@NotNull final CommandLine commandLine) {
- return myCommands.get(commandLine.getCommand().getText());
- }
-
-
- /**
- * Creates range info info signaling command is bad or junk
- *
- *
- * @param commandLine command line passed by user
- * @return info to return
- */
- @NotNull
- private Pair> createBadCommandInfo(final CommandLine commandLine) {
- final List result = new ArrayList();
- // We know that first chunk command line, but we can't say anything about outher chunks except they are bad.
- // How ever, we must say something
- result
- .add(new RangeInfo(null, PyBundle.message("commandLine.validation.badCommand"), new SuggestionInfo(true, true, myCommands.keySet()),
- commandLine.getCommand(), false));
- // Command is unknown, all other parts are junk
- for (final CommandLinePart part : commandLine.getParts()) {
- result.add(new RangeInfo(null, "", false, part.getWord()));
- }
-
-
- return Pair.create(null, result);
- }
-
-
- /**
- * Finds option by its name
- * @param command current command
- * @param optionName option name
- * @return option or null if no option found
- */
- @Nullable
- static Option findOptionByName(@NotNull final Command command, @NotNull final String optionName) {
- for (final Option option : command.getOptions()) {
- for (final String name : option.getAllNames()) {
- if (name.equals(optionName)) {
- return option;
- }
- }
- }
- return null;
- }
-}
diff --git a/python/src/com/jetbrains/python/commandInterface/commandBasedRangeDriver/CommandExecutor.java b/python/src/com/jetbrains/python/commandInterface/commandBasedRangeDriver/CommandExecutor.java
deleted file mode 100644
index 992f00c1fc45..000000000000
--- a/python/src/com/jetbrains/python/commandInterface/commandBasedRangeDriver/CommandExecutor.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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.python.commandInterface.commandBasedRangeDriver;
-
-import com.intellij.openapi.module.Module;
-import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.util.ArrayUtil;
-import com.jetbrains.python.commandInterface.command.Command;
-import com.jetbrains.python.commandInterface.rangeBasedPresenter.Executor;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.Arrays;
-
-/**
- * Executes commands according to {@link Executor} contract
- *
- * @author Ilya.Kazakevich
- */
-final class CommandExecutor implements Executor {
- @NotNull
- private final Command myCommand;
- @NotNull
- private final Module myModule;
- @NotNull
- private final String[] myArguments;
-
- /**
- * @param command command to execute
- * @param module module to execute against
- * @param argumentsLine all command arguments as testline
- */
- CommandExecutor(@NotNull final Command command, @NotNull final Module module, @NotNull final String argumentsLine) {
- myCommand = command;
- myModule = module;
- myArguments = (StringUtil.isEmpty(argumentsLine) ? ArrayUtil.EMPTY_STRING_ARRAY : argumentsLine.split(" "));
- }
-
- @Nullable
- @Override
- public String getExecutionDescription() {
- return myCommand.getHelp();
- }
-
- @Override
- public void execute() {
- myCommand.execute(myModule, Arrays.asList(myArguments));
- }
-}
diff --git a/python/src/com/jetbrains/python/commandInterface/commandBasedRangeDriver/RangeInfoCollector.java b/python/src/com/jetbrains/python/commandInterface/commandBasedRangeDriver/RangeInfoCollector.java
deleted file mode 100644
index cf2f92edf34e..000000000000
--- a/python/src/com/jetbrains/python/commandInterface/commandBasedRangeDriver/RangeInfoCollector.java
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * 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.python.commandInterface.commandBasedRangeDriver;
-
-import com.google.common.collect.Sets;
-import com.intellij.openapi.util.Pair;
-import com.intellij.util.containers.HashSet;
-import com.jetbrains.python.PyBundle;
-import com.jetbrains.python.WordWithPosition;
-import com.jetbrains.python.commandInterface.command.Argument;
-import com.jetbrains.python.commandInterface.command.Command;
-import com.jetbrains.python.commandInterface.command.Option;
-import com.jetbrains.python.commandInterface.command.OptionArgumentInfo;
-import com.jetbrains.python.commandInterface.rangeBasedPresenter.RangeInfo;
-import com.jetbrains.python.commandInterface.rangeBasedPresenter.SuggestionInfo;
-import com.jetbrains.python.commandLineParser.CommandLineArgument;
-import com.jetbrains.python.commandLineParser.CommandLineOption;
-import com.jetbrains.python.commandLineParser.CommandLinePart;
-import com.jetbrains.python.commandLineParser.CommandLinePartVisitor;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.*;
-
-/**
- * Visitor that collections ranges info by visiting options and arguments
- *
- * @author Ilya.Kazakevich
- */
-final class RangeInfoCollector implements CommandLinePartVisitor {
- /**
- * Options already met in command line. It has nothing to do with {@link UnusedOptionsCollector}!
- */
- @NotNull
- private final Set myUsedOptions = new HashSet();
- @NotNull
- private final List myRangeInfos = new ArrayList();
- @NotNull
- private final Command myCommand;
-
- private int myNumOfProcessedPositionalArguments = 0;
- private boolean mySkipNextArgument;
- private Pair myExpectedOptionArgument;
- @NotNull
- private final UnusedOptionsCollector myUnusedOptionsCollector;
-
- /**
- * @param command command
- * @param unusedOptionsCollector instance of unused options collector
- */
- private RangeInfoCollector(@NotNull final Command command,
- @NotNull final UnusedOptionsCollector unusedOptionsCollector) {
- myCommand = command;
- myUnusedOptionsCollector = unusedOptionsCollector;
- }
-
- @NotNull
- static RangeInfoCollector create(@NotNull final Command command,
- @NotNull final Iterable commandLineParts,
- @NotNull final UnusedOptionsCollector unusedOptionsCollector) {
- final RangeInfoCollector infoCollector = new RangeInfoCollector(command, unusedOptionsCollector);
- for (final CommandLinePart part : commandLineParts) {
- part.accept(infoCollector);
- }
- return infoCollector;
- }
-
- @Override
- public void visitOption(@NotNull final CommandLineOption option) {
- if (processOptionArgument(option.getWord())) {
- return;
- }
-
-
- final Option commandOption = CommandBasedRangeInfoDriver.findOptionByName(myCommand, option.getOptionName());
- final WordWithPosition attachedArgument = option.getAttachedArgument();
- if (commandOption == null) {
- // There is no such option
- // To Mark attached arg so we skip it in {@link #visitArgument}
- if (attachedArgument != null) {
- mySkipNextArgument = true;
- }
- // No such option
- myRangeInfos.add(new RangeInfo(null, PyBundle.message("commandLine.validation.badOption"), getCurrentSuggestions(false, null),
- option.getWord(), false));
- return;
- }
-
-
- final Pair argumentAndQuantity = commandOption.getArgumentAndQuantity();
-
-
- // If option already used, then mark it
- final String optionAlreadyUsed = Sets.intersection(Sets.newHashSet(commandOption.getAllNames()), myUsedOptions).isEmpty()
- ? null
- : PyBundle.message("commandLine.validation.badOption");
- myRangeInfos
- .add(new RangeInfo(commandOption.getHelp(), optionAlreadyUsed, getCurrentSuggestions(false, null), option.getWord(),
- argumentAndQuantity != null));
-
- // remove from existing options
- myUsedOptions.addAll(commandOption.getAllNames());
-
-
- if (argumentAndQuantity == null) {
- if (attachedArgument != null) {
- myRangeInfos.add(new RangeInfo(null, PyBundle.message("commandLine.validation.noArgAllowed"), false, attachedArgument));
- mySkipNextArgument = true;
- }
- }
- else {
- // Some option args required
- myExpectedOptionArgument = argumentAndQuantity;
- }
- }
-
- /**
- * Process option argument (not to be confused with positional!)
- *
- * @param currentPart part with argument.
- * @return false if there should not be any option argument so this method did nothing. True if there should be and it is processed.
- */
- private boolean processOptionArgument(@NotNull final WordWithPosition currentPart) {
- if (myExpectedOptionArgument == null) {
- return false;
- }
- final OptionArgumentInfo argumentInfo = myExpectedOptionArgument.second;
- int argsLeft = myExpectedOptionArgument.first;
-
- final boolean valid = argumentInfo.isValid(currentPart.getText());
- final List availableValues = argumentInfo.getAvailableValues();
- final SuggestionInfo suggestions;
- if (availableValues != null) {
- suggestions = new SuggestionInfo(false, false, availableValues);
- }
- else {
- suggestions = null;
- }
-
- myRangeInfos.add(new RangeInfo(null, (valid ? null : PyBundle.message("commandLine.validation.argBadValue")),
- suggestions, currentPart, false));
-
-
- if (--argsLeft == 0) {
- myExpectedOptionArgument = null;
- }
- else {
- myExpectedOptionArgument = Pair.create(argsLeft, argumentInfo);
- }
- return true;
- }
-
-
- /**
- * Returns suggestions available for current position.
- *
- * @param showAutomatically make suggestions displayed automatically
- * @param argumentPair argument to use. If null, current argument according to internal counter would be used.
- * @return suggestiom info or null if no suggestion available
- */
- @Nullable
- SuggestionInfo getCurrentSuggestions(final boolean showAutomatically, @Nullable Pair argumentPair) {
- if (argumentPair == null) {
- argumentPair = myCommand.getArgumentsInfo().getArgument(myNumOfProcessedPositionalArguments);
- }
-
- final List suggestions = argumentPair != null ? myUnusedOptionsCollector.addUnusedOptions(
- argumentPair.second.getAvailableValues()) : myUnusedOptionsCollector.addUnusedOptions(
- null);
- if (suggestions == null) {
- return null;
- }
- return new SuggestionInfo(showAutomatically, false, suggestions);
- }
-
- @Override
- public void visitArgument(@NotNull final CommandLineArgument argument) {
- if (mySkipNextArgument) {
- // Skip argument, clear flag and do nothing
- mySkipNextArgument = false;
- return;
- }
-
- if (processOptionArgument(argument.getWord())) {
- return;
- }
-
- final Pair argumentPair = myCommand.getArgumentsInfo().getArgument(myNumOfProcessedPositionalArguments++);
- if (argumentPair == null) {
- //Exceed!
- myRangeInfos.add(new RangeInfo(null, PyBundle.message("commandLine.validation.excessArg"), false, argument.getWord()));
- return;
- }
- final Argument commandArgument = argumentPair.second;
-
- final List argumentAvailableValues = commandArgument.getAvailableValues();
- final String argumentValue = argument.getWord().getText();
- String errorMessage = null;
- if (argumentAvailableValues != null && !argumentAvailableValues.contains(argumentValue)) {
- // Bad value
- errorMessage = PyBundle.message("commandLine.validation.argBadValue");
- }
- // Argument seems to be ok. We suggest values automatically only if value is bad
- myRangeInfos.add(new RangeInfo(commandArgument.getHelpText(), errorMessage,
- getCurrentSuggestions(errorMessage != null, argumentPair),
- argument.getWord(), false));
- }
-
- /**
- * @return calculates range infos for all command line parts (not the command itself!)
- */
- @NotNull
- Collection getRangeInfos() {
- return Collections.unmodifiableList(myRangeInfos);
- }
-
-
- /**
- * @return Unsatisfied (currently expected) positional argument ([required, arg]) or null if no arg expected
- */
- @Nullable
- Pair getUnsatisfiedPositionalArgument() {
- return myCommand.getArgumentsInfo().getArgument(myNumOfProcessedPositionalArguments);
- }
-
- /**
- * @return Unsatisfied (currently expected) option argument or null if no option argument expected
- */
- public OptionArgumentInfo getUnsatisfiedOptionArgument() {
- if (myExpectedOptionArgument != null) {
- return myExpectedOptionArgument.second;
- }
- else {
- return null;
- }
- }
-}
diff --git a/python/src/com/jetbrains/python/commandInterface/commandBasedRangeDriver/UnusedOptionsCollector.java b/python/src/com/jetbrains/python/commandInterface/commandBasedRangeDriver/UnusedOptionsCollector.java
deleted file mode 100644
index a72030ac696f..000000000000
--- a/python/src/com/jetbrains/python/commandInterface/commandBasedRangeDriver/UnusedOptionsCollector.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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.python.commandInterface.commandBasedRangeDriver;
-
-import com.intellij.util.containers.HashSet;
-import com.jetbrains.python.commandInterface.command.Command;
-import com.jetbrains.python.commandInterface.command.Option;
-import com.jetbrains.python.commandLineParser.CommandLineArgument;
-import com.jetbrains.python.commandLineParser.CommandLineOption;
-import com.jetbrains.python.commandLineParser.CommandLinePart;
-import com.jetbrains.python.commandLineParser.CommandLinePartVisitor;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Collections all used and unused options to report unused options then.
- * It may be used to add unused options to suggestion list {@link #addUnusedOptions(Collection)}
- *
- * @author Ilya.Kazakevich
- */
-final class UnusedOptionsCollector implements CommandLinePartVisitor {
- @NotNull
- private final Set myUnusedOptions = new HashSet();
- @NotNull
- private final Command myCommand;
-
- /**
- * @param command command to be used
- * @param commandLineParts command line parts
- * @return instance
- */
- static UnusedOptionsCollector create(@NotNull final Command command, @NotNull final Iterable commandLineParts) {
- final UnusedOptionsCollector collector = new UnusedOptionsCollector(command);
- for (final CommandLinePart part : commandLineParts) {
- part.accept(collector);
- }
- return collector;
- }
-
- private UnusedOptionsCollector(@NotNull final Command command) {
- for (final Option option : command.getOptions()) {
- myUnusedOptions.addAll(option.getAllNames());
- }
- myCommand = command;
- }
-
- @Override
- public void visitOption(@NotNull final CommandLineOption option) {
- final Option commandOption = CommandBasedRangeInfoDriver.findOptionByName(myCommand, option.getOptionName());
- if (commandOption != null) {
- myUnusedOptions.removeAll(commandOption.getAllNames());
- }
- }
-
- /**
- * Merges list of unused options and other values provided as argument.
- *
- * @param mainValues values to merge options with. May be null.
- * @return null of no options and no values provided or merged list of values and options. See method usages for more info
- */
- @Nullable
- List addUnusedOptions(@Nullable final Collection mainValues) {
- if (mainValues == null && myUnusedOptions.isEmpty()) {
- return null;
- }
- final List result = new ArrayList(myUnusedOptions);
-
- if (mainValues != null) {
- result.addAll(mainValues);
- }
- return (result.isEmpty() ? null : result);
- }
-
-
- @Override
- public void visitArgument(@NotNull final CommandLineArgument argument) {
-
- }
-}
diff --git a/python/src/com/jetbrains/python/commandInterface/commandBasedRangeDriver/package-info.java b/python/src/com/jetbrains/python/commandInterface/commandBasedRangeDriver/package-info.java
deleted file mode 100644
index 278f48371b70..000000000000
--- a/python/src/com/jetbrains/python/commandInterface/commandBasedRangeDriver/package-info.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.
- */
-
-/**
- * {@link com.jetbrains.python.commandInterface.rangeBasedPresenter.RangeInfoDriver} implementation based on idea of
- * {@link com.jetbrains.python.commandInterface.command command, option and argument}.
- *
- * See {@link com.jetbrains.python.commandInterface.commandBasedRangeDriver.CommandBasedRangeInfoDriver} as entry point.
- * It parses command line using {@link com.jetbrains.python.commandLineParser.CommandLineParser} and finds matching command and arguments
- * provided by user
- *
- * @see com.jetbrains.python.commandInterface.command
- * @see com.jetbrains.python.commandInterface.command.Command
- * @author Ilya.Kazakevich
- */
-package com.jetbrains.python.commandInterface.commandBasedRangeDriver;
\ No newline at end of file
diff --git a/python/src/com/jetbrains/python/commandInterface/package-info.java b/python/src/com/jetbrains/python/commandInterface/package-info.java
deleted file mode 100644
index d96540555e52..000000000000
--- a/python/src/com/jetbrains/python/commandInterface/package-info.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2000-2014 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.
- */
-
-/**
- * View/Presenter pair that implements so-called "command line interface".
- * It has several abilities, including (but not limited):
- *
- *
Suggestion box
- *
Error emphasising
- *
Popups
- *
AutoCompletion
- *
- *
- * System consists of {@link com.jetbrains.python.commandInterface.CommandInterfacePresenter}
- * and appropriate {@link com.jetbrains.python.commandInterface.CommandInterfaceView}.
- * See {@link com.jetbrains.python.vp} for more info.
- *
- *
- *
- * There is also swing-based view implementation in {@link com.jetbrains.python.commandInterface.swingView}
- * and presenter implementation based on idea of commands with arguments. See {@link com.jetbrains.python.commandInterface.rangeBasedPresenter}
- *
- *
- *
- * Presenter and View talk to each other only in term of text and chars. Presenter knows nothing about pixels and should never
- * assume view have certain pixel size.
- *
- *
- *
- *
- * @author Ilya.Kazakevich
- */
-package com.jetbrains.python.commandInterface;
\ No newline at end of file
diff --git a/python/src/com/jetbrains/python/commandInterface/rangeBasedPresenter/RangeBasedPresenter.java b/python/src/com/jetbrains/python/commandInterface/rangeBasedPresenter/RangeBasedPresenter.java
deleted file mode 100644
index 4ab64a444abe..000000000000
--- a/python/src/com/jetbrains/python/commandInterface/rangeBasedPresenter/RangeBasedPresenter.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * 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.python.commandInterface.rangeBasedPresenter;
-
-import com.intellij.openapi.util.Pair;
-import com.intellij.util.Range;
-import com.jetbrains.python.WordWithPosition;
-import com.jetbrains.python.commandInterface.CommandInterfacePresenterAdapter;
-import com.jetbrains.python.commandInterface.CommandInterfaceView;
-import com.jetbrains.python.suggestionList.SuggestionsBuilder;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.*;
-
-
-/**
- * Presenter that uses {@link RangeInfoDriver} to obtain {@link RangeInfo info}.
- * Such info tells presenter whether this text has info, error, suggestions and so on.
- * If caret situated far from text, then next neariest range should be found (see {@link #findNearestRangeInfo()}.
- *
- * @author Ilya.Kazakevich
- * @see RangeInfo
- */
-public final class RangeBasedPresenter extends CommandInterfacePresenterAdapter {
- @NotNull
- private final RangeInfoDriver myRangeInfoDriver;
- @Nullable
- private Executor myExecutor;
- private final SortedSet myRangeInfos = new TreeSet();
-
- public RangeBasedPresenter(@NotNull final CommandInterfaceView view,
- @NotNull final RangeInfoDriver rangeInfoDriver) {
- super(view);
- myRangeInfoDriver = rangeInfoDriver;
- }
-
- @Override
- public void launch() {
- super.launch();
- reparseText(true);
- }
-
- @Override
- public void textChanged() {
- reparseText(false);
- }
-
- private void reparseText(final boolean skipSuggestions) {
-
-
- final Pair> rangeInfoStructure = myRangeInfoDriver.getCommandLineInfo(myView.getText());
- myExecutor = rangeInfoStructure.first;
- final List rangeInfos = rangeInfoStructure.second;
-
- assert !rangeInfos.isEmpty() : "At least one chunk info should exist";
- myRangeInfos.clear();
- myRangeInfos.addAll(rangeInfos);
-
-
- // configure Errors And Balloons
-
- final Collection infoBalloons = new ArrayList();
- final Collection errorBalloons = new ArrayList();
-
-
- for (final RangeInfo rangeInfo : rangeInfos) {
- final String error = rangeInfo.getError();
- if (error != null) {
- errorBalloons.add(new WordWithPosition(error, rangeInfo));
- }
- final String info = rangeInfo.getInfoBalloon();
- if (info != null) {
- infoBalloons.add(new WordWithPosition(info, rangeInfo));
- }
- }
-
- myView.setInfoAndErrors(infoBalloons, errorBalloons);
-
-
- if (!skipSuggestions) {
- configureSuggestion(false);
- }
-
- // Configure subtexts
- final List> placesWhereSuggestionAvailable = new ArrayList>();
- for (final RangeInfo rangeInfo : rangeInfos) {
- // If some place has suggestions, then add it
- if (rangeInfo.getSuggestions() != null) {
- placesWhereSuggestionAvailable.add(rangeInfo);
- }
- }
- final String statusText = (myExecutor != null ? myExecutor.getExecutionDescription() : null);
- myView.configureSubTexts(statusText, placesWhereSuggestionAvailable);
- }
-
- @Override
- public void suggestionRequested() {
- configureSuggestion(true); // Show or hide
- }
-
-
- /**
- * Displays suggestions if needed.
- *
- * @param requestedExplicitly is suggesions where requested by user explicitly or not
- */
- private void configureSuggestion(final boolean requestedExplicitly) {
- myView.removeSuggestions();
- final RangeInfo rangeInfo = findNearestRangeInfo();
- final String text = getTextByRange(rangeInfo);
-
- final SuggestionInfo suggestionInfo = rangeInfo.getSuggestions();
- if (suggestionInfo == null || (!suggestionInfo.isShowSuggestionsAutomatically() && !requestedExplicitly)) {
- return;
- }
- final List suggestions = new ArrayList(suggestionInfo.getSuggestions());
- if (text != null && !requestedExplicitly) {
- filterLeaveOnlyMatching(suggestions, text);
- }
- // TODO: Place to add history
- if (!suggestions.isEmpty()) {
- // No need to display empty suggestions
- myView
- .displaySuggestions(new SuggestionsBuilder(suggestions), suggestionInfo.isShowAbsolute(), text);
- }
- }
-
-
- /**
- * Filters collection of suggestions leaving only those starts with certain text.
- *
- * @param suggestions list to filter
- * @param textToMatch leave only parts that start with this param
- */
- private static void filterLeaveOnlyMatching(@NotNull final Iterable suggestions, @NotNull final String textToMatch) {
- // TODO: use guava instead?
- final Iterator iterator = suggestions.iterator();
- while (iterator.hasNext()) {
- if (!iterator.next().startsWith(textToMatch)) {
- iterator.remove();
- }
- }
- }
-
- /**
- * Searches for the nearest range to use.
- *
- * @return nearest range info
- */
- @NotNull
- private RangeInfo findNearestRangeInfo() {
- final int caretPosition = myView.getCaretPosition();
-
- for (final RangeInfo range : myRangeInfos) {
- if (range.isWithin(caretPosition)) {
- return range;
- }
- if (range.getFrom() > caretPosition) {
- return range; // Ranges are sorted, so we are on the next range. Take it, if caret is not within range
- }
- }
-
- return myRangeInfos.last();
- }
-
-
- @Override
- public void completionRequested(@Nullable final String valueFromSuggestionList) {
- final RangeInfo rangeInfo = findNearestRangeInfo();
- final String text = getTextByRange(rangeInfo);
-
- if (valueFromSuggestionList != null) {
- // Just insert it
- if (text != null) { // If caret is on the text itself
- // TODO: Replace next range, if it has no space before it(--a=12 should be replaced wth arg)
- myView.replaceText(rangeInfo.getFrom(), rangeInfo.getTo(), valueFromSuggestionList);
- }
- else {
- myView.insertTextAfterCaret(valueFromSuggestionList);
- }
- return;
- }
-
- //User did not provide text no insert, do our best to find one
-
- final SuggestionInfo suggestionInfo = rangeInfo.getSuggestions();
- if (suggestionInfo == null) {
- return; // No suggestion available for this chunk
- }
- final List suggestions = new ArrayList(suggestionInfo.getSuggestions());
- if (text != null) {
- filterLeaveOnlyMatching(suggestions, text);
- }
- if (suggestions.size() == 1) {
- // Exclusive!
- if (text != null) {
- // TODO: Replace next range, if it has no space before it(--a=12 should be replaced wth arg)
- myView.replaceText(rangeInfo.getFrom(), rangeInfo.getTo(), suggestions.get(0));
- }
- else {
- myView.insertTextAfterCaret(suggestions.get(0));
- }
- }
- }
-
- /**
- * Searches for text under the range
- * @param rangeInfo range
- * @return text or null if range does not contain any text
- */
- @Nullable
- private String getTextByRange(@NotNull final RangeInfo rangeInfo) {
-
- if (rangeInfo.isTerminationRange()) {
- return null;
- }
- else {
- final String viewText = myView.getText();
- return viewText.substring(rangeInfo.getFrom(), rangeInfo.getTo());
- }
- }
-
- @Override
- public void executionRequested() {
- if (myExecutor == null) {
- // TODO: Display error somehow
- }
- else {
- myExecutor.execute();
- }
- }
-}
diff --git a/python/src/com/jetbrains/python/commandInterface/rangeBasedPresenter/RangeInfo.java b/python/src/com/jetbrains/python/commandInterface/rangeBasedPresenter/RangeInfo.java
deleted file mode 100644
index a695eea7db25..000000000000
--- a/python/src/com/jetbrains/python/commandInterface/rangeBasedPresenter/RangeInfo.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * 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.python.commandInterface.rangeBasedPresenter;
-
-import com.intellij.util.Range;
-import com.jetbrains.python.commandInterface.CommandInterfaceView;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * Information about certain place in text, provided by driver.
- *
- * @author Ilya.Kazakevich
- */
-public final class RangeInfo extends Range implements Comparable {
-
-
- /**
- * Special "terminator": the last range which is after all other ranges.
- */
- public static final Range TERMINATION_RANGE = CommandInterfaceView.AFTER_LAST_CHARACTER_RANGE;
-
- @Nullable
- private final String myInfoBalloon;
- @Nullable
- private final String myError;
- @Nullable
- private final SuggestionInfo mySuggestions;
- private final boolean myExclusiveBorders;
-
-
- /**
- * @param infoBalloon info to bind to this range
- * @param error error to bind to this range
- * @param exclusiveBorders true if range has exclusive borders and right border is not part of it. I.e. 3 is part of 1-3 range with out
- * of exclusive borders, but not part of exclusive range
- * @param range from and to
- */
- public RangeInfo(@Nullable final String infoBalloon,
- @Nullable final String error,
- final boolean exclusiveBorders,
- @NotNull final Range range) {
- this(infoBalloon, error, null, range, exclusiveBorders);
- }
-
-
- /**
- * @param infoBalloon Info balloon to display when caret meets this place (null if display nothing)
- * @param error Error balloon to display when caret meets this place and underline text as error (null if no error)
- * @param suggestions list of suggestions available in this place (if any)
- */
- public RangeInfo(@Nullable final String infoBalloon,
- @Nullable final String error,
- @Nullable final SuggestionInfo suggestions,
- @NotNull final Range range,
- final boolean exclusiveBorders) {
- super(range.getFrom(), range.getTo());
- myInfoBalloon = infoBalloon;
- myError = error;
- mySuggestions = suggestions;
- myExclusiveBorders = exclusiveBorders;
- }
-
-
- /**
- * @return Info balloon to display when caret meets this place (null if display nothing)
- */
- @Nullable
- public String getInfoBalloon() {
- return myInfoBalloon;
- }
-
- /**
- * @return Error balloon to display when caret meets this place and underline text as error (null if no error)
- */
- @Nullable
- public String getError() {
- return myError;
- }
-
- /**
- * @return list of suggestions available in this place (if any)
- */
- @Nullable
- public SuggestionInfo getSuggestions() {
- return mySuggestions;
- }
-
- @Override
- public int compareTo(RangeInfo o) {
- return getFrom().compareTo(o.getFrom());
- }
-
- @Override
- public boolean isWithin(final Integer object) {
- if (!super.isWithin(object)) {
- return false;
- }
- if (myExclusiveBorders) {
- return object < getTo();
- }
- return true;
- }
-
- public boolean isTerminationRange() {
- // TODO: copy/paste with view
- return TERMINATION_RANGE.getFrom().equals(getFrom()) && TERMINATION_RANGE.getTo().equals(getTo());
- }
-}
diff --git a/python/src/com/jetbrains/python/commandInterface/rangeBasedPresenter/RangeInfoDriver.java b/python/src/com/jetbrains/python/commandInterface/rangeBasedPresenter/RangeInfoDriver.java
deleted file mode 100644
index fb5887290654..000000000000
--- a/python/src/com/jetbrains/python/commandInterface/rangeBasedPresenter/RangeInfoDriver.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.python.commandInterface.rangeBasedPresenter;
-
-import com.intellij.openapi.util.Pair;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.List;
-
-/**
- * Driver that knows how to getCommandLineInfo pack of chunks into chunk info.
- *
- * @author Ilya.Kazakevich
- */
-public interface RangeInfoDriver {
- /**
- * Parses command line text into executor and pack of range infos.
- * There always should be at least one range info and the last one is almost always {@link RangeInfo#TERMINATION_RANGE).
- *
- * @param commandLineText command line text to parse.
- * @return pair or executor (the one that knows how to execute command line) and pack of range infos.
- * Warning! :Executor could be null if command can't be executed
- */
- @NotNull
- Pair> getCommandLineInfo(@NotNull String commandLineText);
-}
diff --git a/python/src/com/jetbrains/python/commandInterface/rangeBasedPresenter/SuggestionInfo.java b/python/src/com/jetbrains/python/commandInterface/rangeBasedPresenter/SuggestionInfo.java
deleted file mode 100644
index e7af84e52ea0..000000000000
--- a/python/src/com/jetbrains/python/commandInterface/rangeBasedPresenter/SuggestionInfo.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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.python.commandInterface.rangeBasedPresenter;
-
-import org.jetbrains.annotations.NotNull;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Information about suggestions
- *
- * @author Ilya.Kazakevich
- */
-public final class SuggestionInfo {
- @NotNull
- private final List mySuggestions = new ArrayList();
- private final boolean myShowSuggestionsAutomatically;
- private final boolean myShowAbsolute;
-
- /**
- * @param showSuggestionsAutomatically true it suggestions should be displayed even if user did not ask for that
- * @param showAbsolute show suggestions at the absolute position (not relative to caret).
- * @param suggestions List of suggestions to display
- */
- public SuggestionInfo(final boolean showSuggestionsAutomatically,
- final boolean showAbsolute,
- @NotNull final Collection suggestions) {
- myShowSuggestionsAutomatically = showSuggestionsAutomatically;
- myShowAbsolute = showAbsolute;
- mySuggestions.addAll(suggestions);
- }
-
- /**
- * @return List of suggestions to display
- */
- @NotNull
- public List getSuggestions() {
- return Collections.unmodifiableList(mySuggestions);
- }
-
- /**
- * @return true it suggestions should be displayed even if user did not ask for that
- */
- public boolean isShowSuggestionsAutomatically() {
- return myShowSuggestionsAutomatically;
- }
-
- /**
- * @return show suggestions at the absolute position (not relative to caret).
- */
- public boolean isShowAbsolute() {
- return myShowAbsolute;
- }
-
- @Override
- public String toString() {
- return "SuggestionInfo{" +
- "mySuggestions=" + mySuggestions +
- ", myShowSuggestionsAutomatically=" + myShowSuggestionsAutomatically +
- ", myShowAbsolute=" + myShowAbsolute +
- '}';
- }
-}
diff --git a/python/src/com/jetbrains/python/commandInterface/rangeBasedPresenter/package-info.java b/python/src/com/jetbrains/python/commandInterface/rangeBasedPresenter/package-info.java
deleted file mode 100644
index 152071b1e34c..000000000000
--- a/python/src/com/jetbrains/python/commandInterface/rangeBasedPresenter/package-info.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.
- */
-
-/**
- * {@link com.jetbrains.python.commandInterface.CommandInterfacePresenter} implementation based on ideas of range info
- * and {@link com.jetbrains.python.commandInterface.rangeBasedPresenter.RangeInfoDriver}.
- * This presenter passes command line to driver, and it returns pack of range information.
- * Each record contains everything presenter needs to know about certain range (i.e. error between 2 and 5 chars).
- * Special type of range {@link com.jetbrains.python.commandInterface.rangeBasedPresenter.RangeInfo#TERMINATION_RANGE} exists, that
- * you may need to check.
- *
- * Presenter uses this information to display chunks correctly using view.
- * To use this package, {@link com.jetbrains.python.commandInterface.rangeBasedPresenter.RangeInfoDriver} should be implemented.
- *
- * See {@link com.jetbrains.python.commandInterface.rangeBasedPresenter.RangeBasedPresenter} as entry point
- *
- * @author Ilya.Kazakevich
- */
-package com.jetbrains.python.commandInterface.rangeBasedPresenter;
\ No newline at end of file
diff --git a/python/src/com/jetbrains/python/commandInterface/swingView/CommandInterfaceViewSwingImpl.form b/python/src/com/jetbrains/python/commandInterface/swingView/CommandInterfaceViewSwingImpl.form
deleted file mode 100644
index 3540a57f5144..000000000000
--- a/python/src/com/jetbrains/python/commandInterface/swingView/CommandInterfaceViewSwingImpl.form
+++ /dev/null
@@ -1,58 +0,0 @@
-
-
diff --git a/python/src/com/jetbrains/python/commandInterface/swingView/CommandInterfaceViewSwingImpl.java b/python/src/com/jetbrains/python/commandInterface/swingView/CommandInterfaceViewSwingImpl.java
deleted file mode 100644
index 955d07ee6580..000000000000
--- a/python/src/com/jetbrains/python/commandInterface/swingView/CommandInterfaceViewSwingImpl.java
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
- * Copyright 2000-2014 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.python.commandInterface.swingView;
-
-import com.google.common.base.Preconditions;
-import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.MessageType;
-import com.intellij.openapi.ui.popup.*;
-import com.intellij.openapi.ui.popup.Balloon.Position;
-import com.intellij.ui.JBColor;
-import com.intellij.ui.awt.RelativePoint;
-import com.intellij.util.Range;
-import com.intellij.util.containers.HashSet;
-import com.jetbrains.python.PyBundle;
-import com.jetbrains.python.WordWithPosition;
-import com.jetbrains.python.commandInterface.CommandInterfacePresenter;
-import com.jetbrains.python.commandInterface.CommandInterfaceView;
-import com.jetbrains.python.suggestionList.SuggestionList;
-import com.jetbrains.python.suggestionList.SuggestionsBuilder;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import javax.swing.*;
-import javax.swing.event.CaretEvent;
-import javax.swing.event.CaretListener;
-import javax.swing.event.DocumentEvent;
-import javax.swing.event.DocumentListener;
-import javax.swing.text.BadLocationException;
-import java.awt.*;
-import java.awt.event.FocusAdapter;
-import java.awt.event.FocusEvent;
-import java.awt.event.KeyAdapter;
-import java.awt.event.KeyEvent;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Command-interface view implementation based on Swing.
- * It uses balloons to display errors and infos, drop-down for suggestions and also underlines errors
- *
- * @author Ilya.Kazakevich
- */
-public class CommandInterfaceViewSwingImpl extends JBPopupAdapter implements CommandInterfaceView, DocumentListener, CaretListener {
- private static final JBColor ERROR_COLOR = JBColor.RED;
-
- /**
- * We need to track balloons, so we have field with callback
- */
- @NotNull
- private final BalloonManager myBalloonManager = new BalloonManager();
- /**
- * Pop-up we displayed in
- */
- @NotNull
- private final JBPopup myMainPopUp;
- private JPanel myPanel;
- /**
- * Upper label
- */
- private JLabel myLabel;
- /**
- * Text field
- */
- private SmartTextField myMainTextField;
- /**
- * Lower (sub) label
- */
- private JLabel mySubLabel;
- /**
- * "Suggestion area". Suggestion status is displayed when caret meets this area
- */
- private final List> myPlacesWhereSuggestionsAvailable = new ArrayList>();
- @NotNull
- private final CommandInterfacePresenter myPresenter;
- /**
- * List to display suggestions
- */
- @NotNull
- private final SuggestionList mySuggestionList;
- /**
- * Displayed when there is no text
- */
- @Nullable
- private final String myPlaceHolderText;
-
- /**
- * Information balloons that should be displayed when caret meets their boundaries.
- */
- @NotNull
- private final List myInfoBalloons = new ArrayList();
- /**
- * Error balloons that should be displayed when caret meets their boundaries.
- * Errors are always underlined, but balloons are displayed only if caret meets error
- */
- private final List myErrorBalloons = new ArrayList();
- /**
- * Default subtext to display when caret is out of {@link #myPlacesWhereSuggestionsAvailable "suggestion" area}
- */
- @Nullable
- private String myDefaultSubText;
-
- /**
- * @param presenter our presenter
- * @param title view title to display
- * @param project project
- * @param placeholderText text for placeholder (to be displayed when there is not text)
- */
- public CommandInterfaceViewSwingImpl(@NotNull final CommandInterfacePresenter presenter,
- @NotNull final String title,
- @NotNull final Project project,
- @Nullable final String placeholderText) {
- myPresenter = presenter;
- myLabel.setText(title);
- myPlaceHolderText = placeholderText;
-
- myMainPopUp = JBPopupFactory.getInstance().createComponentPopupBuilder(myPanel, myMainTextField)
- .setFocusable(true)
- .setRequestFocus(true)
- .createPopup();
- myMainTextField.setRequestFocusEnabled(true);
- myMainTextField.setFocusable(true);
-
-
- final int windowWidth = FileEditorManagerEx.getInstanceEx(project).getComponent().getRootPane().getWidth() - 10; // Little gap
-
- myMainTextField
- .setPreferredWidthInPx(windowWidth);
- mySuggestionList = new SuggestionList(new MySuggestionListListener());
- }
-
-
- @Override
- public void show() {
- myMainTextField.getDocument().addDocumentListener(this);
- myMainTextField.addCaretListener(this);
- myMainPopUp.addListener(this);
- if (myPlaceHolderText != null) {
- myMainTextField.setWaterMarkPlaceHolderText(myPlaceHolderText);
- }
-
-
- myMainTextField.addFocusListener(new FocusAdapter() {
- @Override
- public void focusLost(final FocusEvent e) {
- super.focusLost(e);
- myMainPopUp.cancel();
- }
- });
- myMainTextField.setFocusTraversalKeysEnabled(false);
- myMainTextField.addKeyListener(new MyKeyListener()); // Up/down arrows are not handles with actions
-
- // Register all available actions
- for (final KeyStrokeInfo strokeInfo : KeyStrokeInfo.values()) {
- strokeInfo.register(myPresenter, mySuggestionList, myMainTextField);
- }
- myMainPopUp.showInFocusCenter();
- }
-
-
- @Override
- public void displaySuggestions(@NotNull final SuggestionsBuilder suggestions, final boolean absolute, @Nullable final String toSelect) {
-
- int left = 0;
- // Display text right after caret
- if (!absolute) {
- left = myMainTextField.getTextCaretPositionInPx();
- }
- mySuggestionList.showSuggestions(suggestions, new RelativePoint(myPanel, new Point(left, myPanel.getHeight())), toSelect);
- configureAppropriateStatus();
- }
-
- @Override
- public void onClosed(final LightweightWindowEvent event) {
- super.onClosed(event);
- mySuggestionList.close();
- }
-
-
- @Override
- public void insertUpdate(final DocumentEvent e) {
- processDocumentChange();
- }
-
-
- @Override
- public void removeUpdate(final DocumentEvent e) {
- processDocumentChange();
- }
-
- private void processDocumentChange() {
- myMainTextField.hideUnderline();
- myPresenter.textChanged();
- }
-
- @Override
- public void changedUpdate(final DocumentEvent e) {
-
- }
-
- @Override
- public void removeSuggestions() {
- mySuggestionList.close();
- configureAppropriateStatus();
- }
-
-
- @Override
- public final void caretUpdate(final CaretEvent e) {
-
-
- // When caret moved, we need to check if balloon has to be displayed
- displayBalloonsIfRequired();
- configureAppropriateStatus();
- }
-
- private void configureAppropriateStatus() {
- if (!mySuggestionList.isClosed()) {
- // Tell user she may use TAB to complete
- mySubLabel.setText(PyBundle.message("commandLine.subText.key.complete", KeyStrokeInfo.COMPLETION.getText()));
- return;
- }
-
- // If we are in "suggestion available" place -- tell it
- for (final Range range : myPlacesWhereSuggestionsAvailable) {
- final boolean specialCaseAfterLastChar = isAfterLastCharRange(range) && getCaretPosition() == myMainTextField.getText().length();
- if (range.isWithin(getCaretPosition()) || specialCaseAfterLastChar) {
- mySubLabel.setText(PyBundle.message("commandLine.subText.key.suggestions", KeyStrokeInfo.SUGGESTION.getText()));
- return;
- }
- }
-
- // We may simply tell user she may execute command
- if (myDefaultSubText != null) {
- mySubLabel.setText(PyBundle.message("commandLine.subText.key.executeCommand", KeyStrokeInfo.EXECUTION.getText(), myDefaultSubText));
- }
- else {
- mySubLabel.setText(PyBundle.message("commandLine.subText.key.executeUnknown", KeyStrokeInfo.EXECUTION.getText()));
- }
- }
-
-
- private void displayBalloonsIfRequired() {
- synchronized (myErrorBalloons) {
- if (mySuggestionList.isClosed()) { // No need to display error popups when suggestion list is displayed. It intersects.
- showBalloons(myErrorBalloons, Position.below, MessageType.ERROR);
- }
- }
- synchronized (myInfoBalloons) {
- showBalloons(myInfoBalloons, Position.above, MessageType.INFO);
- }
- }
-
- /**
- * Displays some balloons
- *
- * @param balloons balloons to display
- * @param popUpPosition where ti display them. Only {@link Position#above} and {@link Position#below} are supported!
- * @param messageType may be {@link MessageType#ERROR} or {@link MessageType#INFO} for example
- */
- private void showBalloons(@NotNull final List balloons,
- @NotNull final Position popUpPosition,
- @NotNull final MessageType messageType) {
- Preconditions.checkArgument(popUpPosition == Position.above || popUpPosition == Position.below, "Only above or below is supported");
- for (final WordWithPosition balloon : balloons) {
- if (balloon.getText().isEmpty()) {
- continue; // Can't be displayed if empty
- }
- final int caretPosition = myMainTextField.getCaretPosition();
- if ((caretPosition >= balloon.getFrom() && caretPosition <= balloon.getTo())) {
- final int top = (popUpPosition == Position.above ? 0 : myMainTextField.getHeight() * 2); // Display below a little bit lower
- final RelativePoint point = new RelativePoint(myMainTextField, new Point(myMainTextField.getTextCaretPositionInPx(), top));
- final Balloon balloonToShow =
- JBPopupFactory.getInstance().createBalloonBuilder(new JLabel(balloon.getText())).setFillColor(messageType.getPopupBackground())
- .createBalloon();
- balloonToShow.setAnimationEnabled(false);
- myBalloonManager.registerBalloon(balloonToShow);
- balloonToShow.show(point, popUpPosition);
- }
- }
- }
-
- @Override
- public final void setInfoAndErrors(@NotNull final Collection infoBalloons,
- @NotNull final Collection errors) {
- synchronized (myInfoBalloons) {
- myInfoBalloons.clear();
- myInfoBalloons.addAll(infoBalloons);
- }
- synchronized (myErrorBalloons) {
- myErrorBalloons.clear();
- myErrorBalloons.addAll(errors);
- }
- for (final WordWithPosition error : errors) {
- if (isAfterLastCharRange(error)) {
- // In "special" case we use last char
- myMainTextField.underlineText(ERROR_COLOR, myMainTextField.getText().length(), myMainTextField.getText().length() + 1);
- }
- else {
- myMainTextField.underlineText(ERROR_COLOR, error.getFrom(), error.getTo());
- }
- }
- }
-
- /**
- * Checks if some range is special case {@link #AFTER_LAST_CHARACTER_RANGE}.
- *
- * @param range range to check
- * @return true if special case
- */
- private static boolean isAfterLastCharRange(@NotNull final Range range) {
- return AFTER_LAST_CHARACTER_RANGE.getFrom().equals(range.getFrom()) && AFTER_LAST_CHARACTER_RANGE.getTo().equals(range.getTo());
- }
-
- @Override
- public final void insertTextAfterCaret(@NotNull final String text) {
- try {
- myMainTextField.getDocument().insertString(myMainTextField.getCaretPosition(), text, null);
- }
- catch (final BadLocationException e) {
- // TODO: Display error somehow!
- e.printStackTrace();
- }
- }
-
- @Override
- public final void replaceText(final int from, final int to, @NotNull final String newText) {
- myMainTextField.select(from, to);
- myMainTextField.replaceSelection(newText);
- myBalloonManager.closeAllBalloons();
- myPresenter.textChanged();
- displayBalloonsIfRequired(); // This crunch but we need to recalculate balloons in this case (position is changed!)
- }
-
- @Override
- public final int getCaretPosition() {
- return myMainTextField.getCaretPosition();
- }
-
-
- @Override
- public final void configureSubTexts(@Nullable final String defaultSubText,
- @NotNull final List> suggestionAvailablePlaces) {
- synchronized (myPlacesWhereSuggestionsAvailable) {
- myPlacesWhereSuggestionsAvailable.clear();
- myPlacesWhereSuggestionsAvailable.addAll(suggestionAvailablePlaces);
- myDefaultSubText = defaultSubText;
- }
- configureAppropriateStatus();
- }
-
- /**
- * Reacts on keys, pressed by user
- */
- private class MyKeyListener extends KeyAdapter {
- @Override
- public void keyPressed(final KeyEvent e) {
- super.keyPressed(e);
-
- final int keyCode = e.getKeyCode();
- if (keyCode == KeyEvent.VK_UP) {
- mySuggestionList.moveSelection(true);
- }
- else if (keyCode == KeyEvent.VK_DOWN) {
- mySuggestionList.moveSelection(false);
- }
- }
- }
-
- @NotNull
- @Override
- public String getText() {
- return myMainTextField.getText();
- }
-
-
- /**
- * Listener for suggestion list
- */
- private class MySuggestionListListener extends JBPopupAdapter {
-
- @Override
- public void onClosed(final LightweightWindowEvent event) {
- super.onClosed(event);
- removeSuggestions();
- }
- }
-
- /**
- * Keeps tracks for baloons to close all of them in case of text inserion
- */
- private static final class BalloonManager extends JBPopupAdapter {
- @NotNull
- private final Set myCurrentBaloons = new HashSet();
-
- void registerBalloon(final Balloon balloon) {
- synchronized (myCurrentBaloons) {
- myCurrentBaloons.add(balloon);
- balloon.addListener(this);
- }
- }
-
- @Override
- public void onClosed(final LightweightWindowEvent event) {
- synchronized (myCurrentBaloons) {
- myCurrentBaloons.remove(event.asBalloon());
- }
- super.onClosed(event);
- }
-
- void closeAllBalloons() {
- synchronized (myCurrentBaloons) {
- for (final Balloon balloon : myCurrentBaloons) {
- balloon.dispose();
- }
- }
- }
- }
-}
diff --git a/python/src/com/jetbrains/python/commandInterface/swingView/CompletionKeyStrokeAction.java b/python/src/com/jetbrains/python/commandInterface/swingView/CompletionKeyStrokeAction.java
deleted file mode 100644
index 8ed0c5af06ed..000000000000
--- a/python/src/com/jetbrains/python/commandInterface/swingView/CompletionKeyStrokeAction.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.python.commandInterface.swingView;
-
-import java.awt.event.ActionEvent;
-
-/**
- * "Complete current command or argument" action
- *
- * @author Ilya.Kazakevich
- */
-final class CompletionKeyStrokeAction extends KeyStrokeAction {
- CompletionKeyStrokeAction() {
- super(KeyStrokeInfo.COMPLETION);
- }
-
- @Override
- public void actionPerformed(final ActionEvent e) {
- myPresenter.completionRequested(mySuggestionList.getValue());
- }
-}
diff --git a/python/src/com/jetbrains/python/commandInterface/swingView/KeyStrokeAction.java b/python/src/com/jetbrains/python/commandInterface/swingView/KeyStrokeAction.java
deleted file mode 100644
index a801580a5bf6..000000000000
--- a/python/src/com/jetbrains/python/commandInterface/swingView/KeyStrokeAction.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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.python.commandInterface.swingView;
-
-import com.jetbrains.python.commandInterface.CommandInterfacePresenter;
-import com.jetbrains.python.suggestionList.SuggestionList;
-import org.jetbrains.annotations.NotNull;
-
-import javax.swing.text.TextAction;
-
-/**
- * Action that should be taken for certain {@link javax.swing.KeyStroke} (wrapped in {@link com.jetbrains.python.commandInterface.swingView.KeyStrokeInfo}).
- * You need to call {@link #configure(com.jetbrains.python.commandInterface.CommandInterfacePresenter, com.jetbrains.python.suggestionList.SuggestionList)}
- * to enable one.
- *
- * @author Ilya.Kazakevich
- */
-@SuppressWarnings({"InstanceVariableMayNotBeInitialized", "NonSerializableFieldInSerializableClass"}) // Will never serialize
-abstract class KeyStrokeAction extends TextAction {
- @NotNull
- private final String myName;
- @NotNull
- private final KeyStrokeInfo myStroke;
-
- protected CommandInterfacePresenter myPresenter;
- protected SuggestionList mySuggestionList;
-
- /**
- * @param stroke key stroke to bind this info to
- */
- KeyStrokeAction(@NotNull final KeyStrokeInfo stroke) {
- super(stroke.name());
- myName = stroke.name();
- myStroke = stroke;
- }
-
-
- /**
- * Configures action.
- *
- * @param presenter presenter to be used for call back.
- * @param suggestionList list of suggestions to be used for call back
- * @return name of this action to add to {@link javax.swing.InputMap}
- */
- @NotNull
- final String configure(@NotNull final CommandInterfacePresenter presenter, @NotNull final SuggestionList suggestionList) {
- myPresenter = presenter;
- mySuggestionList = suggestionList;
- return myName;
- }
-
- /**
- * @return stroke bound to this action
- */
- @NotNull
- final KeyStrokeInfo getStroke() {
- return myStroke;
- }
-}
diff --git a/python/src/com/jetbrains/python/commandInterface/swingView/KeyStrokeInfo.java b/python/src/com/jetbrains/python/commandInterface/swingView/KeyStrokeInfo.java
deleted file mode 100644
index dcf8278e6612..000000000000
--- a/python/src/com/jetbrains/python/commandInterface/swingView/KeyStrokeInfo.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * 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.python.commandInterface.swingView;
-
-import com.intellij.openapi.keymap.KeymapUtil;
-import com.jetbrains.python.commandInterface.CommandInterfacePresenter;
-import com.jetbrains.python.suggestionList.SuggestionList;
-import org.jetbrains.annotations.NotNull;
-
-import javax.swing.*;
-import java.awt.event.InputEvent;
-import java.awt.event.KeyEvent;
-
-/**
- * Key strokes to be used with view.
- * Strokes paired with action. You need to register each action via {@link javax.swing.InputMap}
- *
- * @author Ilya.Kazakevich
- */
-enum KeyStrokeInfo {
- /**
- * "Execute command" keystroke
- */
- EXECUTION(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0)),
- /**
- * "Complete current command or argument" keystroke
- */
- COMPLETION(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0)),
- /**
- * "Display suggestions" keystroke.
- */
- SUGGESTION(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, InputEvent.CTRL_MASK)),;
-
- /**
- * List of actions. Each action should be bound to some {@link com.jetbrains.python.commandInterface.swingView.KeyStrokeInfo}
- */
- @NotNull
- private static final KeyStrokeAction[] ACTIONS = {
- new CompletionKeyStrokeAction(),
- new ExecutionKeyStrokeAction(),
- new SuggestionKeyStrokeAction()};
-
- private final KeyStroke myStroke;
-
- KeyStrokeInfo(@NotNull final KeyStroke stroke) {
- myStroke = stroke;
- }
-
- /**
- * Registers action and binds it appropriate stroke. Call if for all instances to make all actions available.
- *
- * @param presenter presenter to be used as call back
- * @param suggestionList suggestion list to be used as call back
- * @param source Component with {@link javax.swing.InputMap} and {@link javax.swing.ActionMap} (swing view itself)
- */
- void register(@NotNull final CommandInterfacePresenter presenter,
- @NotNull final SuggestionList suggestionList,
- @NotNull final JComponent source) {
- final KeyStrokeAction action = getAction();
- final String strokeName = action.configure(presenter, suggestionList);
- source.getInputMap().put(myStroke, strokeName);
- source.getActionMap().put(strokeName, action);
- }
-
- /**
- * @return Human-readable name of this action (to display it to user)
- */
- @NotNull
- String getText() {
- return KeymapUtil.getKeystrokeText(myStroke);
- }
-
-
- /**
- * @return action paired with stroke
- */
- @NotNull
- private KeyStrokeAction getAction() {
- for (final KeyStrokeAction action : ACTIONS) {
- if (action.getStroke() == this) {
- return action;
- }
- }
- throw new IllegalStateException("Failed to find action for " + name());
- }
-}
diff --git a/python/src/com/jetbrains/python/commandInterface/swingView/SmartTextField.java b/python/src/com/jetbrains/python/commandInterface/swingView/SmartTextField.java
deleted file mode 100644
index 2e7ff1a07352..000000000000
--- a/python/src/com/jetbrains/python/commandInterface/swingView/SmartTextField.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright 2000-2014 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.python.commandInterface.swingView;
-
-import com.intellij.openapi.editor.colors.EditorColorsManager;
-import com.intellij.openapi.editor.colors.EditorFontType;
-import com.intellij.util.Range;
-import com.intellij.util.ui.StatusText;
-import org.jetbrains.annotations.NotNull;
-
-import javax.swing.*;
-import java.awt.*;
-import java.util.ArrayList;
-import java.util.Collection;
-
-/**
- * Text field that has width to be changed and accepts error underline
- *
- * @author Ilya.Kazakevich
- */
-@SuppressWarnings({"NonSerializableFieldInSerializableClass", "SerializableHasSerializationMethods"}) // Will never serialize it
-public class SmartTextField extends JTextField {
- /**
- * Placeholder for this textbox
- */
- private StatusText myPlaceHolder;
- /**
- * Error (underline) info to display. Check {@link UnderlineInfo} class for more info
- */
- @NotNull
- private final Collection myUnderlineInfo = new ArrayList();
- private int myPreferredWidth;
-
- public SmartTextField() {
- setFont(EditorColorsManager.getInstance().getGlobalScheme().getFont(EditorFontType.CONSOLE_PLAIN));
- }
-
- @Override
- protected void paintComponent(final Graphics g) {
- super.paintComponent(g);
- if (myPlaceHolder != null) {
- myPlaceHolder.paint(this, g);
- }
- synchronized (myUnderlineInfo) {
- for (final UnderlineInfo underlineInfo : myUnderlineInfo) {
- g.setColor(underlineInfo.myColor);
- // To prevent too long underlines: last char should really be last
- underline(g, underlineInfo.getFrom(), underlineInfo.getTo());
- }
- }
- }
-
- /**
- * Underlines certain place
- *
- * @param g canvas
- * @param from from where (int px)
- * @param to to where (int px)
- */
- private void underline(@NotNull final Graphics g, final int from, final int to) {
- final int verticalPosition = getHeight() - 5;
- g.drawLine(from + getColumnWidth(), verticalPosition, to + getColumnWidth(), verticalPosition);
- }
-
-
- /**
- * @return place (in px) where caret.
- */
- int getTextCaretPositionInPx() {
- return (getCaretPosition() + 1) * getColumnWidth();
- }
-
- void setWaterMarkPlaceHolderText(@NotNull final String watermark) {
- myPlaceHolder = new MyStatusText(this);
- myPlaceHolder.setText(watermark);
- }
-
-
- @Override
- public Dimension getPreferredSize() {
- final Dimension dimension = super.getPreferredSize();
- final int placeHolderTextLength = ((myPlaceHolder != null) ? myPlaceHolder.getText().length() : 0);
- final int columns = Math.max(Math.max(getText().length(), placeHolderTextLength), getColumns());
- final int desiredSize = columns * getColumnWidth();
- return new Dimension(Math.max(Math.max(myPreferredWidth, dimension.width), desiredSize), dimension.height);
- }
-
- /**
- * Display underline
- *
- * @param color color to underline
- * @param from from (in chars)
- * @param to (in chars)
- */
- final void underlineText(@NotNull final Color color, final int from, final int to) {
- final int columnWidth = getColumnWidth();
- synchronized (myUnderlineInfo) {
- myUnderlineInfo.add(new UnderlineInfo(from * columnWidth, to * columnWidth, color));
- }
- }
-
- /**
- * Removes underline
- */
- void hideUnderline() {
- synchronized (myUnderlineInfo) {
- myUnderlineInfo.clear();
- }
- }
-
- /**
- * Sets appropriate width in pixels
- *
- * @param width width in px
- */
- void setPreferredWidthInPx(final int width) {
- myPreferredWidth = width;
- }
-
-
- /**
- * Wrapper to display placeholder
- */
- private class MyStatusText extends StatusText {
- MyStatusText(final JComponent owner) {
- super(owner);
- }
-
- @Override
- protected boolean isStatusVisible() {
- return SmartTextField.this.getText().isEmpty();
- }
- }
-
- /**
- * Information about underline
- *
- * @author Ilya.Kazakevich
- */
- private static final class UnderlineInfo extends Range {
- /**
- * Color to use to underline
- */
- @NotNull
- private final Color myColor;
-
- /**
- * @param from underline from where (in px)
- * @param to underline to where (in px)
- * @param color color to use to underline
- */
- UnderlineInfo(final int from, final int to, @NotNull final Color color) {
- super(from, to);
- myColor = color;
- }
- }
-}
diff --git a/python/src/com/jetbrains/python/commandInterface/swingView/SuggestionKeyStrokeAction.java b/python/src/com/jetbrains/python/commandInterface/swingView/SuggestionKeyStrokeAction.java
deleted file mode 100644
index 088ff8c3fe27..000000000000
--- a/python/src/com/jetbrains/python/commandInterface/swingView/SuggestionKeyStrokeAction.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.python.commandInterface.swingView;
-
-import java.awt.event.ActionEvent;
-
-/**
- * "Suggestion request" action
- *
- * @author Ilya.Kazakevich
- */
-final class SuggestionKeyStrokeAction extends KeyStrokeAction {
- SuggestionKeyStrokeAction() {
- super(KeyStrokeInfo.SUGGESTION);
- }
-
- @Override
- public void actionPerformed(final ActionEvent e) {
- myPresenter.suggestionRequested();
- }
-}
diff --git a/python/src/com/jetbrains/python/commandInterface/swingView/package-info.java b/python/src/com/jetbrains/python/commandInterface/swingView/package-info.java
deleted file mode 100644
index 56a257230d03..000000000000
--- a/python/src/com/jetbrains/python/commandInterface/swingView/package-info.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright 2000-2014 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.
- */
-
-/**
- * Command-line like interface view GUI. See {@link com.jetbrains.python.commandInterface.swingView.CommandInterfaceViewSwingImpl}
- * @author Ilya.Kazakevich
- */
-package com.jetbrains.python.commandInterface.swingView;
\ No newline at end of file
diff --git a/python/src/com/jetbrains/python/commandLineParser/CommandLine.java b/python/src/com/jetbrains/python/commandLineParser/CommandLine.java
deleted file mode 100644
index 201a779554a8..000000000000
--- a/python/src/com/jetbrains/python/commandLineParser/CommandLine.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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.python.commandLineParser;
-
-import com.intellij.openapi.util.text.StringUtil;
-import com.jetbrains.python.WordWithPosition;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Command line getCommandLineInfo result.
- * It consists of command itself and its parts.
- * Each part may be {@link com.jetbrains.python.commandLineParser.CommandLinePartType#ARGUMENT argument} or
- * {@link com.jetbrains.python.commandLineParser.CommandLinePartType#OPTION option} or something else.
- *
- * @author Ilya.Kazakevich
- */
-public final class CommandLine {
- @NotNull
- private final List myParts = new ArrayList();
- @NotNull
- private final WordWithPosition myCommand;
-
- public CommandLine(
- @NotNull final WordWithPosition command,
- @NotNull final Collection parts) {
- myCommand = command;
- myParts.addAll(parts);
- }
-
- /**
- * @return command (i.e. "startapp" in "startapp my_app")
- */
- @NotNull
- public WordWithPosition getCommand() {
- return myCommand;
- }
-
- @NotNull
- public List getParts() {
- return Collections.unmodifiableList(myParts);
- }
-
- /**
- * @return all command parts as text (actually by bindning them back together)
- */
- @NotNull
- public String getPartsAsText() {
- final StringBuilder builder = new StringBuilder();
- int lastPosition = 0;
- for (final CommandLinePart part : getParts()) {
- final WordWithPosition partWord = part.getWord();
- if (lastPosition != partWord.getFrom()) {
- builder.append(' ');
- }
- builder.append(partWord.getText());
- lastPosition = partWord.getTo();
- }
- return StringUtil.trim(builder.toString());
- }
-}
diff --git a/python/src/com/jetbrains/python/commandLineParser/CommandLineOption.java b/python/src/com/jetbrains/python/commandLineParser/CommandLineOption.java
deleted file mode 100644
index 217b4fa44dc0..000000000000
--- a/python/src/com/jetbrains/python/commandLineParser/CommandLineOption.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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.python.commandLineParser;
-
-import com.jetbrains.python.WordWithPosition;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * Option. Each option has name and may also have attached argument like "--long-option=attached_arg" or "-sATTACHED_ARG"
- *
- * @author Ilya.Kazakevich
- */
-public final class CommandLineOption extends CommandLinePart {
-
- @NotNull
- private final String myOptionName;
-
- @Nullable
- private final WordWithPosition myAttachedArgument;
-
- /**
- * @param option option (text and position)
- * @param optionName option name (like "--foo")
- * @param attachedArgument option attached argument (like --foo=ATTACHED_ARG)
- */
- public CommandLineOption(@NotNull final WordWithPosition option,
- @NotNull final String optionName,
- @Nullable final WordWithPosition attachedArgument) {
- super(option);
- myOptionName = optionName;
- myAttachedArgument = attachedArgument;
- }
-
-
- /**
- * @return option name (like "--foo")
- */
- @NotNull
- public String getOptionName() {
- return myOptionName;
- }
-
- /**
- * @return option attached argument (like --foo=ATTACHED_ARG)
- */
- @Nullable
- public WordWithPosition getAttachedArgument() {
- return myAttachedArgument;
- }
-
- @Override
- public void accept(@NotNull final CommandLinePartVisitor visitor) {
- visitor.visitOption(this);
- }
-}
diff --git a/python/src/com/jetbrains/python/commandLineParser/CommandLineParser.java b/python/src/com/jetbrains/python/commandLineParser/CommandLineParser.java
deleted file mode 100644
index b52d785f54c9..000000000000
--- a/python/src/com/jetbrains/python/commandLineParser/CommandLineParser.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.python.commandLineParser;
-
-import org.jetbrains.annotations.NotNull;
-
-/**
- * Engine to {@link CommandLine} structure from text.
- *
- * @author Ilya.Kazakevich
- */
-public interface CommandLineParser {
- /**
- *
- * @param commandLineText command line to parse
- * @return command line information
- * @throws MalformedCommandLineException in case of bad commandline
- */
- @NotNull
- CommandLine parse(@NotNull String commandLineText) throws MalformedCommandLineException;
-}
diff --git a/python/src/com/jetbrains/python/commandLineParser/CommandLinePart.java b/python/src/com/jetbrains/python/commandLineParser/CommandLinePart.java
deleted file mode 100644
index 93af9e0d92ea..000000000000
--- a/python/src/com/jetbrains/python/commandLineParser/CommandLinePart.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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.python.commandLineParser;
-
-import com.jetbrains.python.WordWithPosition;
-import org.jetbrains.annotations.NotNull;
-
-/**
- * Part of command line. Known subclasses are {@link CommandLineOption} and {@link CommandLineArgument}
- *
- * @author Ilya.Kazakevich
- * @see CommandLineArgument
- * @see CommandLineOption
- */
-public abstract class CommandLinePart {
- @NotNull
- private final WordWithPosition myWord;
-
- /**
- * @param word word (and its position) this part represents
- */
- protected CommandLinePart(@NotNull final WordWithPosition word) {
- myWord = word;
- }
-
- /**
- * @return word (and its position) this part represents
- */
- @NotNull
- public final WordWithPosition getWord() {
- return myWord;
- }
-
- /**
- * @param visitor visitor to accept
- */
- public abstract void accept(@NotNull CommandLinePartVisitor visitor);
-}
diff --git a/python/src/com/jetbrains/python/commandLineParser/optParse/OptParseCommandLineParser.java b/python/src/com/jetbrains/python/commandLineParser/optParse/OptParseCommandLineParser.java
deleted file mode 100644
index 4612b87dc9a4..000000000000
--- a/python/src/com/jetbrains/python/commandLineParser/optParse/OptParseCommandLineParser.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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.python.commandLineParser.optParse;
-
-import com.intellij.openapi.util.Pair;
-import com.jetbrains.python.WordWithPosition;
-import com.jetbrains.python.commandLineParser.*;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.Deque;
-import java.util.List;
-
-/**
- *
- * Optparse-based commandline parses.
- * According to optparse manual, commandline should look like:
- *
.
- * You should understand difference between argument, long option, short option, and option argument before using this class.
- * It is documented in optparse manual.
- *
- *
- * This class provides not only args and options (like many other parsers do), but also position in command line
- * which may be useful when you want to mark argument somehow.
- *
- *
- * @author Ilya.Kazakevich
- */
-public final class OptParseCommandLineParser implements CommandLineParser {
- /**
- * Supported option parsers (option types, actually)
- * Short (-o) and long (--option) strategies are used here
- */
-
- private static final OptionParser[] OPTION_PARSERS = {new ShortOptionParser(), new LongOptionParser()};
-
-
- @NotNull
- @Override
- public CommandLine parse(@NotNull final String commandLineText) throws MalformedCommandLineException {
- final Deque parts = new ArrayDeque(WordWithPosition.splitText(commandLineText));
- if (parts.isEmpty()) {
- throw new MalformedCommandLineException("No command provided");
- }
- final WordWithPosition command = parts.pop();
-
- final List optionsAndArguments = new ArrayList();
-
- for (final WordWithPosition part : parts) {
- final Pair optionTextAndName = findOptionTextAndName(part.getText());
- if (optionTextAndName != null) {
- final String optionText = optionTextAndName.first;
- final String optionName = optionTextAndName.second;
- final WordWithPosition option = new WordWithPosition(optionText, part.getFrom(), part.getFrom() + optionText.length());
-
- final WordWithPosition optionArgument;
- if (optionText.length() == part.getText().length()) {
- optionArgument = null;
- }
- else {
- // Looks like we have option argument here.
- final String argumentText = part.getText().substring(optionText.length());
- optionArgument = new WordWithPosition(argumentText, option.getTo(), part.getTo());
- }
- optionsAndArguments.add(new CommandLineOption(option, optionName, optionArgument)); //Option
- if (optionArgument != null) {
- optionsAndArguments.add(new CommandLineArgument(optionArgument)); // And its argument
- }
- }
- else {
- optionsAndArguments.add(new CommandLineArgument(part)); //Not an option. Should be argument
- }
- }
- return new CommandLine(command, optionsAndArguments);
- }
-
-
- /**
- * Parse out option and its value iterating through the parsers
- *
- * @param text text believed to be an option like "--foo=123"
- * @return [option_text, option_name] or null of no such option
- * @see OptionParser#findOptionTextAndName(String)
- */
- @Nullable
- private static Pair findOptionTextAndName(@NotNull final String optionText) {
- for (final OptionParser parser : OPTION_PARSERS) {
- final Pair optionTextAndName = parser.findOptionTextAndName(optionText);
- if (optionTextAndName != null) {
- return optionTextAndName;
- }
- }
- return null;
- }
-}
diff --git a/python/src/com/jetbrains/python/commandLineParser/optParse/OptionParser.java b/python/src/com/jetbrains/python/commandLineParser/optParse/OptionParser.java
deleted file mode 100644
index 246e51fb47f9..000000000000
--- a/python/src/com/jetbrains/python/commandLineParser/optParse/OptionParser.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.python.commandLineParser.optParse;
-
-import com.intellij.openapi.util.Pair;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * Engine that knows how to deal with option of certain style (like long and short)
- *
- * @author Ilya.Kazakevich
- */
-interface OptionParser {
- /**
- * @param optionText text to parse (like --foo=bar)
- * @return null if option can't be parsed. Otherwise pair of [option_text, option_name]. That may match each other in some cases.
- */
- @Nullable
- Pair findOptionTextAndName(@NotNull String optionText);
-}
diff --git a/python/src/com/jetbrains/python/commandLineParser/optParse/OptionParserRegexBased.java b/python/src/com/jetbrains/python/commandLineParser/optParse/OptionParserRegexBased.java
deleted file mode 100644
index 628bf4114550..000000000000
--- a/python/src/com/jetbrains/python/commandLineParser/optParse/OptionParserRegexBased.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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.python.commandLineParser.optParse;
-
-import com.intellij.openapi.util.Pair;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Parses options using regex and template method
- *
- * @author Ilya.Kazakevich
- */
-abstract class OptionParserRegexBased implements OptionParser {
- @NotNull
- private final Pattern myPattern;
-
- /**
- * @param pattern regex. If option matches pattern, ({@link Matcher#find() opened matcher}) would be passed to template method
- * {@link #getOptionTextAndNameFromMatcher(Matcher)}
- */
- protected OptionParserRegexBased(@NotNull final Pattern pattern) {
- myPattern = pattern;
- }
-
- @Nullable
- @Override
- public final Pair findOptionTextAndName(@NotNull final String optionText) {
- final Matcher matcher = myPattern.matcher(optionText);
- if (!matcher.find()) {
- return null;
- }
- return getOptionTextAndNameFromMatcher(matcher);
- }
-
- /**
- * Obtains [option_text, option_name] from matcher
- *
- * @param matcher opened (with find() called) matcher
- * @return pair [option_text, option_name]
- */
- @NotNull
- protected abstract Pair getOptionTextAndNameFromMatcher(@NotNull Matcher matcher);
-}
diff --git a/python/src/com/jetbrains/python/commandLineParser/package-info.java b/python/src/com/jetbrains/python/commandLineParser/package-info.java
deleted file mode 100644
index 23d92d7c45c6..000000000000
--- a/python/src/com/jetbrains/python/commandLineParser/package-info.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.
- */
-
-/**
- * Engine to parse commandline from string to {@link com.jetbrains.python.commandLineParser.CommandLine} structure.
- *
- * Command line consists of command itself, {@link com.jetbrains.python.commandLineParser.CommandLineArgument arguments}
- * and {@link com.jetbrains.python.commandLineParser.CommandLineOption options}.
- * Use need to pass text to {@link com.jetbrains.python.commandLineParser.CommandLineParser parser} and obtain {@link com.jetbrains.python.commandLineParser.CommandLine}.
- *
- * Not like any other parsers, this package supports {@link com.jetbrains.python.WordWithPosition} telling you exactly with part of
- * command line is command or argument. That helps you to underline or emphisize some parts.
- *
- * @author Ilya.Kazakevich
- */
-package com.jetbrains.python.commandLineParser;
\ No newline at end of file
diff --git a/python/testData/commandLine/badCommandLineNoCommand.cmdline b/python/testData/commandLine/badCommandLineNoCommand.cmdline
new file mode 100644
index 000000000000..9a85201b350d
--- /dev/null
+++ b/python/testData/commandLine/badCommandLineNoCommand.cmdline
@@ -0,0 +1 @@
+bad_command positional_argument --available-option=available_argument
\ No newline at end of file
diff --git a/python/testData/commandLine/badCommandLineWithCommand.cmdline b/python/testData/commandLine/badCommandLineWithCommand.cmdline
new file mode 100644
index 000000000000..284932b07a6a
--- /dev/null
+++ b/python/testData/commandLine/badCommandLineWithCommand.cmdline
@@ -0,0 +1 @@
+command bad_positional_value --available-option=bad_argument--bad-optionunexpected_argument --option-no-argument=asd
\ No newline at end of file
diff --git a/python/testData/commandLine/commandLine.cmdline b/python/testData/commandLine/commandLine.cmdline
new file mode 100644
index 000000000000..f7c4b2e577b4
--- /dev/null
+++ b/python/testData/commandLine/commandLine.cmdline
@@ -0,0 +1 @@
+command_name positional_argument_1 positional_argument_2 -sSMALL_OPTION_VALUE -a --long-option --long-option-2=long_option_value --long-option-3 argument_for_long_option
\ No newline at end of file
diff --git a/python/testData/commandLine/commandLine.txt b/python/testData/commandLine/commandLine.txt
new file mode 100644
index 000000000000..78055130d8fa
--- /dev/null
+++ b/python/testData/commandLine/commandLine.txt
@@ -0,0 +1,32 @@
+FILE
+ CommandLineCommandImpl(COMMAND)
+ PsiElement(LITERAL_STARTS_FROM_LETTER)('command_name')
+ PsiWhiteSpace(' ')
+ CommandLineArgumentImpl(ARGUMENT)
+ PsiElement(LITERAL_STARTS_FROM_LETTER)('positional_argument_1')
+ PsiWhiteSpace(' ')
+ CommandLineArgumentImpl(ARGUMENT)
+ PsiElement(LITERAL_STARTS_FROM_LETTER)('positional_argument_2')
+ PsiWhiteSpace(' ')
+ CommandLineOptionImpl(OPTION)
+ PsiElement(SHORT_OPTION_NAME_TOKEN)('-s')
+ CommandLineArgumentImpl(ARGUMENT)
+ PsiElement(LITERAL_STARTS_FROM_LETTER)('SMALL_OPTION_VALUE')
+ PsiWhiteSpace(' ')
+ CommandLineOptionImpl(OPTION)
+ PsiElement(SHORT_OPTION_NAME_TOKEN)('-a')
+ PsiWhiteSpace(' ')
+ CommandLineOptionImpl(OPTION)
+ PsiElement(LONG_OPTION_NAME_TOKEN)('--long-option')
+ PsiWhiteSpace(' ')
+ CommandLineOptionImpl(OPTION)
+ PsiElement(LONG_OPTION_NAME_TOKEN)('--long-option-2')
+ PsiElement(=)('=')
+ CommandLineArgumentImpl(ARGUMENT)
+ PsiElement(LITERAL_STARTS_FROM_LETTER)('long_option_value')
+ PsiWhiteSpace(' ')
+ CommandLineOptionImpl(OPTION)
+ PsiElement(LONG_OPTION_NAME_TOKEN)('--long-option-3')
+ PsiWhiteSpace(' ')
+ CommandLineArgumentImpl(ARGUMENT)
+ PsiElement(LITERAL_STARTS_FROM_LETTER)('argument_for_long_option')
\ No newline at end of file
diff --git a/python/testData/commandLine/goodCommandLine.cmdline b/python/testData/commandLine/goodCommandLine.cmdline
new file mode 100644
index 000000000000..c6b4fd34754d
--- /dev/null
+++ b/python/testData/commandLine/goodCommandLine.cmdline
@@ -0,0 +1 @@
+command positional_argument --available-option=available_argument
\ No newline at end of file
diff --git a/python/testData/commandLine/junk.cmdline b/python/testData/commandLine/junk.cmdline
new file mode 100644
index 000000000000..a5470be3af25
--- /dev/null
+++ b/python/testData/commandLine/junk.cmdline
@@ -0,0 +1 @@
+--can_t_be
\ No newline at end of file
diff --git a/python/testData/commandLine/junk.txt b/python/testData/commandLine/junk.txt
new file mode 100644
index 000000000000..a8129715640c
--- /dev/null
+++ b/python/testData/commandLine/junk.txt
@@ -0,0 +1,3 @@
+FILE
+ PsiErrorElement:LITERAL_STARTS_FROM_LETTER expected, got '--can_t_be'
+ PsiElement(LONG_OPTION_NAME_TOKEN)('--can_t_be')
\ No newline at end of file
diff --git a/python/testData/commandLine/optionNoValueJunk.cmdline b/python/testData/commandLine/optionNoValueJunk.cmdline
new file mode 100644
index 000000000000..5a95d4958e5c
--- /dev/null
+++ b/python/testData/commandLine/optionNoValueJunk.cmdline
@@ -0,0 +1 @@
+command --bad_value=
\ No newline at end of file
diff --git a/python/testData/commandLine/optionNoValueJunk.txt b/python/testData/commandLine/optionNoValueJunk.txt
new file mode 100644
index 000000000000..1d4e5fc0b398
--- /dev/null
+++ b/python/testData/commandLine/optionNoValueJunk.txt
@@ -0,0 +1,9 @@
+FILE
+ CommandLineCommandImpl(COMMAND)
+ PsiElement(LITERAL_STARTS_FROM_LETTER)('command')
+ PsiWhiteSpace(' ')
+ CommandLineOptionImpl(OPTION)
+ PsiElement(LONG_OPTION_NAME_TOKEN)('--bad_value')
+ PsiErrorElement:Space between argument is its value is unexpected
+
+ PsiElement(=)('=')
\ No newline at end of file
diff --git a/python/testSrc/com/jetbrains/commandInterface/gnuCommandLine/CommandLineInspectionTest.java b/python/testSrc/com/jetbrains/commandInterface/gnuCommandLine/CommandLineInspectionTest.java
new file mode 100644
index 000000000000..1d17f701e68b
--- /dev/null
+++ b/python/testSrc/com/jetbrains/commandInterface/gnuCommandLine/CommandLineInspectionTest.java
@@ -0,0 +1,75 @@
+/*
+ * 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.gnuCommandLine;
+
+import com.intellij.psi.PsiFile;
+import com.jetbrains.commandInterface.gnuCommandLine.psi.CommandLineFile;
+import com.jetbrains.python.fixtures.PyTestCase;
+import org.junit.Assert;
+
+
+/**
+ * Tests command line inspection
+ *
+ * @author Ilya.Kazakevich
+ */
+public final class CommandLineInspectionTest extends PyTestCase {
+
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ CommandTestTools.initFileType();
+ }
+
+ /**
+ * Everything should be ok
+ */
+ public void testGoodCommandLine() throws Exception {
+ doTest();
+ }
+
+ /**
+ * No command provided in file
+ */
+ public void testBadCommandLineNoCommand() throws Exception {
+ doTest();
+ }
+
+ /**
+ * Command provided, but args and opts have errors
+ */
+ public void testBadCommandLineWithCommand() throws Exception {
+ doTest();
+ }
+
+ @Override
+ protected String getTestDataPath() {
+ return CommandTestTools.TEST_PATH;
+ }
+
+ /**
+ * Enables inspection on testName.cmdline and checks it.
+ */
+ private void doTest() {
+ final PsiFile file = myFixture.configureByFile(getTestName(true) + '.' + CommandLineFileType.EXTENSION);
+ Assert.assertSame("Bad file type!", CommandLineFile.class, file.getClass());
+ final CommandLineFile commandLineFile = (CommandLineFile)file;
+ commandLineFile.setCommands(CommandTestTools.createCommands());
+ myFixture.enableInspections(CommandLineInspection.class);
+ myFixture.checkHighlighting();
+ }
+}
diff --git a/python/testSrc/com/jetbrains/commandInterface/gnuCommandLine/CommandLineParserTest.java b/python/testSrc/com/jetbrains/commandInterface/gnuCommandLine/CommandLineParserTest.java
new file mode 100644
index 000000000000..cf7424ffb8bc
--- /dev/null
+++ b/python/testSrc/com/jetbrains/commandInterface/gnuCommandLine/CommandLineParserTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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.gnuCommandLine;
+
+
+import com.intellij.testFramework.ParsingTestCase;
+
+import com.jetbrains.python.PythonTestUtil;
+
+
+/**
+ * Tests command line parser
+ *
+ * @author Ilya.Kazakevich
+ */
+public final class CommandLineParserTest extends ParsingTestCase {
+ public CommandLineParserTest() {
+ super("", CommandLineFileType.EXTENSION, true, new CommandLineParserDefinition());
+ }
+
+ @Override
+ protected String getTestDataPath() {
+ return CommandTestTools.TEST_PATH;
+ }
+
+
+ /**
+ * Should be ok
+ */
+ public void testCommandLine() throws Exception {
+ doTest(true);
+ }
+
+ /**
+ * Should have a lot of errors
+ */
+ public void testJunk() throws Exception {
+ doTest(true);
+ }
+
+ /**
+ * Should have error because option ends with "="
+ */
+ public void testOptionNoValueJunk() throws Exception {
+ doTest(true);
+ }
+}
diff --git a/python/testSrc/com/jetbrains/commandInterface/gnuCommandLine/CommandLineSuggestionTest.java b/python/testSrc/com/jetbrains/commandInterface/gnuCommandLine/CommandLineSuggestionTest.java
new file mode 100644
index 000000000000..fa3d40e56c79
--- /dev/null
+++ b/python/testSrc/com/jetbrains/commandInterface/gnuCommandLine/CommandLineSuggestionTest.java
@@ -0,0 +1,70 @@
+/*
+ * 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.gnuCommandLine;
+
+import com.intellij.codeInsight.lookup.LookupElement;
+import com.intellij.util.containers.HashSet;
+import com.jetbrains.commandInterface.gnuCommandLine.psi.CommandLineFile;
+import com.jetbrains.python.fixtures.PyTestCase;
+import org.hamcrest.Matchers;
+import org.jetbrains.annotations.NotNull;
+import org.junit.Assert;
+
+
+import java.util.Set;
+
+
+/**
+ * Tests references provide correct suggestions for commands, options and argument in command line
+ *
+ * @author Ilya.Kazakevich
+ */
+public final class CommandLineSuggestionTest extends PyTestCase {
+ /**
+ * Ensures suggestions are correct
+ */
+ public void testSuggestions() throws Exception {
+ CommandTestTools.initFileType();
+ final CommandLineFile file =
+ (CommandLineFile)myFixture.configureByText(CommandLineFileType.INSTANCE, "command positional_ar --a");
+ file.setCommands(CommandTestTools.createCommands());
+
+ ensureSuggestions("command", "command");
+ ensureSuggestions("positional_ar", "positional_argument", "--option-no-argument", "--available-option");
+ ensureSuggestions("--a", "--option-no-argument", "--available-option");
+ }
+
+ /**
+ * @param initialPositionText place to move cusor to
+ * @param expectedSuggestions expected suggestions
+ */
+ private void ensureSuggestions(@NotNull final String initialPositionText, @NotNull final String... expectedSuggestions) {
+ moveByText(initialPositionText);
+ final Set completions = new HashSet();
+ for (final LookupElement element : myFixture.completeBasic()) {
+ completions.add(element.getLookupString());
+ }
+
+ Assert.assertThat("Bad suggestions", completions,
+ Matchers.containsInAnyOrder(expectedSuggestions));
+ }
+
+
+ @Override
+ protected String getTestDataPath() {
+ return CommandTestTools.TEST_PATH;
+ }
+}
diff --git a/python/testSrc/com/jetbrains/commandInterface/gnuCommandLine/CommandTestTools.java b/python/testSrc/com/jetbrains/commandInterface/gnuCommandLine/CommandTestTools.java
new file mode 100644
index 000000000000..360324e97cc8
--- /dev/null
+++ b/python/testSrc/com/jetbrains/commandInterface/gnuCommandLine/CommandTestTools.java
@@ -0,0 +1,91 @@
+/*
+ * 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.gnuCommandLine;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.fileTypes.FileTypeManager;
+import com.intellij.openapi.util.Pair;
+import com.jetbrains.commandInterface.command.*;
+import com.jetbrains.python.PythonTestUtil;
+import org.easymock.EasyMock;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.TestOnly;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Shared tools to testing command line
+ * @author Ilya.Kazakevich
+ */
+final class CommandTestTools {
+ @NotNull
+ static final String TEST_PATH = PythonTestUtil.getTestDataPath() + "/commandLine/";
+
+ private CommandTestTools() {
+ }
+
+ /**
+ *