mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -672,12 +672,13 @@ public class BuildManager implements Disposable {
|
||||
return null;
|
||||
}
|
||||
|
||||
final DelegateFuture<?> _future = new DelegateFuture<>();
|
||||
final DelegateFuture<BuilderMessageHandler> _future = new DelegateFuture<>();
|
||||
// by using the same queue that processes events we ensure that
|
||||
// the build will be aware of all events that have happened before this request
|
||||
runCommand(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
final Pair<RequestFuture<PreloadedProcessMessageHandler>, OSProcessHandler> preloaded = takePreloadedProcess(projectPath);
|
||||
final RequestFuture<PreloadedProcessMessageHandler> preloadedFuture = preloaded != null? preloaded.first : null;
|
||||
final boolean usingPreloadedProcess = preloadedFuture != null;
|
||||
@@ -692,7 +693,8 @@ public class BuildManager implements Disposable {
|
||||
sessionId = UUID.randomUUID();
|
||||
}
|
||||
|
||||
final RequestFuture<? extends BuilderMessageHandler> future = usingPreloadedProcess? preloadedFuture : new RequestFuture<BuilderMessageHandler>(handler, sessionId, new CancelBuildSessionAction<BuilderMessageHandler>());
|
||||
final RequestFuture<? extends BuilderMessageHandler> future = usingPreloadedProcess? preloadedFuture : new RequestFuture<>(handler, sessionId, new CancelBuildSessionAction<BuilderMessageHandler>());
|
||||
_future.setDelegate(future);
|
||||
|
||||
if (!usingPreloadedProcess && (future.isCancelled() || project.isDisposed())) {
|
||||
// in case of preloaded process the process was already running, so the handler will be notified upon process termination
|
||||
@@ -739,7 +741,7 @@ public class BuildManager implements Disposable {
|
||||
}
|
||||
|
||||
try {
|
||||
Future<?> buildFuture = projectTaskQueue.submit(new Runnable() {
|
||||
projectTaskQueue.submit(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Throwable execFailure = null;
|
||||
@@ -776,7 +778,7 @@ public class BuildManager implements Disposable {
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Throwable e) {
|
||||
catch(Throwable e) {
|
||||
LOG.info(e);
|
||||
}
|
||||
}
|
||||
@@ -841,9 +843,6 @@ public class BuildManager implements Disposable {
|
||||
}
|
||||
}
|
||||
});
|
||||
TaskFutureAdapter adapter = new TaskFutureAdapter<>(buildFuture);
|
||||
boolean set = _future.setDelegate(adapter);
|
||||
assert set;
|
||||
}
|
||||
catch (Throwable e) {
|
||||
handleProcessExecutionFailure(sessionId, e);
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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 org.jetbrains.jps.api;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.concurrent.*;
|
||||
|
||||
/**
|
||||
* Makes TaskFuture from the supplied Future
|
||||
*/
|
||||
public class TaskFutureAdapter<T> implements TaskFuture<T> {
|
||||
@NotNull private final Future<T> myFuture;
|
||||
|
||||
public TaskFutureAdapter(@NotNull Future<T> future) {
|
||||
myFuture = future;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void waitFor() {
|
||||
try {
|
||||
get();
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
catch (ExecutionException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
catch (CancellationException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean waitFor(long timeout, TimeUnit unit) {
|
||||
try {
|
||||
get(timeout, unit);
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
catch (ExecutionException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
catch (TimeoutException ignored) {
|
||||
}
|
||||
catch (CancellationException ignored) {
|
||||
}
|
||||
return isDone();
|
||||
}
|
||||
|
||||
// delegates
|
||||
@Override
|
||||
public boolean cancel(boolean mayInterruptIfRunning) {
|
||||
return myFuture.cancel(mayInterruptIfRunning);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return myFuture.isCancelled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDone() {
|
||||
return myFuture.isDone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T get() throws InterruptedException, ExecutionException {
|
||||
return myFuture.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T get(long timeout, @NotNull TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
|
||||
return myFuture.get(timeout, unit);
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,6 @@ import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.io.FileUtilRt;
|
||||
import com.intellij.util.ArrayUtilRt;
|
||||
import com.intellij.util.Restarter;
|
||||
import com.intellij.util.SystemProperties;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
|
||||
@@ -81,9 +80,7 @@ public class Main {
|
||||
System.exit(NO_GRAPHICS);
|
||||
}
|
||||
|
||||
//this property is temporary and will be removed when IntelliJ platform really migrates to Java 8
|
||||
boolean checkVersion = !SystemProperties.getBooleanProperty("idea.no.java.version.check", false);
|
||||
if (checkVersion && !SystemInfo.isJavaVersionAtLeast("1.8")) {
|
||||
if (!SystemInfo.isJavaVersionAtLeast("1.8")) {
|
||||
showMessage("Unsupported Java Version",
|
||||
"Cannot start under Java " + SystemInfo.JAVA_RUNTIME_VERSION + ": Java 1.8 or later is required.", true);
|
||||
System.exit(UNSUPPORTED_JAVA_VERSION);
|
||||
|
||||
@@ -883,6 +883,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
|
||||
isReleased = true;
|
||||
clearSettingsCache();
|
||||
mySizeAdjustmentStrategy.cancelAllRequests();
|
||||
|
||||
myFoldingModel.dispose();
|
||||
mySoftWrapModel.release();
|
||||
|
||||
+4
@@ -103,6 +103,10 @@ class EditorSizeAdjustmentStrategy {
|
||||
scheduleSizeUpdate(editor);
|
||||
return result;
|
||||
}
|
||||
|
||||
void cancelAllRequests() {
|
||||
myAlarm.cancelAllRequests();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes old timings.
|
||||
|
||||
@@ -252,6 +252,16 @@ public class ContainerUtilTest extends TestCase {
|
||||
assertSame(EmptyIterator.getInstance(), iterator);
|
||||
}
|
||||
|
||||
public void testIdenticalItemsInLockFreeCOW() {
|
||||
List<String> list = ContainerUtil.createLockFreeCopyOnWriteList(Arrays.asList("a", "b"));
|
||||
list.add("a");
|
||||
assertEquals(3, list.size());
|
||||
list.remove("a");
|
||||
assertEquals(2, list.size());
|
||||
list.remove("a");
|
||||
assertEquals(1, list.size());
|
||||
}
|
||||
|
||||
public void testLockFreeCOWIteratorRemove() {
|
||||
List<String> seq = Arrays.asList("0", "1", "2", "3", "4");
|
||||
LockFreeCopyOnWriteArrayList<String> my = (LockFreeCopyOnWriteArrayList<String>)ContainerUtil.createLockFreeCopyOnWriteList(seq);
|
||||
|
||||
Binary file not shown.
@@ -3,6 +3,7 @@ package org.jetbrains.plugins.terminal;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.wm.impl.IdeBackgroundUtil;
|
||||
import com.intellij.ui.SearchTextField;
|
||||
import com.intellij.ui.components.JBScrollBar;
|
||||
import com.jediterm.terminal.TerminalStarter;
|
||||
import com.jediterm.terminal.TtyConnector;
|
||||
@@ -14,7 +15,9 @@ import com.jediterm.terminal.ui.settings.SettingsProvider;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.DocumentListener;
|
||||
import java.awt.*;
|
||||
import java.awt.event.KeyListener;
|
||||
|
||||
public class JBTerminalWidget extends JediTermWidget implements Disposable{
|
||||
|
||||
@@ -53,4 +56,31 @@ public class JBTerminalWidget extends JediTermWidget implements Disposable{
|
||||
@Override
|
||||
public void dispose() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SearchComponent createSearchComponent() {
|
||||
return new SearchComponent() {
|
||||
private final SearchTextField myTextField = new SearchTextField(false);
|
||||
@Override
|
||||
public String getText() {
|
||||
return myTextField.getText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent getComponent() {
|
||||
myTextField.setOpaque(false);
|
||||
return myTextField;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDocumentChangeListener(DocumentListener listener) {
|
||||
myTextField.addDocumentListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addKeyListener(KeyListener listener) {
|
||||
myTextField.addKeyboardListener(listener);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.intellij.codeInsight.generation.PsiGenerationInfo;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.actionSystem.Presentation;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -129,7 +130,10 @@ public class GenerateMainAction extends AnAction {
|
||||
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
e.getPresentation().setVisible(isActionEnabled(e));
|
||||
boolean enabled = isActionEnabled(e);
|
||||
Presentation presentation = e.getPresentation();
|
||||
presentation.setEnabled(enabled);
|
||||
presentation.setVisible(enabled);
|
||||
}
|
||||
|
||||
private static boolean isActionEnabled(final AnActionEvent e) {
|
||||
|
||||
+1
-1
@@ -281,7 +281,7 @@ public final class PropertyInspectorTable extends Table implements DataProvider{
|
||||
return myEditor;
|
||||
}
|
||||
else if (PlatformDataKeys.FILE_EDITOR.is(dataId)) {
|
||||
GuiEditor designer = DesignerToolWindowManager.getInstance(myProject).getActiveFormEditor();
|
||||
GuiEditor designer = myProject.isDisposed() ? null : DesignerToolWindowManager.getInstance(myProject).getActiveFormEditor();
|
||||
return designer == null ? null : designer.getEditor();
|
||||
}
|
||||
else if (PlatformDataKeys.HELP_ID.is(dataId)) {
|
||||
|
||||
+45
-43
@@ -1,54 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.uiDesigner.propertyInspector.editors.string.NewKeyDialog">
|
||||
<grid id="1eff1" binding="myPanel" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<grid id="49180" binding="myPanel" layout-manager="BorderLayout" hgap="0" vgap="0">
|
||||
<constraints>
|
||||
<xy x="59" y="38" width="219" height="49"/>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0"/>
|
||||
<xy x="59" y="38" width="232" height="65"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="9981" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<xy x="2" y="5" width="55" height="14"/>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<labelFor value="89f45"/>
|
||||
<text resource-bundle="messages/UIDesignerBundle" key="key.chooser.new.property.name"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="89f45" class="javax.swing.JTextField" binding="myKeyNameEdit">
|
||||
<constraints>
|
||||
<xy x="67" y="2" width="150" height="20"/>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<grid id="772be" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints border-constraint="North"/>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="f12ed" class="javax.swing.JTextField" binding="myKeyValueEdit">
|
||||
<constraints>
|
||||
<xy x="67" y="27" width="150" height="20"/>
|
||||
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties>
|
||||
<columns value="50"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="23f8d" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<xy x="2" y="30" width="55" height="14"/>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<labelFor value="f12ed"/>
|
||||
<text resource-bundle="messages/UIDesignerBundle" key="key.chooser.new.property.value"/>
|
||||
</properties>
|
||||
</component>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="ab054" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<labelFor value="89f45"/>
|
||||
<text resource-bundle="messages/UIDesignerBundle" key="key.chooser.new.property.name"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="5ff32" class="javax.swing.JTextField" binding="myKeyNameEdit">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="19be8" class="javax.swing.JTextField" binding="myKeyValueEdit">
|
||||
<constraints>
|
||||
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties>
|
||||
<columns value="50"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="49d01" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<labelFor value="f12ed"/>
|
||||
<text resource-bundle="messages/UIDesignerBundle" key="key.chooser.new.property.value"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
|
||||
+6
@@ -17,6 +17,7 @@ package com.intellij.uiDesigner.propertyInspector.editors.string;
|
||||
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.uiDesigner.UIDesignerBundle;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.DocumentListener;
|
||||
@@ -63,6 +64,11 @@ public class NewKeyDialog extends DialogWrapper {
|
||||
return myPanel;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected String getDimensionServiceKey() {
|
||||
return getClass().getName();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return myKeyNameEdit.getText();
|
||||
}
|
||||
|
||||
@@ -235,10 +235,17 @@ public class StudyUtils {
|
||||
if (course == null) {
|
||||
return null;
|
||||
}
|
||||
final VirtualFile taskDir = file.getParent();
|
||||
VirtualFile taskDir = file.getParent();
|
||||
if (taskDir == null) {
|
||||
return null;
|
||||
}
|
||||
//need this because of multi-module generation
|
||||
if ("src".equals(taskDir.getName())) {
|
||||
taskDir = taskDir.getParent();
|
||||
if (taskDir == null) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
final String taskDirName = taskDir.getName();
|
||||
if (taskDirName.contains(EduNames.TASK)) {
|
||||
final VirtualFile lessonDir = taskDir.getParent();
|
||||
@@ -392,6 +399,12 @@ public class StudyUtils {
|
||||
}
|
||||
if (taskDirectory != null) {
|
||||
VirtualFile taskTextFile = taskDirectory.findChild(EduNames.TASK_HTML);
|
||||
if (taskTextFile == null) {
|
||||
VirtualFile srcDir = taskDirectory.findChild("src");
|
||||
if (srcDir != null) {
|
||||
taskTextFile = srcDir.findChild(EduNames.TASK_HTML);
|
||||
}
|
||||
}
|
||||
if (taskTextFile != null) {
|
||||
try {
|
||||
return FileUtil.loadTextAndClose(taskTextFile.getInputStream());
|
||||
|
||||
+2
-1
@@ -92,7 +92,8 @@ abstract public class StudyTaskNavigationAction extends DumbAwareAction {
|
||||
for (Map.Entry<String, TaskFile> entry : nextTaskFiles.entrySet()) {
|
||||
String name = entry.getKey();
|
||||
TaskFile taskFile = entry.getValue();
|
||||
VirtualFile vf = taskDir.findChild(name);
|
||||
VirtualFile srcDir = taskDir.findChild("src");
|
||||
VirtualFile vf = srcDir == null ? taskDir.findChild(name) : srcDir.findChild(name);
|
||||
if (vf != null) {
|
||||
FileEditorManager.getInstance(project).openFile(vf, true);
|
||||
if (!taskFile.getAnswerPlaceholders().isEmpty()) {
|
||||
|
||||
+3
-3
@@ -46,10 +46,10 @@ import java.util.Map;
|
||||
public class StudyProjectGenerator {
|
||||
private static final Logger LOG = Logger.getInstance(StudyProjectGenerator.class.getName());
|
||||
private final List<SettingsListener> myListeners = ContainerUtil.newArrayList();
|
||||
private static final File ourCoursesDir = new File(PathManager.getConfigPath(), "courses");
|
||||
protected static final File ourCoursesDir = new File(PathManager.getConfigPath(), "courses");
|
||||
private static final String CACHE_NAME = "courseNames.txt";
|
||||
private List<CourseInfo> myCourses = new ArrayList<>();
|
||||
private CourseInfo mySelectedCourseInfo;
|
||||
protected CourseInfo mySelectedCourseInfo;
|
||||
private static final String COURSE_NAME_ATTRIBUTE = "name";
|
||||
private static final String COURSE_DESCRIPTION = "description";
|
||||
public static final String AUTHOR_ATTRIBUTE = "authors";
|
||||
@@ -82,7 +82,7 @@ public class StudyProjectGenerator {
|
||||
})));
|
||||
}
|
||||
|
||||
private Course getCourse() {
|
||||
protected Course getCourse() {
|
||||
Reader reader = null;
|
||||
try {
|
||||
final File courseFile = new File(new File(ourCoursesDir, mySelectedCourseInfo.getName()), EduNames.COURSE_META_FILE);
|
||||
|
||||
+11
-13
@@ -41,7 +41,7 @@ public class StudyDirectoryNode extends PsiDirectoryNode {
|
||||
String valueName = myValue.getName();
|
||||
StudyTaskManager studyTaskManager = StudyTaskManager.getInstance(myProject);
|
||||
Course course = studyTaskManager.getCourse();
|
||||
if (course == null || valueName == null) {
|
||||
if (course == null) {
|
||||
return;
|
||||
}
|
||||
if (valueName.equals(myProject.getName())) {
|
||||
@@ -50,19 +50,17 @@ public class StudyDirectoryNode extends PsiDirectoryNode {
|
||||
data.addText(course.getName(), new SimpleTextAttributes(SimpleTextAttributes.STYLE_PLAIN, JBColor.BLACK));
|
||||
}
|
||||
else if (valueName.contains(EduNames.TASK)) {
|
||||
TaskFile file = null;
|
||||
for (PsiElement child : myValue.getChildren()) {
|
||||
VirtualFile virtualFile = child instanceof PsiDirectory ? ((PsiDirectory)child).getVirtualFile() :
|
||||
child.getContainingFile().getVirtualFile();
|
||||
file = StudyUtils.getTaskFile(myProject, virtualFile);
|
||||
if (file != null) {
|
||||
break;
|
||||
VirtualFile taskVirtualFile = myValue.getVirtualFile();
|
||||
VirtualFile lessonVirtualFile = taskVirtualFile.getParent();
|
||||
if (lessonVirtualFile != null) {
|
||||
Lesson lesson = course.getLesson(lessonVirtualFile.getName());
|
||||
if (lesson != null) {
|
||||
Task task = lesson.getTask(taskVirtualFile.getName());
|
||||
if (task != null) {
|
||||
setStudyAttributes(task, data, task.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (file != null) {
|
||||
Task task = file.getTask();
|
||||
setStudyAttributes(task, data, task.getName());
|
||||
}
|
||||
}
|
||||
else if (valueName.contains(EduNames.LESSON)) {
|
||||
int lessonIndex = Integer.parseInt(valueName.substring(EduNames.LESSON.length())) - 1;
|
||||
@@ -73,7 +71,7 @@ public class StudyDirectoryNode extends PsiDirectoryNode {
|
||||
else if (valueName.contains(EduNames.SANDBOX_DIR)) {
|
||||
if (myValue.getParent() != null) {
|
||||
final String parentName = myValue.getParent().getName();
|
||||
if (parentName!= null && !parentName.contains(EduNames.SANDBOX_DIR)) {
|
||||
if (!parentName.contains(EduNames.SANDBOX_DIR)) {
|
||||
data.setPresentableText(EduNames.SANDBOX_DIR);
|
||||
data.setIcon(InteractiveLearningIcons.Sandbox);
|
||||
}
|
||||
|
||||
@@ -4,61 +4,19 @@
|
||||
<variable name="method" expression="pyFunctionName()" defaultValue="" alwaysStopAt="false" />
|
||||
<variable name="end" expression="" defaultValue="" alwaysStopAt="true" />
|
||||
<context>
|
||||
<option name="HTML_TEXT" value="false" />
|
||||
<option name="HTML" value="false" />
|
||||
<option name="XSL_TEXT" value="false" />
|
||||
<option name="XML" value="false" />
|
||||
<option name="Python" value="true" />
|
||||
<option name="Django" value="false" />
|
||||
<option name="CSS_PROPERTY_VALUE" value="false" />
|
||||
<option name="CSS_DECLARATION_BLOCK" value="false" />
|
||||
<option name="CSS_RULESET_LIST" value="false" />
|
||||
<option name="CSS" value="false" />
|
||||
<option name="JAVA_SCRIPT" value="false" />
|
||||
<option name="TypeScript" value="false" />
|
||||
<option name="SQL" value="false" />
|
||||
<option name="CoffeeScript" value="false" />
|
||||
<option name="OTHER" value="false" />
|
||||
<option name="Python_Class" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="main" value="if __name__ == '__main__': $END$" description="if __name__ == '__main__'" toReformat="false" toShortenFQNames="true">
|
||||
<context>
|
||||
<option name="HTML_TEXT" value="false" />
|
||||
<option name="HTML" value="false" />
|
||||
<option name="XSL_TEXT" value="false" />
|
||||
<option name="XML" value="false" />
|
||||
<option name="Python" value="true" />
|
||||
<option name="Django" value="false" />
|
||||
<option name="CSS_PROPERTY_VALUE" value="false" />
|
||||
<option name="CSS_DECLARATION_BLOCK" value="false" />
|
||||
<option name="CSS_RULESET_LIST" value="false" />
|
||||
<option name="CSS" value="false" />
|
||||
<option name="JAVA_SCRIPT" value="false" />
|
||||
<option name="TypeScript" value="false" />
|
||||
<option name="SQL" value="false" />
|
||||
<option name="CoffeeScript" value="false" />
|
||||
<option name="OTHER" value="false" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="iter" value="for $VAR$ in $ITERABLE$: $END$" description="Iterate (for ... in ...)" toReformat="false" toShortenFQNames="true">
|
||||
<variable name="ITERABLE" expression="pyIterableVariable()" defaultValue="" alwaysStopAt="true" />
|
||||
<variable name="VAR" expression="collectionElementName(ITERABLE)" defaultValue="" alwaysStopAt="true" />
|
||||
<context>
|
||||
<option name="HTML_TEXT" value="false" />
|
||||
<option name="HTML" value="false" />
|
||||
<option name="XSL_TEXT" value="false" />
|
||||
<option name="XML" value="false" />
|
||||
<option name="Python" value="true" />
|
||||
<option name="Django" value="false" />
|
||||
<option name="CSS_PROPERTY_VALUE" value="false" />
|
||||
<option name="CSS_DECLARATION_BLOCK" value="false" />
|
||||
<option name="CSS_RULESET_LIST" value="false" />
|
||||
<option name="CSS" value="false" />
|
||||
<option name="JAVA_SCRIPT" value="false" />
|
||||
<option name="TypeScript" value="false" />
|
||||
<option name="SQL" value="false" />
|
||||
<option name="CoffeeScript" value="false" />
|
||||
<option name="OTHER" value="false" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="itere" value="for $INDEX$, $VAR$ in enumerate($ITERABLE$): $END$" description="Iterate (for ... in enumerate)" toReformat="false" toShortenFQNames="true">
|
||||
@@ -66,21 +24,7 @@
|
||||
<variable name="VAR" expression="collectionElementName(ITERABLE)" defaultValue="" alwaysStopAt="true" />
|
||||
<variable name="INDEX" expression="" defaultValue=""i"" alwaysStopAt="true" />
|
||||
<context>
|
||||
<option name="HTML_TEXT" value="false" />
|
||||
<option name="HTML" value="false" />
|
||||
<option name="XSL_TEXT" value="false" />
|
||||
<option name="XML" value="false" />
|
||||
<option name="Python" value="true" />
|
||||
<option name="Django" value="false" />
|
||||
<option name="CSS_PROPERTY_VALUE" value="false" />
|
||||
<option name="CSS_DECLARATION_BLOCK" value="false" />
|
||||
<option name="CSS_RULESET_LIST" value="false" />
|
||||
<option name="CSS" value="false" />
|
||||
<option name="JAVA_SCRIPT" value="false" />
|
||||
<option name="TypeScript" value="false" />
|
||||
<option name="SQL" value="false" />
|
||||
<option name="CoffeeScript" value="false" />
|
||||
<option name="OTHER" value="false" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="compl" value="[$VAR_EXPR$ for $VAR$ in $ITERABLE$]" description="List comprehension" toReformat="false" toShortenFQNames="true">
|
||||
@@ -88,21 +32,7 @@
|
||||
<variable name="VAR" expression="collectionElementName(ITERABLE)" defaultValue="" alwaysStopAt="true" />
|
||||
<variable name="VAR_EXPR" expression="" defaultValue="VAR" alwaysStopAt="true" />
|
||||
<context>
|
||||
<option name="HTML_TEXT" value="false" />
|
||||
<option name="HTML" value="false" />
|
||||
<option name="XSL_TEXT" value="false" />
|
||||
<option name="XML" value="false" />
|
||||
<option name="Python" value="true" />
|
||||
<option name="Django" value="false" />
|
||||
<option name="CSS_PROPERTY_VALUE" value="false" />
|
||||
<option name="CSS_DECLARATION_BLOCK" value="false" />
|
||||
<option name="CSS_RULESET_LIST" value="false" />
|
||||
<option name="CSS" value="false" />
|
||||
<option name="JAVA_SCRIPT" value="false" />
|
||||
<option name="TypeScript" value="false" />
|
||||
<option name="SQL" value="false" />
|
||||
<option name="CoffeeScript" value="false" />
|
||||
<option name="OTHER" value="false" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="compli" value="[$VAR_EXPR$ for $VAR$ in $ITERABLE$ if $VAR_EXPR_IF$]" description="List comprehension with 'if'" toReformat="false" toShortenFQNames="true">
|
||||
@@ -111,21 +41,7 @@
|
||||
<variable name="VAR_EXPR" expression="" defaultValue="VAR" alwaysStopAt="true" />
|
||||
<variable name="VAR_EXPR_IF" expression="" defaultValue="VAR" alwaysStopAt="true" />
|
||||
<context>
|
||||
<option name="HTML_TEXT" value="false" />
|
||||
<option name="HTML" value="false" />
|
||||
<option name="XSL_TEXT" value="false" />
|
||||
<option name="XML" value="false" />
|
||||
<option name="Python" value="true" />
|
||||
<option name="Django" value="false" />
|
||||
<option name="CSS_PROPERTY_VALUE" value="false" />
|
||||
<option name="CSS_DECLARATION_BLOCK" value="false" />
|
||||
<option name="CSS_RULESET_LIST" value="false" />
|
||||
<option name="CSS" value="false" />
|
||||
<option name="JAVA_SCRIPT" value="false" />
|
||||
<option name="TypeScript" value="false" />
|
||||
<option name="SQL" value="false" />
|
||||
<option name="CoffeeScript" value="false" />
|
||||
<option name="OTHER" value="false" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="compg" value="($VAR_EXPR$ for $VAR$ in $ITERABLE$)" description="Generator comprehension" toReformat="false" toShortenFQNames="true">
|
||||
@@ -133,21 +49,7 @@
|
||||
<variable name="VAR" expression="collectionElementName(ITERABLE)" defaultValue="" alwaysStopAt="true" />
|
||||
<variable name="VAR_EXPR" expression="" defaultValue="VAR" alwaysStopAt="true" />
|
||||
<context>
|
||||
<option name="HTML_TEXT" value="false" />
|
||||
<option name="HTML" value="false" />
|
||||
<option name="XSL_TEXT" value="false" />
|
||||
<option name="XML" value="false" />
|
||||
<option name="Python" value="true" />
|
||||
<option name="Django" value="false" />
|
||||
<option name="CSS_PROPERTY_VALUE" value="false" />
|
||||
<option name="CSS_DECLARATION_BLOCK" value="false" />
|
||||
<option name="CSS_RULESET_LIST" value="false" />
|
||||
<option name="CSS" value="false" />
|
||||
<option name="JAVA_SCRIPT" value="false" />
|
||||
<option name="TypeScript" value="false" />
|
||||
<option name="SQL" value="false" />
|
||||
<option name="CoffeeScript" value="false" />
|
||||
<option name="OTHER" value="false" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="compgi" value="($VAR_EXPR$ for $VAR$ in $ITERABLE$ if $VAR_EXPR_IF$)" description="Generator comprehension with 'if'" toReformat="false" toShortenFQNames="true">
|
||||
@@ -156,21 +58,7 @@
|
||||
<variable name="VAR_EXPR" expression="" defaultValue="VAR" alwaysStopAt="true" />
|
||||
<variable name="VAR_EXPR_IF" expression="" defaultValue="VAR" alwaysStopAt="true" />
|
||||
<context>
|
||||
<option name="HTML_TEXT" value="false" />
|
||||
<option name="HTML" value="false" />
|
||||
<option name="XSL_TEXT" value="false" />
|
||||
<option name="XML" value="false" />
|
||||
<option name="Python" value="true" />
|
||||
<option name="Django" value="false" />
|
||||
<option name="CSS_PROPERTY_VALUE" value="false" />
|
||||
<option name="CSS_DECLARATION_BLOCK" value="false" />
|
||||
<option name="CSS_RULESET_LIST" value="false" />
|
||||
<option name="CSS" value="false" />
|
||||
<option name="JAVA_SCRIPT" value="false" />
|
||||
<option name="TypeScript" value="false" />
|
||||
<option name="SQL" value="false" />
|
||||
<option name="CoffeeScript" value="false" />
|
||||
<option name="OTHER" value="false" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="comps" value="{$VAR_EXPR$ for $VAR$ in $ITERABLE$}" description="Set comprehension" toReformat="false" toShortenFQNames="true">
|
||||
@@ -178,21 +66,7 @@
|
||||
<variable name="VAR" expression="collectionElementName(ITERABLE)" defaultValue="" alwaysStopAt="true" />
|
||||
<variable name="VAR_EXPR" expression="" defaultValue="VAR" alwaysStopAt="true" />
|
||||
<context>
|
||||
<option name="HTML_TEXT" value="false" />
|
||||
<option name="HTML" value="false" />
|
||||
<option name="XSL_TEXT" value="false" />
|
||||
<option name="XML" value="false" />
|
||||
<option name="Python" value="true" />
|
||||
<option name="Django" value="false" />
|
||||
<option name="CSS_PROPERTY_VALUE" value="false" />
|
||||
<option name="CSS_DECLARATION_BLOCK" value="false" />
|
||||
<option name="CSS_RULESET_LIST" value="false" />
|
||||
<option name="CSS" value="false" />
|
||||
<option name="JAVA_SCRIPT" value="false" />
|
||||
<option name="TypeScript" value="false" />
|
||||
<option name="SQL" value="false" />
|
||||
<option name="CoffeeScript" value="false" />
|
||||
<option name="OTHER" value="false" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="compsi" value="{$VAR_EXPR$ for $VAR$ in $ITERABLE$ if $VAR_EXPR_IF$}" description="Set comprehension with 'if'" toReformat="false" toShortenFQNames="true">
|
||||
@@ -201,21 +75,7 @@
|
||||
<variable name="VAR_EXPR" expression="" defaultValue="VAR" alwaysStopAt="true" />
|
||||
<variable name="VAR_EXPR_IF" expression="" defaultValue="VAR" alwaysStopAt="true" />
|
||||
<context>
|
||||
<option name="HTML_TEXT" value="false" />
|
||||
<option name="HTML" value="false" />
|
||||
<option name="XSL_TEXT" value="false" />
|
||||
<option name="XML" value="false" />
|
||||
<option name="Python" value="true" />
|
||||
<option name="Django" value="false" />
|
||||
<option name="CSS_PROPERTY_VALUE" value="false" />
|
||||
<option name="CSS_DECLARATION_BLOCK" value="false" />
|
||||
<option name="CSS_RULESET_LIST" value="false" />
|
||||
<option name="CSS" value="false" />
|
||||
<option name="JAVA_SCRIPT" value="false" />
|
||||
<option name="TypeScript" value="false" />
|
||||
<option name="SQL" value="false" />
|
||||
<option name="CoffeeScript" value="false" />
|
||||
<option name="OTHER" value="false" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="compd" value="{$KEY_EXPR$: $VAL_EXPR$ for $VAR$ in $ITERABLE$}" description="Dict comprehension" toReformat="false" toShortenFQNames="true">
|
||||
@@ -224,21 +84,7 @@
|
||||
<variable name="KEY_EXPR" expression="" defaultValue="VAR" alwaysStopAt="true" />
|
||||
<variable name="VAL_EXPR" expression="" defaultValue="VAR" alwaysStopAt="true" />
|
||||
<context>
|
||||
<option name="HTML_TEXT" value="false" />
|
||||
<option name="HTML" value="false" />
|
||||
<option name="XSL_TEXT" value="false" />
|
||||
<option name="XML" value="false" />
|
||||
<option name="Python" value="true" />
|
||||
<option name="Django" value="false" />
|
||||
<option name="CSS_PROPERTY_VALUE" value="false" />
|
||||
<option name="CSS_DECLARATION_BLOCK" value="false" />
|
||||
<option name="CSS_RULESET_LIST" value="false" />
|
||||
<option name="CSS" value="false" />
|
||||
<option name="JAVA_SCRIPT" value="false" />
|
||||
<option name="TypeScript" value="false" />
|
||||
<option name="SQL" value="false" />
|
||||
<option name="CoffeeScript" value="false" />
|
||||
<option name="OTHER" value="false" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="compdi" value="{$KEY_EXPR$: $VAL_EXPR$ for $VAR$ in $ITERABLE$ if $VAR_EXPR_IF$}" description="Dict comprehension with 'if'" toReformat="false" toShortenFQNames="true">
|
||||
@@ -248,81 +94,25 @@
|
||||
<variable name="VAL_EXPR" expression="" defaultValue="VAR" alwaysStopAt="true" />
|
||||
<variable name="VAR_EXPR_IF" expression="" defaultValue="VAR" alwaysStopAt="true" />
|
||||
<context>
|
||||
<option name="HTML_TEXT" value="false" />
|
||||
<option name="HTML" value="false" />
|
||||
<option name="XSL_TEXT" value="false" />
|
||||
<option name="XML" value="false" />
|
||||
<option name="Python" value="true" />
|
||||
<option name="Django" value="false" />
|
||||
<option name="CSS_PROPERTY_VALUE" value="false" />
|
||||
<option name="CSS_DECLARATION_BLOCK" value="false" />
|
||||
<option name="CSS_RULESET_LIST" value="false" />
|
||||
<option name="CSS" value="false" />
|
||||
<option name="JAVA_SCRIPT" value="false" />
|
||||
<option name="TypeScript" value="false" />
|
||||
<option name="SQL" value="false" />
|
||||
<option name="CoffeeScript" value="false" />
|
||||
<option name="OTHER" value="false" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="prop" value="@property def $NAME$(self): return $END$" description="Property getter" toReformat="false" toShortenFQNames="true">
|
||||
<variable name="NAME" expression="" defaultValue="" alwaysStopAt="true" />
|
||||
<context>
|
||||
<option name="HTML_TEXT" value="false" />
|
||||
<option name="HTML" value="false" />
|
||||
<option name="XSL_TEXT" value="false" />
|
||||
<option name="XML" value="false" />
|
||||
<option name="Python" value="true" />
|
||||
<option name="Django" value="false" />
|
||||
<option name="CSS_PROPERTY_VALUE" value="false" />
|
||||
<option name="CSS_DECLARATION_BLOCK" value="false" />
|
||||
<option name="CSS_RULESET_LIST" value="false" />
|
||||
<option name="CSS" value="false" />
|
||||
<option name="JAVA_SCRIPT" value="false" />
|
||||
<option name="TypeScript" value="false" />
|
||||
<option name="SQL" value="false" />
|
||||
<option name="CoffeeScript" value="false" />
|
||||
<option name="OTHER" value="false" />
|
||||
<option name="Python_Class" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="props" value="@property def $NAME$(self): return $END$ @$NAME$.setter def $NAME$(self, value): pass" description="Property getter/setter" toReformat="false" toShortenFQNames="true">
|
||||
<variable name="NAME" expression="" defaultValue="" alwaysStopAt="true" />
|
||||
<context>
|
||||
<option name="HTML_TEXT" value="false" />
|
||||
<option name="HTML" value="false" />
|
||||
<option name="XSL_TEXT" value="false" />
|
||||
<option name="XML" value="false" />
|
||||
<option name="Python" value="true" />
|
||||
<option name="Django" value="false" />
|
||||
<option name="CSS_PROPERTY_VALUE" value="false" />
|
||||
<option name="CSS_DECLARATION_BLOCK" value="false" />
|
||||
<option name="CSS_RULESET_LIST" value="false" />
|
||||
<option name="CSS" value="false" />
|
||||
<option name="JAVA_SCRIPT" value="false" />
|
||||
<option name="TypeScript" value="false" />
|
||||
<option name="SQL" value="false" />
|
||||
<option name="CoffeeScript" value="false" />
|
||||
<option name="OTHER" value="false" />
|
||||
<option name="Python_Class" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="propsd" value="@property def $NAME$(self): return $END$ @$NAME$.setter def $NAME$(self, value): pass @$NAME$.deleter def $NAME$(self): pass" description="Property getter/setter/deleter" toReformat="false" toShortenFQNames="true">
|
||||
<variable name="NAME" expression="" defaultValue="" alwaysStopAt="true" />
|
||||
<context>
|
||||
<option name="HTML_TEXT" value="false" />
|
||||
<option name="HTML" value="false" />
|
||||
<option name="XSL_TEXT" value="false" />
|
||||
<option name="XML" value="false" />
|
||||
<option name="Python" value="true" />
|
||||
<option name="Django" value="false" />
|
||||
<option name="CSS_PROPERTY_VALUE" value="false" />
|
||||
<option name="CSS_DECLARATION_BLOCK" value="false" />
|
||||
<option name="CSS_RULESET_LIST" value="false" />
|
||||
<option name="CSS" value="false" />
|
||||
<option name="JAVA_SCRIPT" value="false" />
|
||||
<option name="TypeScript" value="false" />
|
||||
<option name="SQL" value="false" />
|
||||
<option name="CoffeeScript" value="false" />
|
||||
<option name="OTHER" value="false" />
|
||||
<option name="Python_Class" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
</templateSet>
|
||||
|
||||
@@ -374,7 +374,9 @@
|
||||
<localInspection language="Python" shortName="PyPep8NamingInspection" suppressId="PyPep8Naming" displayName="PEP 8 naming convention violation" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WEAK WARNING" implementationClass="com.jetbrains.python.inspections.PyPep8NamingInspection"/>
|
||||
<localInspection language="Python" shortName="PyAssignmentToLoopOrWithParameterInspection" suppressId="PyAssignmentToLoopOrWithParameter" displayName="Assignment to 'for' loop or 'with' statement parameter" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WEAK WARNING" implementationClass="com.jetbrains.python.inspections.PyAssignmentToLoopOrWithParameterInspection"/>
|
||||
|
||||
<liveTemplateContext implementation="com.jetbrains.python.codeInsight.liveTemplates.PythonTemplateContextType"/>
|
||||
<defaultLiveTemplatesProvider implementation="com.jetbrains.python.codeInsight.liveTemplates.PyDefaultLiveTemplatesProvider"/>
|
||||
<liveTemplateContext implementation="com.jetbrains.python.codeInsight.liveTemplates.PythonTemplateContextType$General"/>
|
||||
<liveTemplateContext implementation="com.jetbrains.python.codeInsight.liveTemplates.PythonTemplateContextType$Class"/>
|
||||
<liveTemplateMacro implementation="com.jetbrains.python.codeInsight.liveTemplates.CollectionElementNameMacro"/>
|
||||
<liveTemplateMacro implementation="com.jetbrains.python.codeInsight.liveTemplates.PyClassNameMacro"/>
|
||||
<liveTemplateMacro implementation="com.jetbrains.python.codeInsight.liveTemplates.PyFunctionNameMacro"/>
|
||||
@@ -418,8 +420,6 @@
|
||||
serviceImplementation="com.jetbrains.python.sdk.PySdkService"/>
|
||||
<autoImportOptionsProvider instance="com.jetbrains.python.codeInsight.imports.PyAutoImportOptions"/>
|
||||
|
||||
<defaultLiveTemplatesProvider implementation="com.jetbrains.python.codeInsight.liveTemplates.PyDefaultLiveTemplatesProvider"/>
|
||||
|
||||
<completion.contributor language="Python"
|
||||
implementationClass="com.jetbrains.python.codeInsight.completion.PyClassNameCompletionContributor"/>
|
||||
<weigher key="completion" implementationClass="com.jetbrains.python.codeInsight.completion.PythonCompletionWeigher" order="first"/>
|
||||
|
||||
+50
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -15,15 +15,18 @@
|
||||
*/
|
||||
package com.jetbrains.python.codeInsight.liveTemplates;
|
||||
|
||||
import com.intellij.codeInsight.template.FileTypeBasedContextType;
|
||||
import com.intellij.codeInsight.template.EverywhereContextType;
|
||||
import com.intellij.codeInsight.template.TemplateContextType;
|
||||
import com.intellij.patterns.PsiElementPattern;
|
||||
import com.intellij.psi.PsiComment;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.PythonFileType;
|
||||
import com.jetbrains.python.PythonLanguage;
|
||||
import com.jetbrains.python.psi.PyClass;
|
||||
import com.jetbrains.python.psi.PyParameterList;
|
||||
import com.jetbrains.python.psi.PyStringLiteralExpression;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -33,22 +36,37 @@ import static com.intellij.patterns.PlatformPatterns.psiElement;
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class PythonTemplateContextType extends FileTypeBasedContextType {
|
||||
public PythonTemplateContextType() {
|
||||
super("Python", "Python", PythonFileType.INSTANCE);
|
||||
public abstract class PythonTemplateContextType extends TemplateContextType {
|
||||
|
||||
public PythonTemplateContextType(@NotNull String id,
|
||||
@NotNull String presentableName,
|
||||
@NotNull java.lang.Class<? extends TemplateContextType> baseContextType) {
|
||||
super(id, presentableName, baseContextType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInContext(@NotNull PsiFile file, int offset) {
|
||||
if (super.isInContext(file, offset)) {
|
||||
if (isPythonLanguage(file, offset)) {
|
||||
final PsiElement element = file.findElementAt(offset);
|
||||
|
||||
if (element != null) {
|
||||
return !(isAfterDot(element) || element instanceof PsiComment || isInsideStringLiteral(element) || isInsideParameterList(element));
|
||||
if (isAfterDot(element) || element instanceof PsiComment || isInsideStringLiteral(element) || isInsideParameterList(element)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isInContext(element);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected abstract boolean isInContext(@NotNull PsiElement element);
|
||||
|
||||
private static boolean isPythonLanguage(@NotNull PsiFile file, int offset) {
|
||||
return PsiUtilCore.getLanguageAtOffset(file, offset).isKindOf(PythonLanguage.getInstance());
|
||||
}
|
||||
|
||||
private static boolean isInsideStringLiteral(@NotNull PsiElement element) {
|
||||
return PsiTreeUtil.getParentOfType(element, PyStringLiteralExpression.class, false) != null;
|
||||
}
|
||||
@@ -62,4 +80,28 @@ public class PythonTemplateContextType extends FileTypeBasedContextType {
|
||||
psiElement().withElementType(PyTokenTypes.DOT));
|
||||
return capture.accepts(element, new ProcessingContext());
|
||||
}
|
||||
|
||||
public static class General extends PythonTemplateContextType {
|
||||
|
||||
public General() {
|
||||
super("Python", "Python", EverywhereContextType.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isInContext(@NotNull PsiElement element) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Class extends PythonTemplateContextType {
|
||||
|
||||
public Class() {
|
||||
super("Python_Class", "Class", General.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isInContext(@NotNull PsiElement element) {
|
||||
return PsiTreeUtil.getParentOfType(element, PyClass.class) != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
foo.<caret>
|
||||
@@ -0,0 +1,3 @@
|
||||
class C(object):
|
||||
p<caret>
|
||||
pass
|
||||
@@ -0,0 +1,2 @@
|
||||
p<caret>
|
||||
pass
|
||||
@@ -0,0 +1 @@
|
||||
# <caret>
|
||||
@@ -0,0 +1,2 @@
|
||||
def foo(a, <caret>):
|
||||
pass
|
||||
@@ -0,0 +1 @@
|
||||
"abc<caret>"
|
||||
@@ -0,0 +1,3 @@
|
||||
<html>
|
||||
<caret>
|
||||
</html>
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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.jetbrains.python.codeInsight.liveTemplates;
|
||||
|
||||
import com.intellij.codeInsight.template.TemplateContextType;
|
||||
import com.intellij.testFramework.UsefulTestCase;
|
||||
import com.jetbrains.python.fixtures.PyTestCase;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class PyLiveTemplatesTest extends PyTestCase {
|
||||
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return super.getTestDataPath() + "/codeInsight/liveTemplates/context/";
|
||||
}
|
||||
|
||||
public void testNotPython() {
|
||||
doTest(Collections.emptyList(), "html");
|
||||
}
|
||||
|
||||
// PY-12212
|
||||
public void testAfterDot() {
|
||||
doTest(Collections.emptyList());
|
||||
}
|
||||
|
||||
// PY-13076
|
||||
public void testInComment() {
|
||||
doTest(Collections.emptyList());
|
||||
}
|
||||
|
||||
// PY-12349
|
||||
public void testInStringLiteral() {
|
||||
doTest(Collections.emptyList());
|
||||
}
|
||||
|
||||
// PY-12395
|
||||
public void testInParameterList() {
|
||||
doTest(Collections.emptyList());
|
||||
}
|
||||
|
||||
public void testGeneral() {
|
||||
doTest(
|
||||
Collections.singletonList(PythonTemplateContextType.General.class)
|
||||
);
|
||||
}
|
||||
|
||||
// PY-12396
|
||||
public void testClass() {
|
||||
doTest(
|
||||
Arrays.asList(PythonTemplateContextType.Class.class, PythonTemplateContextType.General.class)
|
||||
);
|
||||
}
|
||||
|
||||
private void doTest(@NotNull List<Class<? extends PythonTemplateContextType>> expectedContextTypes) {
|
||||
doTest(expectedContextTypes, "py");
|
||||
}
|
||||
|
||||
private void doTest(@NotNull List<Class<? extends PythonTemplateContextType>> expectedContextTypes, @NotNull String extension) {
|
||||
myFixture.configureByFile(getTestName(true) + "." + extension);
|
||||
|
||||
UsefulTestCase.assertSameElements(
|
||||
calculateEnabledContextTypes(getRegisteredContextTypes()),
|
||||
expectedContextTypes
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<Class<? extends PythonTemplateContextType>> calculateEnabledContextTypes(@NotNull List<PythonTemplateContextType> registeredContextTypes) {
|
||||
//noinspection Convert2MethodRef
|
||||
return registeredContextTypes
|
||||
.stream()
|
||||
.filter(type -> type.isInContext(myFixture.getFile(), myFixture.getCaretOffset()))
|
||||
.map(type -> type.getClass())
|
||||
.sorted((o1, o2) -> o1.getSimpleName().compareTo(o2.getSimpleName()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<PythonTemplateContextType> getRegisteredContextTypes() {
|
||||
return Arrays
|
||||
.stream(TemplateContextType.EP_NAME.getExtensions())
|
||||
.filter(type -> type instanceof PythonTemplateContextType)
|
||||
.map(type -> (PythonTemplateContextType)type)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user