2 * Copyright 2000-2011 JetBrains s.r.o.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package com.intellij.openapi.vcs;
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;
37 import java.util.List;
40 * @author Dmitry Avdeev
42 public class CommitCompletionContributor extends CompletionContributor {
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;
51 CommitMessage commitMessage = document.getUserData(CommitMessage.DATA_KEY);
52 if (commitMessage == null) return;
55 int count = parameters.getInvocationCount();
57 String prefix = TextFieldWithAutoCompletionListProvider.getCompletionPrefix(parameters);
58 if (count == 0 && prefix.length() < 5) {
59 result.restartCompletionOnPrefixChange(StandardPatterns.string().withLength(5));
62 CompletionResultSet resultSet = result.caseInsensitive().withPrefixMatcher(
63 count == 0 ? new PlainPrefixMatcher(prefix, true) : new CamelHumpMatcher(prefix));
64 CompletionResultSet prefixed = result.withPrefixMatcher(new PlainPrefixMatcher(prefix, count == 0));
65 for (ChangeList list : commitMessage.getChangeLists()) {
66 ProgressManager.checkCanceled();
67 for (Change change : list.getChanges()) {
68 ProgressManager.checkCanceled();
69 FilePath beforePath = ChangesUtil.getBeforePath(change);
70 FilePath afterPath = ChangesUtil.getAfterPath(change);
71 if (afterPath != null) {
72 addFilePathName(resultSet, afterPath, false);
73 addLanguageSpecificElements(project, count, prefixed, afterPath);
75 if (beforePath != null) {
76 if (afterPath == null || !beforePath.getName().equals(afterPath.getName())) {
77 addFilePathName(resultSet, beforePath, true);
84 result.caseInsensitive()
85 .withPrefixMatcher(new PlainPrefixMatcher(prefix))
87 StreamEx.of(VcsConfiguration.getInstance(project).getRecentMessages())
89 .map(lookupString -> PrioritizedLookupElement.withPriority(LookupElementBuilder.create(lookupString), Integer.MIN_VALUE)));
93 private static void addFilePathName(CompletionResultSet resultSet, FilePath filePath, boolean strikeout) {
94 resultSet.addElement(LookupElementBuilder.create(filePath.getName())
95 .withIcon(filePath.getFileType().getIcon())
96 .withStrikeoutness(strikeout));
99 private static void addLanguageSpecificElements(Project project, int count, CompletionResultSet prefixed, FilePath filePath) {
100 VirtualFile vFile = filePath.getVirtualFile();
101 if (vFile == null) return;
102 PsiFile psiFile = PsiManagerEx.getInstanceEx(project).findFile(vFile);
103 if (psiFile == null) return;
104 PlainTextSymbolCompletionContributor contributor = PlainTextSymbolCompletionContributorEP.forLanguage(psiFile.getLanguage());
105 if (contributor == null) return;
106 prefixed.addAllElements(contributor.getLookupElements(psiFile, count, prefixed.getPrefixMatcher().getPrefix()));