diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java index 76f0cd55e279..f790f5a2c53d 100644 --- a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java +++ b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java @@ -41,8 +41,6 @@ import com.intellij.ui.ColoredTreeCellRenderer; import com.intellij.ui.components.JBLabel; import com.intellij.ui.treeStructure.Tree; import com.intellij.util.ArrayUtil; -import com.intellij.util.Function; -import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.FactoryMap; import com.intellij.util.containers.MultiMap; import com.intellij.util.ui.tree.TreeUtil; @@ -110,17 +108,12 @@ public class ProjectTypeStep extends ModuleWizardStep { } }; - List categories = new ArrayList(); - /* - categories.addAll(ContainerUtil.map(ModuleBuilder.getAllBuilders(), new Function() { - @Override - public ProjectCategory fun(ModuleBuilder builder) { - return new BuilderBasedProjectType(builder); - } - })); - */ - categories.addAll(Arrays.asList(ProjectCategory.EXTENSION_POINT_NAME.getExtensions())); + final MultiMap categories = new MultiMap(); + for (ProjectCategory category : ProjectCategory.EXTENSION_POINT_NAME.getExtensions()) { + categories.putValue(category.getGroupName(), category); + } + List list = new ArrayList(); DefaultMutableTreeNode root = new DefaultMutableTreeNode(); MultiMap templatesMap = CreateFromTemplateMode.getTemplatesMap(context, false); List groups = new ArrayList(templatesMap.keySet()); @@ -128,32 +121,21 @@ public class ProjectTypeStep extends ModuleWizardStep { for (TemplatesGroup group : groups) { DefaultMutableTreeNode groupNode = new DefaultMutableTreeNode(group); root.add(groupNode); + Collection collection = categories.get(group.getName()); + for (ProjectCategory category : collection) { + groupNode.add(new DefaultMutableTreeNode(category)); + list.add(category); + } for (ProjectTemplate template : templatesMap.get(group)) { TemplateBasedProjectType projectType = new TemplateBasedProjectType(template); groupNode.add(new DefaultMutableTreeNode(projectType)); + list.add(projectType); } } - categories.addAll(ContainerUtil.map(templatesMap.values(), new Function() { - @Override - public ProjectCategory fun(ProjectTemplate template) { - return new TemplateBasedProjectType(template); - } - })); - - final MultiMap map = new MultiMap(); - for (ProjectCategory category : categories) { - map.putValue(category.getGroupName(), category); - } - Collections.sort(categories, new Comparator() { - @Override - public int compare(ProjectCategory o1, ProjectCategory o2) { - return map.get(o2.getGroupName()).size() - map.get(o1.getGroupName()).size(); - } - }); - myProjectTypeTree.setModel(new DefaultTreeModel(root)); TreeUtil.expandAll(myProjectTypeTree); + myProjectTypeTree.addSelectionRow(0); myProjectTypeTree.setCellRenderer(new ColoredTreeCellRenderer() { @Override @@ -191,7 +173,7 @@ public class ProjectTypeStep extends ModuleWizardStep { } }); - for (ProjectCategory category : categories) { + for (ProjectCategory category : list) { myWizard.getSequence().addStepsForBuilder(myBuilders.get(category), context, modulesProvider, true); } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java b/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java index a7ae91fd10f7..41ea001c6321 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java @@ -223,13 +223,11 @@ public class ConstructorInsertHandler implements InsertHandler candidatesToImplement = OverrideImplementUtil.getMethodsToOverrideImplement(aClass, true); - if (PsiUtil.isLanguageLevel8OrHigher(aClass)) { - for (Iterator iterator = candidatesToImplement.iterator(); iterator.hasNext(); ) { - final CandidateInfo candidate = iterator.next(); - final PsiElement element = candidate.getElement(); - if (element instanceof PsiMethod && ((PsiMethod)element).hasModifierProperty(PsiModifier.DEFAULT)) { - iterator.remove(); - } + for (Iterator iterator = candidatesToImplement.iterator(); iterator.hasNext(); ) { + final CandidateInfo candidate = iterator.next(); + final PsiElement element = candidate.getElement(); + if (element instanceof PsiMethod && ((PsiMethod)element).hasModifierProperty(PsiModifier.DEFAULT)) { + iterator.remove(); } } boolean invokeOverride = candidatesToImplement.isEmpty(); diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java b/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java index 15e6d5a04d9f..e58de2929ee1 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java @@ -450,7 +450,7 @@ public class OverrideImplementUtil extends OverrideImplementExploreUtil { final Collection candidates, Collection secondary) { - if (toImplement && PsiUtil.isLanguageLevel8OrHigher(aClass)) { + if (toImplement) { for (Iterator iterator = candidates.iterator(); iterator.hasNext(); ) { CandidateInfo candidate = iterator.next(); PsiElement element = candidate.getElement(); diff --git a/platform/lang-impl/src/com/intellij/ide/actions/GoToLinkTargetAction.java b/platform/lang-impl/src/com/intellij/ide/actions/GoToLinkTargetAction.java new file mode 100644 index 000000000000..d6ef42787274 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/actions/GoToLinkTargetAction.java @@ -0,0 +1,50 @@ +/* + * Copyright 2000-2013 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.intellij.ide.actions; + +import com.intellij.ide.projectView.ProjectView; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; +import com.intellij.openapi.project.DumbAwareAction; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VFileProperty; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; + +public class GoToLinkTargetAction extends DumbAwareAction { + @Override + public void update(AnActionEvent e) { + Project project = CommonDataKeys.PROJECT.getData(e.getDataContext()); + VirtualFile file = CommonDataKeys.VIRTUAL_FILE.getData(e.getDataContext()); + e.getPresentation().setEnabledAndVisible(project != null && file != null && file.is(VFileProperty.SYMLINK)); + } + + @Override + public void actionPerformed(AnActionEvent e) { + Project project = CommonDataKeys.PROJECT.getData(e.getDataContext()); + VirtualFile file = CommonDataKeys.VIRTUAL_FILE.getData(e.getDataContext()); + if (project != null && file != null && file.is(VFileProperty.SYMLINK)) { + VirtualFile target = file.getCanonicalFile(); + if (target != null) { + PsiFile psiFile = PsiManager.getInstance(project).findFile(target); + if (psiFile != null) { + ProjectView.getInstance(project).select(psiFile, target, false); + } + } + } + } +} diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/ActionInstallPlugin.java b/platform/platform-impl/src/com/intellij/ide/plugins/ActionInstallPlugin.java index 8c123e1b9d84..a72187b97ef0 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/ActionInstallPlugin.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/ActionInstallPlugin.java @@ -90,6 +90,7 @@ public class ActionInstallPlugin extends AnAction implements DumbAware { if (userConfirm(selection)) { final ArrayList list = new ArrayList(); + final PluginTableModel pluginTableModel = host.getPluginsModel(); for (IdeaPluginDescriptor descr : selection) { PluginNode pluginNode = null; if (descr instanceof PluginNode) { @@ -101,8 +102,7 @@ public class ActionInstallPlugin extends AnAction implements DumbAware { pluginNode.setName(descr.getName()); pluginNode.setDepends(Arrays.asList(descr.getDependentPluginIds()), descr.getOptionalDependentPluginIds()); pluginNode.setSize("-1"); - pluginNode.setRepositoryName(((InstalledPluginsTableModel)host.getPluginsModel()) - .getPluginHostUrl(pluginId.getIdString())); + pluginNode.setRepositoryName(((InstalledPluginsTableModel)pluginTableModel).getPluginHostUrl(pluginId.getIdString())); } if (pluginNode != null) { @@ -158,7 +158,7 @@ public class ActionInstallPlugin extends AnAction implements DumbAware { } } }; - PluginManagerMain.downloadPlugins(list, host.getPluginsModel().view, onInstallRunnable, new Runnable(){ + PluginManagerMain.downloadPlugins(list, pluginTableModel.getAllPlugins(), onInstallRunnable, new Runnable(){ @Override public void run() { ourInstallingNodes.removeAll(list); diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsManagerMain.java b/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsManagerMain.java index ed3bf3431346..57edd4894f7b 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsManagerMain.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsManagerMain.java @@ -168,7 +168,7 @@ public class InstalledPluginsManagerMain extends PluginManagerMain { } if (!disabledIds.isEmpty()) { final Set dependencies = new HashSet(); - for (IdeaPluginDescriptor ideaPluginDescriptor : pluginsModel.view) { + for (IdeaPluginDescriptor ideaPluginDescriptor : pluginsModel.getAllPlugins()) { if (disabledIds.contains(ideaPluginDescriptor.getPluginId())) { dependencies.add(ideaPluginDescriptor); } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java b/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java index fb2a3a83edea..1f2de10be311 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java @@ -440,8 +440,7 @@ public class InstalledPluginsTableModel extends PluginTableModel { if (newVal) { Collections.addAll(descriptorsToCheckDependencies, ideaPluginDescriptors); } else { - descriptorsToCheckDependencies.addAll(view); - descriptorsToCheckDependencies.addAll(filtered); + descriptorsToCheckDependencies.addAll(getAllPlugins()); descriptorsToCheckDependencies.removeAll(Arrays.asList(ideaPluginDescriptors)); for (Iterator iterator = descriptorsToCheckDependencies.iterator(); iterator.hasNext(); ) { diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginTableModel.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginTableModel.java index 1eac75961157..8fa37012d6d0 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginTableModel.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginTableModel.java @@ -103,7 +103,7 @@ abstract public class PluginTableModel extends AbstractTableModel implements Sor public ArrayList dependent(IdeaPluginDescriptorImpl plugin) { ArrayList list = new ArrayList(); - for (IdeaPluginDescriptor any : view) { + for (IdeaPluginDescriptor any : getAllPlugins()) { if (any instanceof IdeaPluginDescriptorImpl) { PluginId[] dep = any.getDependentPluginIds(); for (PluginId id : dep) { @@ -168,4 +168,11 @@ abstract public class PluginTableModel extends AbstractTableModel implements Sor public void setSortByStatus(boolean sortByStatus) { mySortByStatus = sortByStatus; } + + public List getAllPlugins() { + final ArrayList list = new ArrayList(); + list.addAll(view); + list.addAll(filtered); + return list; + } } diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiser.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiser.java index 24615ca1bc14..10cd1ee4470e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiser.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiser.java @@ -98,7 +98,7 @@ public class PluginsAdvertiser implements StartupActivity { int idx = 0; final Set ids = new HashSet(); for (UnknownFeature feature : unknownFeatures) { - indicator.setText("Searching for: " + feature.getFeatureType()); + indicator.setText("Searching for plugin supporting \'" + feature.getImplementationName() + "\'"); final List pluginId = retrieve(feature); if (pluginId != null) { //do not suggest to download disabled plugins diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties index d5e4e192d372..74794763a2be 100644 --- a/platform/platform-resources-en/src/messages/ActionsBundle.properties +++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties @@ -1330,6 +1330,8 @@ action.Console.History.Next.description=Next console history entry action.Console.History.Browse.text=Browse History action.Console.History.Browse.description=Browse console history action.RevealIn.text=Show/Reveal in Explorer/Finder/Konqueror/Nautilus +action.GoToLinkTarget.text=Go to Link Target +action.GoToLinkTarget.description=Opens a target ot this symlink in the Project View action.Images.EditExternaly.text=Jump to External Editor action.Images.EditExternaly.description=Open image in external editor diff --git a/platform/platform-resources/src/idea/LangActions.xml b/platform/platform-resources/src/idea/LangActions.xml index c10a538d3136..57aa79c0bdf0 100644 --- a/platform/platform-resources/src/idea/LangActions.xml +++ b/platform/platform-resources/src/idea/LangActions.xml @@ -70,7 +70,7 @@ - + @@ -160,7 +160,7 @@ - + @@ -284,7 +284,7 @@ - + @@ -431,6 +431,7 @@ + @@ -823,24 +824,24 @@ - + - + - + - + diff --git a/platform/testRunner/src/com/intellij/execution/testframework/TestTreeView.java b/platform/testRunner/src/com/intellij/execution/testframework/TestTreeView.java index 9ebebb61ce7d..822a5ab379b3 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/TestTreeView.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/TestTreeView.java @@ -92,6 +92,7 @@ public abstract class TestTreeView extends Tree implements DataProvider, CopyPro if (paths != null && paths.length > 1) { final List els = new ArrayList(paths.length); for (TreePath path : paths) { + if (isPathSelected(path.getParentPath())) continue; AbstractTestProxy test = getSelectedTest(path); if (test != null) { final PsiElement psiElement = (PsiElement)TestsUIUtil.getData(test, CommonDataKeys.PSI_ELEMENT.getName(), myModel); diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/JiraRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/JiraRepository.java index 5c5f181de97a..4270254efd4a 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/JiraRepository.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/JiraRepository.java @@ -142,6 +142,8 @@ public class JiraRepository extends BaseRepositoryImpl { throw e; } JsonObject object = JiraUtil.GSON.fromJson(responseBody, JsonObject.class); + // when JIRA 4.x support will be dropped 'versionNumber' array in response + // may be used instead version string parsing return JiraRestApi.fromJiraVersion(object.get("version").getAsString(), this); } diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/JiraVersion.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/JiraVersion.java index 41e69820c183..83519590cd33 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/JiraVersion.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/JiraVersion.java @@ -1,6 +1,7 @@ package com.intellij.tasks.jira; +import com.intellij.util.text.VersionComparatorUtil; import org.jetbrains.annotations.NotNull; import java.util.regex.Matcher; @@ -9,10 +10,11 @@ import java.util.regex.Pattern; /** * @author Mikhail Golubev */ -public class JiraVersion { - private static final Pattern VERSION_PATTERN = Pattern.compile("(\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))?"); +public class JiraVersion implements Comparable { + // Fix for IDEA-113944 + private static final Pattern VERSION_PATTERN = Pattern.compile("(\\d+)(?:[^\\d]+(\\d+))?(?:[^\\d]+(\\d+))?.*"); - private final int myMajorNumber, myMinorNumber, myBuildNumber; + private final int myMajorNumber, myMinorNumber, myMicroNumber; public JiraVersion(int majorNumber) { this(majorNumber, 0, 0); @@ -22,10 +24,10 @@ public class JiraVersion { this(majorNumber, minorNumber, 0); } - public JiraVersion(int majorNumber, int minorNumber, int buildNumber) { + public JiraVersion(int majorNumber, int minorNumber, int microNumber) { myMajorNumber = majorNumber; myMinorNumber = minorNumber; - myBuildNumber = buildNumber; + myMicroNumber = microNumber; } public JiraVersion(@NotNull String version) { @@ -35,7 +37,7 @@ public class JiraVersion { } myMajorNumber = m.group(1) == null ? 0 : Integer.parseInt(m.group(1)); myMinorNumber = m.group(2) == null ? 0 : Integer.parseInt(m.group(2)); - myBuildNumber = m.group(3) == null ? 0 : Integer.parseInt(m.group(3)); + myMicroNumber = m.group(3) == null ? 0 : Integer.parseInt(m.group(3)); } public int getMajorNumber() { @@ -46,12 +48,17 @@ public class JiraVersion { return myMinorNumber; } - public int getBuildNumber() { - return myBuildNumber; + public int getMicroNumber() { + return myMicroNumber; } @Override public String toString() { - return String.format("%d.%d.%d", myMajorNumber, myMinorNumber, myBuildNumber); + return String.format("%d.%d.%d", myMajorNumber, myMinorNumber, myMicroNumber); + } + + @Override + public int compareTo(@NotNull JiraVersion o) { + return VersionComparatorUtil.compare(toString(), o.toString()); } } diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/lang/YouTrackHighlightingAnnotator.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/lang/YouTrackHighlightingAnnotator.java index 16717d69d102..09af6363c19b 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/lang/YouTrackHighlightingAnnotator.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/lang/YouTrackHighlightingAnnotator.java @@ -5,15 +5,11 @@ import com.intellij.lang.annotation.AnnotationHolder; import com.intellij.lang.annotation.ExternalAnnotator; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.editor.markup.EffectType; -import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.psi.PsiFile; import com.intellij.tasks.youtrack.YouTrackIntellisense; -import com.intellij.ui.JBColor; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.awt.*; import java.util.Collections; import java.util.List; @@ -26,16 +22,9 @@ import static com.intellij.tasks.youtrack.lang.YouTrackHighlightingAnnotator.Que public class YouTrackHighlightingAnnotator extends ExternalAnnotator> { private static Logger LOG = Logger.getInstance(YouTrackHighlightingAnnotator.class); - private static final boolean DEBUG = false; - private static final TextAttributes DEBUG_ATTRIBUTES = - new TextAttributes(JBColor.RED, JBColor.WHITE, JBColor.GREEN, EffectType.STRIKEOUT, Font.BOLD); - @Nullable @Override public QueryInfo collectInformation(@NotNull PsiFile file, @NotNull Editor editor, boolean hasErrors) { - if (DEBUG) { - return new QueryInfo(0, "empty", null); - } final YouTrackIntellisense intellisense = file.getUserData(YouTrackIntellisense.INTELLISENSE_KEY); if (intellisense == null || !intellisense.getRepository().isConfigured()) { return null; @@ -49,12 +38,11 @@ public class YouTrackHighlightingAnnotator extends ExternalAnnotator doAnnotate(QueryInfo collectedInfo) { - //noinspection ConstantConditions - if (collectedInfo == null || DEBUG) { + if (collectedInfo == null) { return Collections.emptyList(); } - String query = collectedInfo.myText; - int offset = collectedInfo.myCaretOffset; + final String query = collectedInfo.myText; + final int offset = collectedInfo.myCaretOffset; try { return collectedInfo.myIntellisense.fetchHighlighting(query, offset); } @@ -65,11 +53,6 @@ public class YouTrackHighlightingAnnotator extends ExternalAnnotator ranges, @NotNull AnnotationHolder holder) { - if (DEBUG) { - Annotation annotation = holder.createErrorAnnotation(file.getFirstChild(), "Debug message"); - annotation.setEnforcedTextAttributes(DEBUG_ATTRIBUTES); - return; - } for (HighlightRange range : ranges) { if (range.getStyleClass().equals("error")) { holder.createErrorAnnotation(range.getTextRange(), null); diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/lang/codeinsight/YouTrackCompletionContributor.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/lang/codeinsight/YouTrackCompletionContributor.java index 893006abf999..4b397e9ed825 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/lang/codeinsight/YouTrackCompletionContributor.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/lang/codeinsight/YouTrackCompletionContributor.java @@ -29,7 +29,7 @@ import static com.intellij.tasks.youtrack.YouTrackIntellisense.CompletionItem; */ public class YouTrackCompletionContributor extends CompletionContributor { private static final Logger LOG = Logger.getInstance(YouTrackCompletionContributor.class); - private static final int TIMEOUT = 2000; + private static final int TIMEOUT = 2000; // ms private static final InsertHandler INSERT_HANDLER = new MyInsertHandler(); @@ -57,26 +57,23 @@ public class YouTrackCompletionContributor extends CompletionContributor { try { final List suggestions = future.get(TIMEOUT, TimeUnit.MILLISECONDS); // actually backed by original CompletionResultSet - result = result.withPrefixMatcher(extractPrefix(parameters)); + result = result.withPrefixMatcher(extractPrefix(parameters)).caseInsensitive(); result.addAllElements(ContainerUtil.map(suggestions, new Function() { @Override public LookupElement fun(CompletionItem item) { - LookupElementBuilder builder = LookupElementBuilder.create(item, item.getOption()) + return LookupElementBuilder.create(item, item.getOption()) .withTypeText(item.getDescription(), true) - .withInsertHandler(INSERT_HANDLER); - // doesn't work actually TODO: write about it to guys in YouTrack - //if (item.getStyleClass().equals("keyword")) { - // builder = builder.bold(); - //} - return builder; + .withInsertHandler(INSERT_HANDLER) + .withBoldness(item.getStyleClass().equals("keyword")); } })); } catch (Exception ignored) { + //noinspection InstanceofCatchParameter if (ignored instanceof TimeoutException) { - LOG.debug("YouTrack request took more than %d ms to complete"); + LOG.debug(String.format("YouTrack request took more than %d ms to complete", TIMEOUT)); } - result.stopHere(); + LOG.debug(ignored); } } @@ -90,20 +87,27 @@ public class YouTrackCompletionContributor extends CompletionContributor { if (text.isEmpty() || caretOffset == 0) { return ""; } - final int lastSpace = text.lastIndexOf(' ', caretOffset - 1); + int stopAt = text.lastIndexOf('{', caretOffset - 1); + // caret isn't inside braces + if (stopAt <= text.lastIndexOf('}', caretOffset - 1)) { + // we stay right after colon + if (text.charAt(caretOffset - 1) == ':') { + stopAt = caretOffset - 1; + } + // use rightmost word boundary as last resort + else { + stopAt = text.lastIndexOf(' ', caretOffset - 1); + } + } //int start = CharArrayUtil.shiftForward(text, lastSpace < 0 ? 0 : lastSpace + 1, "#{ "); - int start = Math.min(lastSpace + 1, text.length() - 1); - if (text.charAt(start) == '#') { - start++; + int prefixStart = stopAt + 1; + if (prefixStart < text.length() && text.charAt(prefixStart) == '#') { + prefixStart++; } - if (start < text.length() && text.charAt(start) == '{') { - start++; - } - return StringUtil.trimLeading(text.substring(start, caretOffset)); + return StringUtil.trimLeading(text.substring(prefixStart, caretOffset)); } - /** * Inserts additional braces around values that contains spaces, colon after attribute names * and '#' before short-cut attributes if any @@ -120,21 +124,37 @@ public class YouTrackCompletionContributor extends CompletionContributor { final String prefix = completionItem.getPrefix(); final String suffix = completionItem.getSuffix(); - if (!prefix.isEmpty() && !hasPrefixAt(document, context.getStartOffset() - prefix.length(), prefix)) { - document.insertString(context.getStartOffset(), prefix); + String text = document.getText(); + int offset = context.getStartOffset(); + // skip possible spaces after '{', e.g. "{ My Project " + if (prefix.endsWith("{")) { + while (offset > prefix.length() && Character.isWhitespace(text.charAt(offset - 1))) { + offset--; + } } - if (!suffix.isEmpty() && !hasPrefixAt(document, context.getTailOffset(), suffix)) { - document.insertString(context.getTailOffset(), suffix); + if (!prefix.isEmpty() && !hasPrefixAt(document.getText(), offset - prefix.length(), prefix)) { + document.insertString(offset, prefix); + } + offset = context.getTailOffset(); + text = document.getText(); + if (suffix.startsWith("} ")) { + while (offset < text.length() - suffix.length() && Character.isWhitespace(text.charAt(offset))) { + offset++; + } + } + if (!suffix.isEmpty() && !hasPrefixAt(text, offset, suffix)) { + document.insertString(offset, suffix); } editor.getCaretModel().moveToOffset(context.getTailOffset()); } } - static boolean hasPrefixAt(Document document, int offset, String prefix) { - String text = document.getText(); - if (text.isEmpty() || offset < 0) { + static boolean hasPrefixAt(String text, int offset, String prefix) { + if (text.isEmpty() || offset < 0 || offset >= text.length()) { return false; } return text.regionMatches(true, offset, prefix, 0, prefix.length()); } } + + diff --git a/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/JiraIntegrationTest.java b/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/JiraIntegrationTest.java index 75a792d7e493..3780bd89c15a 100644 --- a/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/JiraIntegrationTest.java +++ b/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/JiraIntegrationTest.java @@ -20,6 +20,7 @@ import com.intellij.tasks.TaskManagerTestCase; import com.intellij.tasks.TaskState; import com.intellij.tasks.jira.JiraRepository; import com.intellij.tasks.jira.JiraRepositoryType; +import com.intellij.tasks.jira.JiraVersion; import org.jetbrains.annotations.NonNls; /** @@ -115,6 +116,13 @@ public class JiraIntegrationTest extends TaskManagerTestCase { } } + public void testParseVersionNumbers() throws Exception { + assertEquals(new JiraVersion("6.1-OD-09-WN").toString(), "6.1.9"); + assertEquals(new JiraVersion("5.0.6").toString(), "5.0.6"); + assertEquals(new JiraVersion("4.4.5").toString(), "4.4.5"); + + } + @Override public void setUp() throws Exception { super.setUp(); diff --git a/test-log.xml b/test-log.xml index 3028abeab261..bb13329ce489 100644 --- a/test-log.xml +++ b/test-log.xml @@ -18,7 +18,7 @@ - +