/src/java/ideah/actions/NewHaskellFileAction.java

https://github.com/makido/ideah · Java · 141 lines · 125 code · 16 blank · 0 comment · 23 complexity · 3f5f0ce21c36137386fdb4667579c29b MD5 · raw file

  1. package ideah.actions;
  2. import com.intellij.CommonBundle;
  3. import com.intellij.ide.IdeView;
  4. import com.intellij.ide.actions.CreateElementActionBase;
  5. import com.intellij.openapi.actionSystem.DataContext;
  6. import com.intellij.openapi.actionSystem.LangDataKeys;
  7. import com.intellij.openapi.actionSystem.PlatformDataKeys;
  8. import com.intellij.openapi.fileEditor.FileEditorManager;
  9. import com.intellij.openapi.module.Module;
  10. import com.intellij.openapi.project.Project;
  11. import com.intellij.openapi.roots.ProjectRootManager;
  12. import com.intellij.openapi.ui.Messages;
  13. import com.intellij.openapi.vfs.VirtualFile;
  14. import com.intellij.psi.PsiDirectory;
  15. import com.intellij.psi.PsiElement;
  16. import com.intellij.psi.PsiFile;
  17. import com.intellij.psi.PsiFileFactory;
  18. import com.intellij.util.IncorrectOperationException;
  19. import ideah.HaskellFileType;
  20. import ideah.module.HaskellModuleType;
  21. import org.jetbrains.annotations.NotNull;
  22. public final class NewHaskellFileAction extends CreateElementActionBase {
  23. private static final String WHAT = "Haskell module";
  24. public NewHaskellFileAction() {
  25. super(WHAT, "Creates new " + WHAT, HaskellFileType.HASKELL_ICON); // todo: another icon?
  26. }
  27. @NotNull
  28. protected PsiElement[] invokeDialog(Project project, PsiDirectory directory) {
  29. if (!isHaskellModule(project, directory)) {
  30. Messages.showErrorDialog(project, "Cannot create " + WHAT + " in non-Haskell project", "Wrong module");
  31. return new PsiElement[0];
  32. }
  33. MyInputValidator validator = new MyInputValidator(project, directory);
  34. Messages.showInputDialog(project, "Enter name for new " + WHAT, "New " + WHAT, Messages.getQuestionIcon(), "", validator);
  35. return validator.getCreatedElements();
  36. }
  37. protected void checkBeforeCreate(String newName, PsiDirectory directory) throws IncorrectOperationException {
  38. }
  39. @NotNull
  40. protected PsiElement[] create(String newName, PsiDirectory directory) throws Exception {
  41. if ("".equals(newName)) {
  42. throw new IncorrectOperationException("A name should be specified.");
  43. }
  44. HaskellFileType type = HaskellFileType.INSTANCE;
  45. String ext = type.getDefaultExtension();
  46. Project project = directory.getProject();
  47. PsiDirectory moduleDir = directory;
  48. int length = newName.length() - 1;
  49. while (newName.charAt(length) == '.') {
  50. newName = newName.substring(0, length);
  51. length--;
  52. }
  53. String[] fileNames = newName.split("\\.");
  54. int depth = fileNames.length;
  55. String moduleName = fileNames[depth - 1];
  56. boolean needsModuleName = Character.isUpperCase(moduleName.charAt(0));
  57. String parentPackages = ProjectRootManager.getInstance(project).getFileIndex().getPackageNameByDirectory(directory.getVirtualFile());
  58. StringBuilder packages = new StringBuilder(
  59. "".equals(parentPackages) || !needsModuleName
  60. ? ""
  61. : parentPackages + "."
  62. );
  63. for (int i = 0; i < depth - 1; i++) {
  64. String dirName = fileNames[i];
  65. if ("".equals(dirName)) {
  66. throw new IncorrectOperationException("File name cannot be empty.");
  67. }
  68. PsiDirectory subDir = moduleDir.findSubdirectory(dirName);
  69. moduleDir = subDir == null ? moduleDir.createSubdirectory(dirName) : subDir;
  70. if (needsModuleName) {
  71. packages.append(dirName).append('.');
  72. }
  73. }
  74. PsiFile file = PsiFileFactory.getInstance(project).createFileFromText(moduleName + "." + ext, type,
  75. needsModuleName
  76. ? "module " + packages + moduleName + " where\n\n"
  77. : ""
  78. );
  79. file = (PsiFile) moduleDir.add(file);
  80. VirtualFile virtualFile = file.getVirtualFile();
  81. if (virtualFile != null) {
  82. FileEditorManager.getInstance(directory.getProject()).openFile(virtualFile, true);
  83. }
  84. return new PsiElement[] {file};
  85. }
  86. protected String getErrorTitle() {
  87. return CommonBundle.getErrorTitle();
  88. }
  89. protected String getCommandName() {
  90. return "Create " + WHAT;
  91. }
  92. protected String getActionName(PsiDirectory directory, String newName) {
  93. return WHAT;
  94. }
  95. @Override
  96. protected boolean isAvailable(DataContext dataContext) {
  97. if (!super.isAvailable(dataContext))
  98. return false;
  99. Project project = PlatformDataKeys.PROJECT.getData(dataContext);
  100. if (project == null) {
  101. return false;
  102. }
  103. IdeView view = LangDataKeys.IDE_VIEW.getData(dataContext);
  104. if (view == null) {
  105. return false;
  106. }
  107. PsiDirectory[] dirs = view.getDirectories();
  108. if (dirs == null || dirs.length <= 0)
  109. return false;
  110. boolean anyHaskell = false;
  111. for (PsiDirectory dir : dirs) {
  112. if (isHaskellModule(project, dir)) {
  113. anyHaskell = true;
  114. break;
  115. }
  116. }
  117. return anyHaskell;
  118. }
  119. private static boolean isHaskellModule(Project project, PsiDirectory dir) {
  120. Module module = ProjectRootManager.getInstance(project).getFileIndex().getModuleForFile(dir.getVirtualFile());
  121. if (module == null)
  122. return false;
  123. return HaskellModuleType.INSTANCE.equals(module.getModuleType());
  124. }
  125. }