Skip to content

Commit 30c8bb4

Browse files
committed
Created settings and implemented insertion of LiveTemplate on SmartEnter
1 parent 3b99788 commit 30c8bb4

9 files changed

Lines changed: 543 additions & 91 deletions

File tree

resources/META-INF/plugin.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,9 +169,9 @@
169169
<psi.referenceContributor language="Mathematica" implementation="de.halirutan.mathematica.parsing.psi.MathematicaReferenceContributor"/>
170170
<renamePsiElementProcessor implementation="de.halirutan.mathematica.refactoring.MathematicaPsiRenameProcessor"/>
171171

172-
<!--<applicationService serviceInterface="de.halirutan.mathematica.MathematicaSettings" serviceImplementation="de.halirutan.mathematica.MathematicaSettings"/>-->
173-
<!--<applicationConfigurable groupId="language" displayName="Mathematica" id="preferences.Mathematica"-->
174-
<!--instance="de.halirutan.mathematica.MathematicaSettingsConfigurable"/>-->
172+
<applicationService serviceInterface="de.halirutan.mathematica.settings.MathematicaSettings" serviceImplementation="de.halirutan.mathematica.settings.MathematicaSettings"/>
173+
<applicationConfigurable groupId="language" displayName="Mathematica" id="preferences.Mathematica"
174+
instance="de.halirutan.mathematica.settings.MathematicaSettingsConfigurable"/>
175175
<gotoRelatedProvider
176176
implementation="de.halirutan.mathematica.codeinsight.navigation.MathematicaGotoRelatedProvider"/>
177177

src/de/halirutan/mathematica/MathematicaSettingsConfigurable.form

Lines changed: 0 additions & 41 deletions
This file was deleted.

src/de/halirutan/mathematica/codeinsight/completion/BuiltinSymbolLookupElement.java

Lines changed: 68 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,24 +25,32 @@
2525
import com.intellij.codeInsight.lookup.Lookup;
2626
import com.intellij.codeInsight.lookup.LookupElement;
2727
import com.intellij.codeInsight.lookup.LookupElementPresentation;
28+
import com.intellij.codeInsight.template.*;
2829
import com.intellij.openapi.editor.Document;
2930
import com.intellij.openapi.editor.Editor;
3031
import com.intellij.openapi.project.Project;
3132
import com.intellij.openapi.util.TextRange;
3233
import com.intellij.psi.PsiDocumentManager;
34+
import com.intellij.psi.PsiElement;
35+
import com.intellij.psi.util.PsiTreeUtil;
3336
import de.halirutan.mathematica.codeinsight.completion.SymbolInformationProvider.SymbolInformation;
37+
import de.halirutan.mathematica.parsing.psi.api.FunctionCall;
38+
import de.halirutan.mathematica.settings.MathematicaSettings;
39+
import de.halirutan.mathematica.settings.MathematicaSettings.SmartEnterResult;
3440
import org.jetbrains.annotations.NotNull;
41+
import org.jetbrains.annotations.Nullable;
3542

3643
/**
3744
* @author patrick (30.11.16).
3845
*/
46+
@SuppressWarnings("AnonymousClassVariableHidesContainingMethodVariable")
3947
public class BuiltinSymbolLookupElement extends LookupElement {
4048

4149
private final SymbolInformation myInfo;
4250
private static final char OPEN_BRACKET = '[';
4351
private static final char CLOSING_BRACKET = ']';
4452

45-
public BuiltinSymbolLookupElement(SymbolInformation info) {
53+
BuiltinSymbolLookupElement(SymbolInformation info) {
4654
myInfo = info;
4755
}
4856

@@ -70,33 +78,78 @@ public boolean isCaseSensitive() {
7078

7179
@Override
7280
public void handleInsert(InsertionContext context) {
73-
Editor editor = context.getEditor();
74-
Document document = editor.getDocument();
75-
context.commitDocument();
81+
final SmartEnterResult smartEnterSetting = MathematicaSettings.getInstance().getSmartEnterResult();
82+
Editor editor = context.getEditor();
83+
Document document = editor.getDocument();
84+
context.commitDocument();
7685

77-
char completionChar = context.getCompletionChar();
78-
context.setAddCompletionChar(false);
86+
char completionChar = context.getCompletionChar();
87+
context.setAddCompletionChar(false);
7988

80-
if (completionChar == Lookup.COMPLETE_STATEMENT_SELECT_CHAR) {
81-
if (myInfo.function) {
89+
if (completionChar == Lookup.COMPLETE_STATEMENT_SELECT_CHAR) {
90+
if (myInfo.function) {
91+
if (smartEnterSetting.equals(SmartEnterResult.INSERT_BRACES)) {
92+
document.insertString(context.getTailOffset(), "[]");
93+
final int currentPosition = context.getTailOffset();
94+
editor.getCaretModel().moveToOffset(currentPosition - 1);
95+
} else if (smartEnterSetting.equals(SmartEnterResult.INSERT_CODE) || smartEnterSetting.equals(SmartEnterResult.INSERT_TEMPLATE)) {
8296
document.insertString(context.getTailOffset(), Character.toString(OPEN_BRACKET));
8397
final int currentPosition = context.getTailOffset();
8498
document.insertString(currentPosition, myInfo.getCallPattern());
8599
document.insertString(context.getTailOffset(), Character.toString(CLOSING_BRACKET));
86100
final int endOffset = getFirstArgumentRange(myInfo).getEndOffset() + currentPosition;
87101
editor.getSelectionModel().setSelection(currentPosition, endOffset);
88102
editor.getCaretModel().moveToOffset(endOffset);
89-
} else {
90-
document.insertString(context.getTailOffset(), " ");
91-
editor.getCaretModel().moveToOffset(context.getTailOffset());
92-
}
93103

94-
}
104+
if (smartEnterSetting.equals(SmartEnterResult.INSERT_TEMPLATE)) {
105+
106+
PsiDocumentManager.getInstance(context.getProject()).commitDocument(context.getDocument());
107+
final PsiElement headOfFunction = PsiTreeUtil.findElementOfClassAtRange(context.getFile(), context.getStartOffset(), context.getTailOffset(), PsiElement.class);
108+
final TemplateBuilderFactory factory = TemplateBuilderFactoryImpl.getInstance();
109+
final TemplateBuilderImpl builder = (TemplateBuilderImpl) factory.createTemplateBuilder(headOfFunction);
110+
if (headOfFunction instanceof FunctionCall) {
111+
final PsiElement[] children = headOfFunction.getChildren();
112+
for (int i = 1; i < children.length; i++) {
113+
final PsiElement child = children[i];
114+
115+
builder.replaceElement(child, new Expression() {
116+
@Nullable
117+
@Override
118+
public Result calculateResult(ExpressionContext context) {
119+
return new TextResult(child.getText());
120+
}
121+
122+
@Nullable
123+
@Override
124+
public Result calculateQuickResult(ExpressionContext context) {
125+
return new TextResult(child.getText());
126+
}
127+
128+
@Nullable
129+
@Override
130+
public LookupElement[] calculateLookupItems(ExpressionContext context) {
131+
return LookupElement.EMPTY_ARRAY;
132+
}
133+
});
134+
}
135+
Template template = builder.buildInlineTemplate();
136+
TemplateManager.getInstance(context.getProject()).startTemplate(context.getEditor(), template);
95137

96-
if (completionChar == ' ') {
97-
context.setAddCompletionChar(true);
138+
}
139+
140+
}
141+
}
142+
} else {
143+
document.insertString(context.getTailOffset(), " ");
144+
editor.getCaretModel().moveToOffset(context.getTailOffset());
98145
}
99146

147+
}
148+
149+
if (completionChar == ' ') {
150+
context.setAddCompletionChar(true);
151+
}
152+
100153
final Project project = context.getProject();
101154
PsiDocumentManager.getInstance(project).commitDocument(document);
102155
}

src/de/halirutan/mathematica/parsing/psi/impl/MathematicaSymbolFactory.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,26 @@
2222
package de.halirutan.mathematica.parsing.psi.impl;
2323

2424
import com.intellij.openapi.project.Project;
25+
import com.intellij.psi.PsiElement;
2526
import com.intellij.psi.PsiFileFactory;
2627
import de.halirutan.mathematica.filetypes.MathematicaFileType;
2728
import de.halirutan.mathematica.parsing.psi.api.Symbol;
2829

2930
/**
3031
* @author patrick (5/21/13)
3132
*/
32-
public class MathematicaSymbolFactory {
33+
class MathematicaSymbolFactory {
3334
public static Symbol createSymbol(Project project, String name) {
3435
final MathematicaPsiFileImpl file = createFile(project, name);
3536
return (Symbol) file.getFirstChild();
3637
}
3738

39+
public static PsiElement createExpression(Project project, String name) {
40+
final MathematicaPsiFileImpl file = createFile(project, name);
41+
return file.getFirstChild();
42+
}
43+
44+
3845
private static MathematicaPsiFileImpl createFile(Project project, String symbolName) {
3946
String fileName = "dummy.m";
4047
final PsiFileFactory psiFileFactory = PsiFileFactory.getInstance(project);

src/de/halirutan/mathematica/MathematicaSettings.java renamed to src/de/halirutan/mathematica/settings/MathematicaSettings.java

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
* THE SOFTWARE.
2020
*/
2121

22-
package de.halirutan.mathematica;/*
22+
package de.halirutan.mathematica.settings;/*
2323
* Copyright (c) 2016 Patrick Scheibe
2424
* Permission is hereby granted, free of charge, to any person obtaining a copy
2525
* of this software and associated documentation files (the "Software"), to deal
@@ -50,16 +50,18 @@
5050
/**
5151
* @author patrick (01.12.16).
5252
*/
53+
@SuppressWarnings({"InstanceVariableNamingConvention", "WeakerAccess", "InstanceMethodNamingConvention"})
5354
@State(name = "MathematicaSettings", storages = @Storage("other.xml"))
5455
public class MathematicaSettings implements PersistentStateComponent<MathematicaSettings> {
5556

5657
public enum SmartEnterResult {
5758
INSERT_BRACES,
58-
INSERT_CALL_PATTERN
59+
INSERT_CODE,
60+
INSERT_TEMPLATE
5961
}
6062

61-
public SmartEnterResult mySmartEnterResult = SmartEnterResult.INSERT_CALL_PATTERN;
62-
public boolean mySortEntriesLexicographically = false;
63+
public SmartEnterResult smartEnterResult = SmartEnterResult.INSERT_TEMPLATE;
64+
public boolean sortCompletionEntriesLexicographically = false;
6365

6466
public static MathematicaSettings getInstance() {
6567
return ServiceManager.getService(MathematicaSettings.class);
@@ -75,4 +77,41 @@ public MathematicaSettings getState() {
7577
public void loadState(MathematicaSettings state) {
7678
XmlSerializerUtil.copyBean(state, this);
7779
}
80+
81+
@Override
82+
public boolean equals(Object obj) {
83+
if (this == obj) {
84+
return true;
85+
}
86+
if (obj == null || getClass() != obj.getClass()) {
87+
return false;
88+
}
89+
90+
final MathematicaSettings settings = (MathematicaSettings) obj;
91+
if(smartEnterResult != settings.smartEnterResult) return false;
92+
return sortCompletionEntriesLexicographically == settings.sortCompletionEntriesLexicographically;
93+
}
94+
95+
@Override
96+
public int hashCode() {
97+
int result = (smartEnterResult.ordinal());
98+
result = 29 * result + (sortCompletionEntriesLexicographically ? 1 : 0);
99+
return result;
100+
}
101+
102+
public SmartEnterResult getSmartEnterResult() {
103+
return smartEnterResult;
104+
}
105+
106+
public void setSmartEnterResult(SmartEnterResult result) {
107+
this.smartEnterResult = result;
108+
}
109+
110+
public boolean isSortCompletionEntriesLexicographically() {
111+
return sortCompletionEntriesLexicographically;
112+
}
113+
114+
public void setSortCompletionEntriesLexicographically(boolean shouldSort) {
115+
this.sortCompletionEntriesLexicographically = shouldSort;
116+
}
78117
}

src/de/halirutan/mathematica/MathematicaSettingsConfigurable.java renamed to src/de/halirutan/mathematica/settings/MathematicaSettingsConfigurable.java

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2016 Patrick Scheibe
2+
* Copyright (c) 2017 Patrick Scheibe
33
* Permission is hereby granted, free of charge, to any person obtaining a copy
44
* of this software and associated documentation files (the "Software"), to deal
55
* in the Software without restriction, including without limitation the rights
@@ -19,66 +19,63 @@
1919
* THE SOFTWARE.
2020
*/
2121

22-
package de.halirutan.mathematica;
22+
package de.halirutan.mathematica.settings;
2323

24-
import com.intellij.openapi.options.Configurable;
25-
import com.intellij.openapi.options.Configurable.NoScroll;
24+
import com.intellij.openapi.options.BaseConfigurable;
2625
import com.intellij.openapi.options.ConfigurationException;
27-
import com.intellij.openapi.options.SearchableConfigurable;
2826
import org.jetbrains.annotations.Nls;
29-
import org.jetbrains.annotations.NotNull;
3027
import org.jetbrains.annotations.Nullable;
3128

3229
import javax.swing.*;
3330

3431
/**
35-
* @author patrick (01.12.16).
32+
* @author patrick (01.01.17).
3633
*/
37-
public class MathematicaSettingsConfigurable implements SearchableConfigurable, NoScroll{
38-
private JPanel myWholePanel;
39-
private JCheckBox mySortEntries;
40-
private JComboBox mySmartEnterMethod;
34+
public class MathematicaSettingsConfigurable extends BaseConfigurable {
4135

42-
@NotNull
43-
@Override
44-
public String getId() {
45-
return null;
46-
}
36+
private SettingsUI settingsUI;
4737

4838
@Nls
4939
@Override
5040
public String getDisplayName() {
51-
return null;
41+
return "Mathematica";
5242
}
5343

5444
@Nullable
5545
@Override
5646
public String getHelpTopic() {
57-
return null;
47+
return "xpath.settings";
5848
}
5949

6050
@Nullable
6151
@Override
6252
public JComponent createComponent() {
63-
return null;
64-
}
65-
66-
@Override
67-
public boolean isModified() {
68-
return false;
53+
settingsUI = new SettingsUI();
54+
settingsUI.setSettings(MathematicaSettings.getInstance());
55+
return settingsUI;
6956
}
7057

7158
@Override
7259
public void apply() throws ConfigurationException {
60+
if (settingsUI != null) {
61+
final MathematicaSettings instance = MathematicaSettings.getInstance();
62+
instance.loadState(settingsUI.getSettings());
63+
}
7364

7465
}
7566

7667
@Override
7768
public void reset() {
78-
69+
if (settingsUI != null) {
70+
settingsUI.setSettings(MathematicaSettings.getInstance());
71+
}
7972
}
8073

81-
private void createUIComponents() {
82-
// TODO: place custom component creation code here
74+
@Override
75+
public boolean isModified() {
76+
if (settingsUI != null) {
77+
return !settingsUI.getSettings().equals(MathematicaSettings.getInstance());
78+
}
79+
return false;
8380
}
8481
}

0 commit comments

Comments
 (0)