Merge remote-tracking branch 'origin/master'

This commit is contained in:
Ekaterina Tuzova
2013-10-04 15:28:17 +04:00
18 changed files with 171 additions and 111 deletions
@@ -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<ProjectCategory> categories = new ArrayList<ProjectCategory>();
/*
categories.addAll(ContainerUtil.map(ModuleBuilder.getAllBuilders(), new Function<ModuleBuilder, ProjectCategory>() {
@Override
public ProjectCategory fun(ModuleBuilder builder) {
return new BuilderBasedProjectType(builder);
}
}));
*/
categories.addAll(Arrays.asList(ProjectCategory.EXTENSION_POINT_NAME.getExtensions()));
final MultiMap<String, ProjectCategory> categories = new MultiMap<String, ProjectCategory>();
for (ProjectCategory category : ProjectCategory.EXTENSION_POINT_NAME.getExtensions()) {
categories.putValue(category.getGroupName(), category);
}
List<ProjectCategory> list = new ArrayList<ProjectCategory>();
DefaultMutableTreeNode root = new DefaultMutableTreeNode();
MultiMap<TemplatesGroup,ProjectTemplate> templatesMap = CreateFromTemplateMode.getTemplatesMap(context, false);
List<TemplatesGroup> groups = new ArrayList<TemplatesGroup>(templatesMap.keySet());
@@ -128,32 +121,21 @@ public class ProjectTypeStep extends ModuleWizardStep {
for (TemplatesGroup group : groups) {
DefaultMutableTreeNode groupNode = new DefaultMutableTreeNode(group);
root.add(groupNode);
Collection<ProjectCategory> 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<ProjectTemplate, ProjectCategory>() {
@Override
public ProjectCategory fun(ProjectTemplate template) {
return new TemplateBasedProjectType(template);
}
}));
final MultiMap<String, ProjectCategory> map = new MultiMap<String, ProjectCategory>();
for (ProjectCategory category : categories) {
map.putValue(category.getGroupName(), category);
}
Collections.sort(categories, new Comparator<ProjectCategory>() {
@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);
}
@@ -223,13 +223,11 @@ public class ConstructorInsertHandler implements InsertHandler<LookupElementDeco
if (aClass == null) return;
final Collection<CandidateInfo> candidatesToImplement = OverrideImplementUtil.getMethodsToOverrideImplement(aClass, true);
if (PsiUtil.isLanguageLevel8OrHigher(aClass)) {
for (Iterator<CandidateInfo> 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<CandidateInfo> 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();
@@ -450,7 +450,7 @@ public class OverrideImplementUtil extends OverrideImplementExploreUtil {
final Collection<CandidateInfo> candidates,
Collection<CandidateInfo> secondary) {
if (toImplement && PsiUtil.isLanguageLevel8OrHigher(aClass)) {
if (toImplement) {
for (Iterator<CandidateInfo> iterator = candidates.iterator(); iterator.hasNext(); ) {
CandidateInfo candidate = iterator.next();
PsiElement element = candidate.getElement();
@@ -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);
}
}
}
}
}
@@ -90,6 +90,7 @@ public class ActionInstallPlugin extends AnAction implements DumbAware {
if (userConfirm(selection)) {
final ArrayList<PluginNode> list = new ArrayList<PluginNode>();
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);
@@ -168,7 +168,7 @@ public class InstalledPluginsManagerMain extends PluginManagerMain {
}
if (!disabledIds.isEmpty()) {
final Set<IdeaPluginDescriptor> dependencies = new HashSet<IdeaPluginDescriptor>();
for (IdeaPluginDescriptor ideaPluginDescriptor : pluginsModel.view) {
for (IdeaPluginDescriptor ideaPluginDescriptor : pluginsModel.getAllPlugins()) {
if (disabledIds.contains(ideaPluginDescriptor.getPluginId())) {
dependencies.add(ideaPluginDescriptor);
}
@@ -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<IdeaPluginDescriptor> iterator = descriptorsToCheckDependencies.iterator(); iterator.hasNext(); ) {
@@ -103,7 +103,7 @@ abstract public class PluginTableModel extends AbstractTableModel implements Sor
public ArrayList<IdeaPluginDescriptorImpl> dependent(IdeaPluginDescriptorImpl plugin) {
ArrayList<IdeaPluginDescriptorImpl> list = new ArrayList<IdeaPluginDescriptorImpl>();
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<IdeaPluginDescriptor> getAllPlugins() {
final ArrayList<IdeaPluginDescriptor> list = new ArrayList<IdeaPluginDescriptor>();
list.addAll(view);
list.addAll(filtered);
return list;
}
}
@@ -98,7 +98,7 @@ public class PluginsAdvertiser implements StartupActivity {
int idx = 0;
final Set<PluginId> ids = new HashSet<PluginId>();
for (UnknownFeature feature : unknownFeatures) {
indicator.setText("Searching for: " + feature.getFeatureType());
indicator.setText("Searching for plugin supporting \'" + feature.getImplementationName() + "\'");
final List<PluginId> pluginId = retrieve(feature);
if (pluginId != null) {
//do not suggest to download disabled plugins
@@ -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
@@ -70,7 +70,7 @@
<action id="ExportToHTML" class="com.intellij.codeEditor.printing.ExportToHTMLAction"/>
<action id="Print" class="com.intellij.codeEditor.printing.PrintAction" icon="AllIcons.Graph.Print"/>
<reference ref="AddToFavorites"/>
<add-to-group group-id="FileMenu" anchor="after" relative-to-action="InvalidateCaches"/>
</group>
@@ -160,7 +160,7 @@
<add-to-group group-id="ViewMenu" relative-to-action="QuickActions" anchor="after"/>
</group>
<action id="FixDocComment" class="com.intellij.codeInsight.editorActions.FixDocCommentAction"/>
<action id="ViewNavigationBar" class="com.intellij.ide.actions.ViewNavigationBarAction">
@@ -284,7 +284,7 @@
<action id="ExtractSuperclass" class="com.intellij.refactoring.actions.ExtractSuperclassAction"/>
<action id="ExtractModule" class="com.intellij.refactoring.actions.ExtractModuleAction"/>
</group>
<action id="Inline" class="com.intellij.refactoring.actions.InlineAction"/>
<separator/>
<action id="MembersPullUp" class="com.intellij.refactoring.actions.PullUpAction"/>
@@ -431,6 +431,7 @@
<separator/>
<action id="RevealIn" class="com.intellij.ide.actions.RevealFileAction"/>
<reference ref="ShowFilePath"/>
<action id="GoToLinkTarget" class="com.intellij.ide.actions.GoToLinkTargetAction"/>
<separator/>
<reference ref="CompareTwoFiles"/>
<reference ref="CompareFileWithEditor"/>
@@ -823,24 +824,24 @@
<action id="Arrangement.Rule.Group.Condition.Move.Down"
class="com.intellij.application.options.codeStyle.arrangement.action.MoveArrangementGroupingRuleDownAction"
icon="AllIcons.ToolbarDecorator.MoveDown"/>
<group id="Arrangement.Rule.Match.Control.Context.Menu">
<reference ref="Arrangement.Rule.Add"/>
<reference ref="Arrangement.Rule.Remove"/>
<reference ref="Arrangement.Rule.Edit"/>
</group>
<group id="Arrangement.Rule.Match.Control.ToolBar">
<reference ref="Arrangement.Rule.Add"/>
<reference ref="Arrangement.Rule.Remove"/>
<reference ref="Arrangement.Rule.Match.Condition.Move.Up"/>
<reference ref="Arrangement.Rule.Match.Condition.Move.Down"/>
</group>
<group id="Arrangement.Rule.Group.Control.ToolBar">
<reference ref="Arrangement.Rule.Group.Condition.Move.Up"/>
<reference ref="Arrangement.Rule.Group.Condition.Move.Down"/>
</group>
</actions>
</component>
@@ -92,6 +92,7 @@ public abstract class TestTreeView extends Tree implements DataProvider, CopyPro
if (paths != null && paths.length > 1) {
final List<PsiElement> els = new ArrayList<PsiElement>(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);
@@ -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);
}
@@ -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<JiraVersion> {
// 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());
}
}
@@ -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<QueryInfo, List<HighlightRange>> {
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<QueryInfo,
@Nullable
@Override
public List<HighlightRange> 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<QueryInfo,
@Override
public void apply(@NotNull PsiFile file, List<HighlightRange> 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);
@@ -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<LookupElement> INSERT_HANDLER = new MyInsertHandler();
@@ -57,26 +57,23 @@ public class YouTrackCompletionContributor extends CompletionContributor {
try {
final List<CompletionItem> 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<CompletionItem, LookupElement>() {
@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 <caret>"
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());
}
}
@@ -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();
+1 -1
View File
@@ -18,7 +18,7 @@
</layout>
</appender>
<appender name="FILE" class="org.apache.log4j.FileAppender">
<appender name="FILE" class="org.apache.log4j.RollingFileAppender">
<param name="append" value="false"/>
<param name="file" value="$LOG_DIR$/idea.log"/>
<layout class="org.apache.log4j.PatternLayout">