Skip to content

Commit

Permalink
Change to a LanguageConsole to restore command history.
Browse files Browse the repository at this point in the history
It's a bit of a kludge: the language is 'Plain Text'. But this seems like the path of least resistance. No autocompletion provided: that's a much bigger job.

Requires IDEA 11 (Nika), so bumping the version to 1.4.0-SNAPSHOT and branching
until I release 1.3.2 from master.

Fixes #42, References #33
  • Loading branch information
retronym committed Nov 24, 2011
1 parent e5c6506 commit 111587c
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import com.intellij.openapi.wm.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.ui.content.*;
import net.orfjackal.sbt.plugin.sbtlang.SbtLanguage;

import javax.swing.*;
import java.awt.*;
Expand Down Expand Up @@ -60,7 +61,7 @@ public SbtConsole(String title, Project project, SbtRunnerComponent runnerCompon
}

private static ConsoleView createConsoleView(Project project) {
final LanguageConsoleImpl sbtLanguageConsole = new LanguageConsoleImpl(project, "SBT", StdLanguages.TEXT);
final LanguageConsoleImpl sbtLanguageConsole = new LanguageConsoleImpl(project, "SBT", SbtLanguage.INSTANCE);
LanguageConsoleViewImpl consoleView = new LanguageConsoleViewImpl(project, sbtLanguageConsole) {
@Override
public void attachToProcess(ProcessHandler processHandler) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Copyright © 2010-2011, Esko Luontola <www.orfjackal.net>
// This software is released under the Apache License 2.0.
// The license text is at http://www.apache.org/licenses/LICENSE-2.0

package net.orfjackal.sbt.plugin.sbtlang;

import com.intellij.codeInsight.completion.*;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.lang.ASTNode;
import com.intellij.lang.LanguageWordCompletion;
import com.intellij.openapi.project.DumbService;
import com.intellij.patterns.PlatformPatterns;
import com.intellij.psi.PlainTextTokenTypes;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiReference;
import com.intellij.psi.tree.IElementType;
import com.intellij.util.ProcessingContext;
import org.jetbrains.annotations.NotNull;

import java.util.*;

import static com.intellij.patterns.StandardPatterns.character;

// TODO get completion variants from SBT over a telnet-like interface
// TODO target this contributor to the SBT console in a more principled manner (rather than using the getContainingFile.getName == SbtLanguage.INSTACNCE.getID)

// Adapted from WordCompletionContributor in IDEA core.
public class SbtCompletionContributor extends CompletionContributor {

@Override
public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet result) {
if (parameters.getCompletionType() == CompletionType.BASIC && shouldPerformWordCompletion(parameters)) {
addWordCompletionVariants(result, parameters, Collections.<String>emptySet());
}
}

public static void addWordCompletionVariants(CompletionResultSet result, CompletionParameters parameters, Set<String> excludes) {
int startOffset = parameters.getOffset();
PsiElement insertedElement = parameters.getPosition();
final CompletionResultSet plainResultSet = result.withPrefixMatcher(CompletionUtil.findIdentifierPrefix(insertedElement,
startOffset,
character().javaIdentifierPart().andNot(character().equalTo('$')),
character().javaIdentifierStart()));
List<String> strings = Arrays.asList("compile", "run", "test:compile", "test", "project", "projects", "inspect", "show", "last", "last-grep");
for (String string : strings) {
final LookupElement item = LookupElementBuilder.create(string);
plainResultSet.addElement(item);
}
}

private static boolean shouldPerformWordCompletion(CompletionParameters parameters) {
final PsiElement insertedElement = parameters.getPosition();
final boolean dumb = DumbService.getInstance(insertedElement.getProject()).isDumb();
if (dumb) {
return true;
}
// TODO Hackedy-hack.
if (!insertedElement.getContainingFile().getName().equals("SBT")) {
return false;
}

if (parameters.getInvocationCount() == 0) {
return false;
}

final PsiFile file = insertedElement.getContainingFile();

final int startOffset = parameters.getOffset();

final PsiElement element = file.findElementAt(startOffset - 1);

ASTNode textContainer = element != null ? element.getNode() : null;
while (textContainer != null) {
final IElementType elementType = textContainer.getElementType();
if (LanguageWordCompletion.INSTANCE.isEnabledIn(elementType) || elementType == PlainTextTokenTypes.PLAIN_TEXT) {
return true;
}
textContainer = textContainer.getTreeParent();
}
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright © 2010-2011, Esko Luontola <www.orfjackal.net>
// This software is released under the Apache License 2.0.
// The license text is at http://www.apache.org/licenses/LICENSE-2.0

package net.orfjackal.sbt.plugin.sbtlang;

import com.intellij.lang.Language;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.FileViewProvider;
import com.intellij.psi.FileViewProviderFactory;
import com.intellij.psi.PsiManager;
import com.intellij.psi.SingleRootFileViewProvider;

public class SbtFileViewProviderFactory implements FileViewProviderFactory {

public FileViewProvider createFileViewProvider(VirtualFile file, Language language, PsiManager manager, boolean physical) {
return new SingleRootFileViewProvider(manager, file, physical, language.getBaseLanguage()) {


};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright © 2010-2011, Esko Luontola <www.orfjackal.net>
// This software is released under the Apache License 2.0.
// The license text is at http://www.apache.org/licenses/LICENSE-2.0

package net.orfjackal.sbt.plugin.sbtlang;


import com.intellij.lang.Language;
import com.intellij.lang.StdLanguages;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;

/** A language for input in the SBT console */
public class SbtLanguage extends Language {
public SbtLanguage() {
super(StdLanguages.TEXT, "SBT");
}
public static final Language INSTANCE = new SbtLanguage();
}
4 changes: 4 additions & 0 deletions sbt-plugin/src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@
<extensions defaultExtensionNs="com.intellij">
<stepsBeforeRunProvider implementation="net.orfjackal.sbt.plugin.SbtBeforeRunTaskProvider"/>
<projectConfigurable implementation="net.orfjackal.sbt.plugin.settings.SbtConfigurable" order="last"/>

<completion.contributor language="TEXT" implementationClass="net.orfjackal.sbt.plugin.sbtlang.SbtCompletionContributor"/>
<lang.fileViewProviderFactory language="SBT"
implementationClass="net.orfjackal.sbt.plugin.sbtlang.SbtFileViewProviderFactory"/>
</extensions>

<project-components>
Expand Down

1 comment on commit 111587c

@ijuma
Copy link
Contributor

@ijuma ijuma commented on 111587c Nov 25, 2011

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool!

Please sign in to comment.