Skip to content

Commit 8d39e50

Browse files
authored
Basic experimental support for mypy static suggestion engine (#36)
I also bump version and include some recent changes in changelog.
1 parent 29bb86a commit 8d39e50

File tree

5 files changed

+81
-7
lines changed

5 files changed

+81
-7
lines changed

Diff for: build.gradle

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ plugins {
22
id 'org.jetbrains.intellij' version '0.4.8'
33
}
44

5+
sourceCompatibility = 1.8
6+
57
repositories {
68
mavenCentral()
79
}
@@ -11,9 +13,6 @@ sourceSets {
1113
java.srcDir 'src'
1214
resources.srcDir 'resources'
1315
}
14-
test {
15-
java.srcDir 'test'
16-
}
1716
}
1817

1918
intellij {
@@ -24,6 +23,7 @@ intellij {
2423
plugins = ['PythonCore:2019.1.191.7479.7']
2524
updateSinceUntilBuild false
2625
downloadSources true
26+
buildSearchableOptions.enabled = false
2727
}
2828

2929
dependencies {

Diff for: resources/META-INF/plugin.xml

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<idea-plugin>
22
<id>com.dropbox.plugins.mypy_plugin</id>
33
<name>Dropbox mypy plugin</name>
4-
<version>0.2.0</version>
4+
<version>0.3.0</version>
55
<vendor url="https://github.com/dropbox/mypy-PyCharm-plugin">Dropbox Mypy Team</vendor>
66

77
<description><![CDATA[
@@ -11,6 +11,8 @@
1111

1212
<change-notes><![CDATA[
1313
<ul>
14+
<li>Version 0.3.0 (October 2019) — Minor bug fixes. Support reading configuration from mypy.ini.
15+
Experimental support of dmypy suggest. Convert plugin to Gradle.
1416
<li>Version 0.2.0 (November 2018) — Track error locations after editing.
1517
Avoid NullPointerException on empty output. Show output if there are only notes.
1618
Show notification in editor when type checking completed while plugin window is closed.
@@ -66,5 +68,10 @@
6668
<keyboard-shortcut keymap="Mac OS X" first-keystroke="shift ctrl ENTER"/>
6769
<keyboard-shortcut keymap="Mac OS X 10.5+" first-keystroke="shift ctrl ENTER"/>
6870
</action>
71+
<action id="Function Signature Suggestion" class="com.dropbox.plugins.mypy_plugin.actions.AskSuggestion" text="Suggest Signature For Function">
72+
<keyboard-shortcut keymap="$default" first-keystroke="shift ctrl Y"/>
73+
<keyboard-shortcut keymap="Mac OS X" first-keystroke="shift ctrl Y"/>
74+
<keyboard-shortcut keymap="Mac OS X 10.5+" first-keystroke="shift ctrl Y"/>
75+
</action>
6976
</actions>
7077
</idea-plugin>

Diff for: src/com/dropbox/plugins/mypy_plugin/MypyRunner.java

+12-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.intellij.openapi.application.ApplicationManager;
77
import com.intellij.openapi.project.Project;
88
import com.intellij.openapi.ui.Messages;
9+
import com.intellij.openapi.vfs.VirtualFile;
910
import org.jetbrains.annotations.Nullable;
1011

1112
import javax.swing.*;
@@ -27,7 +28,7 @@ public final class MypyRunner {
2728
}
2829

2930
@Nullable
30-
MypyResult runMypyDaemon() {
31+
MypyResult runMypyDaemon(@Nullable String command, @Nullable VirtualFile vf) {
3132
Process process;
3233
String directory = project.getBaseDir().getPath();
3334
MypyConfig config = MypyConfigLoader.findMypyConfig(project);
@@ -41,7 +42,13 @@ MypyResult runMypyDaemon() {
4142
if (!extraPath.equals("")) {
4243
envProcess.put("PATH", envProcess.get("PATH") + File.pathSeparator + extraPath);
4344
}
44-
String mypyCommand = config.getExecutableName();
45+
String mypyCommand;
46+
if (command != null) {
47+
mypyCommand = command;
48+
}
49+
else {
50+
mypyCommand = config.getExecutableName();
51+
}
4552
processBuilder.command("/bin/bash", "-c", mypyCommand);
4653
processBuilder.redirectErrorStream(true);
4754
processBuilder.redirectInput(new File("/dev/null"));
@@ -88,6 +95,9 @@ MypyResult runMypyDaemon() {
8895
}
8996
}
9097
process.waitFor();
98+
if (vf != null) {
99+
vf.refresh(false, false);
100+
}
91101
} catch (IOException | InterruptedException e) {
92102
ApplicationManager.getApplication().invokeLater(() -> Messages.showMessageDialog(project, e.getMessage(),
93103
"Plugin Exception:", Messages.getErrorIcon()));

Diff for: src/com/dropbox/plugins/mypy_plugin/MypyTerminal.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import com.intellij.ui.content.Content;
2929
import com.intellij.ui.content.ContentFactory;
3030
import icons.MypyIcons;
31+
import org.jetbrains.annotations.Nullable;
3132

3233
import javax.swing.*;
3334
import java.awt.*;
@@ -272,14 +273,18 @@ public void mouseClicked(MouseEvent e) {
272273
}
273274

274275
public void runMypyDaemonUIWrapper() {
276+
runMypyDaemonUIWrapper(null, null);
277+
}
278+
279+
public void runMypyDaemonUIWrapper(@Nullable String command, @Nullable VirtualFile vf) {
275280

276281
setWaiting();
277282
FileDocumentManager.getInstance().saveAllDocuments();
278283
// Invoke mypy daemon runner script in a sub-thread,
279284
// it looks like UI is blocked on it otherwise.
280285
Executors.newSingleThreadExecutor().execute(() -> {
281286
Thread.currentThread().setName("MypyRunnerThread");
282-
MypyResult result = MypyTerminal.this.runner.runMypyDaemon();
287+
MypyResult result = MypyTerminal.this.runner.runMypyDaemon(command, vf);
283288
if (result == null) return;
284289
// Access UI is prohibited from non-dispatch thread.
285290
ApplicationManager.getApplication().invokeLater(() -> {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package com.dropbox.plugins.mypy_plugin.actions;
2+
3+
import com.dropbox.plugins.mypy_plugin.MypyTerminal;
4+
import com.dropbox.plugins.mypy_plugin.MypyToolWindowFactory;
5+
import com.intellij.openapi.actionSystem.AnAction;
6+
import com.intellij.openapi.actionSystem.AnActionEvent;
7+
import com.intellij.openapi.actionSystem.PlatformDataKeys;
8+
import com.intellij.openapi.editor.Editor;
9+
import com.intellij.openapi.editor.LogicalPosition;
10+
import com.intellij.openapi.fileEditor.FileDocumentManager;
11+
import com.intellij.openapi.project.DumbAware;
12+
import com.intellij.openapi.project.Project;
13+
import com.intellij.openapi.vfs.VirtualFile;
14+
import com.intellij.openapi.wm.ToolWindow;
15+
import com.intellij.openapi.wm.ToolWindowManager;
16+
import org.jetbrains.annotations.NotNull;
17+
18+
19+
final class AskSuggestion extends AnAction implements DumbAware {
20+
@Override
21+
public void actionPerformed(@NotNull AnActionEvent e) {
22+
Editor editor = e.getData(PlatformDataKeys.EDITOR);
23+
if (editor == null)
24+
return;
25+
LogicalPosition pos = editor.getCaretModel().getPrimaryCaret().getLogicalPosition();
26+
int line = pos.line;
27+
FileDocumentManager.getInstance().saveAllDocuments();
28+
VirtualFile vf = e.getData(PlatformDataKeys.VIRTUAL_FILE);
29+
if (vf == null)
30+
return;
31+
String command = "./mypy/mypy-suggest " + vf.getPath() + " " + String.valueOf(line + 1);
32+
33+
Project project = e.getData(PlatformDataKeys.PROJECT);
34+
if (project == null) {
35+
return;
36+
}
37+
ToolWindow tw = ToolWindowManager.getInstance(project).getToolWindow(
38+
MypyToolWindowFactory.MYPY_PLUGIN_ID);
39+
if (!tw.isVisible()) {
40+
tw.show(null);
41+
}
42+
MypyTerminal terminal = MypyToolWindowFactory.getMypyTerminal(project);
43+
if (terminal == null) {
44+
return;
45+
}
46+
if (terminal.getRunner().isRunning()) {
47+
return;
48+
}
49+
terminal.runMypyDaemonUIWrapper(command, vf);
50+
vf.refresh(false, false);
51+
}
52+
}

0 commit comments

Comments
 (0)