[commit] extract recent commit messages contributor
[idea/community.git] / platform / vcs-impl / src / com / intellij / openapi / vcs / ChangedFilesCommitCompletionContributor.java
1 /*
2  * Copyright 2000-2011 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.openapi.vcs;
17
18 import com.intellij.codeInsight.completion.*;
19 import com.intellij.codeInsight.completion.impl.CamelHumpMatcher;
20 import com.intellij.codeInsight.lookup.LookupElementBuilder;
21 import com.intellij.openapi.editor.Document;
22 import com.intellij.openapi.progress.ProgressManager;
23 import com.intellij.openapi.project.Project;
24 import com.intellij.openapi.vcs.changes.Change;
25 import com.intellij.openapi.vcs.changes.ChangeList;
26 import com.intellij.openapi.vcs.changes.ChangesUtil;
27 import com.intellij.openapi.vcs.ui.CommitMessage;
28 import com.intellij.openapi.vfs.VirtualFile;
29 import com.intellij.patterns.StandardPatterns;
30 import com.intellij.psi.PsiDocumentManager;
31 import com.intellij.psi.PsiFile;
32 import com.intellij.psi.impl.PsiManagerEx;
33 import com.intellij.ui.TextFieldWithAutoCompletionListProvider;
34 import one.util.streamex.StreamEx;
35 import org.jetbrains.annotations.NotNull;
36
37 import java.util.List;
38
39 /**
40  * @author Dmitry Avdeev
41  */
42 public class ChangedFilesCommitCompletionContributor extends CompletionContributor {
43
44   @Override
45   public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
46     PsiFile file = parameters.getOriginalFile();
47     Project project = file.getProject();
48     Document document = PsiDocumentManager.getInstance(project).getDocument(file);
49     if (document == null) return;
50
51     CommitMessage commitMessage = document.getUserData(CommitMessage.DATA_KEY);
52     if (commitMessage == null) return;
53
54     result.stopHere();
55     int count = parameters.getInvocationCount();
56
57     List<ChangeList> lists = commitMessage.getChangeLists();
58     if (lists.isEmpty()) return;
59
60     String prefix = TextFieldWithAutoCompletionListProvider.getCompletionPrefix(parameters);
61     if (count == 0 && prefix.length() < 5) {
62       result.restartCompletionOnPrefixChange(StandardPatterns.string().withLength(5));
63       return;
64     }
65     CompletionResultSet resultSet = result.caseInsensitive().withPrefixMatcher(
66       count == 0 ? new PlainPrefixMatcher(prefix, true) : new CamelHumpMatcher(prefix));
67     CompletionResultSet prefixed = result.withPrefixMatcher(new PlainPrefixMatcher(prefix, count == 0));
68     for (ChangeList list : lists) {
69       ProgressManager.checkCanceled();
70       for (Change change : list.getChanges()) {
71         ProgressManager.checkCanceled();
72         FilePath beforePath = ChangesUtil.getBeforePath(change);
73         FilePath afterPath = ChangesUtil.getAfterPath(change);
74         if (afterPath != null) {
75           addFilePathName(resultSet, afterPath, false);
76           addLanguageSpecificElements(project, count, prefixed, afterPath);
77         }
78         if (beforePath != null) {
79           if (afterPath == null || !beforePath.getName().equals(afterPath.getName())) {
80             addFilePathName(resultSet, beforePath, true);
81           }
82         }
83       }
84     }
85   }
86
87   private static void addFilePathName(CompletionResultSet resultSet, FilePath filePath, boolean strikeout) {
88     resultSet.addElement(LookupElementBuilder.create(filePath.getName())
89                            .withIcon(filePath.getFileType().getIcon())
90                            .withStrikeoutness(strikeout));
91   }
92
93   private static void addLanguageSpecificElements(Project project, int count, CompletionResultSet prefixed, FilePath filePath) {
94     VirtualFile vFile = filePath.getVirtualFile();
95     if (vFile == null) return;
96     PsiFile psiFile = PsiManagerEx.getInstanceEx(project).findFile(vFile);
97     if (psiFile == null) return;
98     PlainTextSymbolCompletionContributor contributor = PlainTextSymbolCompletionContributorEP.forLanguage(psiFile.getLanguage());
99     if (contributor == null) return;
100     prefixed.addAllElements(contributor.getLookupElements(psiFile, count, prefixed.getPrefixMatcher().getPrefix()));
101   }
102 }