try {
GeneralCommandLine commandLine = new GeneralCommandLine();
String emacsPath = EmacsSettings.getInstance(project).getEmacsPath();
if (emacsPath.isEmpty()) {
Notifications.Bus.notify(
new Notification(groupId, NOTIFICATION_TITLE,
"Emacs executable path is empty"+
"<br/><a href='configure'>Configure</a>",
NotificationType.WARNING, new ErlangExternalToolsNotificationListener(project)), project);
return;
}
commandLine.setExePath(emacsPath);
commandLine.addParameters("--batch", "--eval");
String sdkPath = getSdkPath(project);
if (StringUtil.isEmpty(sdkPath)) {
Notifications.Bus.notify(
new Notification(groupId, NOTIFICATION_TITLE, "Erlang project SDK is not configured",
NotificationType.WARNING), project);
return;
}
final File tmpFile = FileUtil.createTempFile("emacs", ".erl", true);
VirtualFile virtualTmpFile = LocalFileSystem.getInstance().findFileByIoFile(tmpFile);
if (virtualTmpFile == null) {
Notifications.Bus.notify(
new Notification(groupId, NOTIFICATION_TITLE, "Failed to create a temporary file",
NotificationType.WARNING), project);
return;
}
boolean exists = new File(sdkPath, "lib/erlang/lib").exists();
String emacsCommand = "\n" +
"(progn (find-file \"" + virtualFile.getCanonicalPath() + "\")\n" +
" (setq erlang-root-dir \"" + sdkPath + "\")\n" +
" (setq load-path (cons (car (file-expand-wildcards (concat erlang-root-dir \"/lib/" + (exists ? "erlang/lib/" : "") + "tools-*/emacs\")))\n" +
" load-path))\n" +
" (require 'erlang-start)\n" +
" (erlang-mode)\n" +
" (erlang-indent-current-buffer)\n" +
" (delete-trailing-whitespace)\n" +
" (untabify (point-min) (point-max))\n" +
" (write-region (point-min) (point-max) \"" + virtualTmpFile.getCanonicalPath() + "\")\n" +
" (kill-emacs))";
commandLine.addParameter(emacsCommand);
ApplicationManager.getApplication().saveAll();
final String commandLineString = commandLine.getCommandLineString();
OSProcessHandler handler = new OSProcessHandler(commandLine.createProcess(), commandLineString);
handler.addProcessListener(new ProcessAdapter() {
@Override
public void processTerminated(ProcessEvent event) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
try {
final String emacsText = FileUtilRt.loadFile(tmpFile, true);
if (StringUtil.isEmptyOrSpaces(emacsText)) {
Notifications.Bus.notify(new Notification(groupId, NOTIFICATION_TITLE,
"Emacs returned an empty file",
NotificationType.WARNING), project);
LOG.warn("Emacs returned an empty file:\n" + commandLineString);
return;
}
final Document document = PsiDocumentManager.getInstance(project).getDocument(psiFile);
if (document == null) return;
CommandProcessor.getInstance().executeCommand(project, new Runnable() {
@Override
public void run() {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
document.setText(emacsText);
}
});
}
}, NOTIFICATION_TITLE, "", document);
Notifications.Bus.notify(new Notification(groupId, NOTIFICATION_TITLE,
psiFile.getName() + " formatted with Emacs",
NotificationType.INFORMATION), project);
} catch (Exception ex) {
Notifications.Bus.notify(new Notification(groupId,
psiFile.getName() + " formatting with Emacs failed", ExceptionUtil.getUserStackTrace(ex, LOG),
NotificationType.ERROR), project);
LOG.error(ex);
}
}
});
}
});
handler.startNotify();
} catch (Exception ex) {
Notifications.Bus.notify(new Notification(groupId,
psiFile.getName() + " formatting with Emacs failed", ExceptionUtil.getUserStackTrace(ex, LOG),
NotificationType.ERROR), project);
LOG.error(ex);
}
}