Skip to content

Commit

Permalink
#70
Browse files Browse the repository at this point in the history
  • Loading branch information
Peter Vanusanik committed May 8, 2023
1 parent 2151b15 commit da7213e
Show file tree
Hide file tree
Showing 18 changed files with 444 additions and 157 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
## 0.5.1
## 0.5.1 230508

### Added
- Symbol inspection
- Rainbow braces option
- More browser options
- Evaluate top level action

### Changes
- Macroexpand is now action and menu, no longer automatic!

### Fixes
- Added symbols with no file into all search places

Expand Down
19 changes: 7 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,26 +95,21 @@ You can also open this as a project in Intellij Idea.
* [x] Breakpoints
* [x] Documentation
* [x] Hyperspec intergration
* [x] Macro expand in documentation
* Macro expand requires you to hover element twice for now
* [x] Macro expand (all, 1, normal)
* [x] Find function by symbol name
* [x] Search for symbols
* [x] Back references
* [x] Rainbow braces
* [ ] Refactoring
* [ ] List of quicklisp installed packages / ASDF packages
* [ ] List of modified top level forms that are yet to be evaluated
* [ ] Actually make an IDE, ie just plugin with dependencies as one application, not a plugin

### Far futures / possible goals

* [x] SDK Support
* not a true SDK because that is only available in Intellij and not in (for instance) PyCharm, thus
this is implemented manually.
* [x] Download SBCL and quicklisp for user
* [x] SDK Support
* not a true SDK because that is only available in Intellij and not in (for instance) PyCharm, thus
this is implemented manually.
* [x] Download SBCL and quicklisp for user
* [x] Automatic download of lisp interpret and quicklisp
* [x] Different lisp interpreter support
* [ ] Remote connections to interpreters
* [ ] Rewrite everything into ABCL just for purity’s sake lol
* [x] Different lisp interpreter support

## License

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package com.en_circle.slt.plugin;

import com.en_circle.slt.plugin.SymbolState.SymbolBinding;
import com.en_circle.slt.plugin.environment.LispFeatures;
import com.en_circle.slt.plugin.lisp.LispParserUtil;
import com.en_circle.slt.plugin.lisp.psi.LispList;
import com.en_circle.slt.plugin.lisp.psi.LispSymbol;
import com.en_circle.slt.plugin.services.lisp.LispEnvironmentService;
import com.intellij.lang.documentation.AbstractDocumentationProvider;
Expand Down Expand Up @@ -68,7 +66,7 @@ public class SltDocumentationProvider extends AbstractDocumentationProvider {
String text = element.getText();
String packageName = LispParserUtil.getPackage(element);
SymbolState state = LispEnvironmentService.getInstance(element.getProject()).refreshSymbolFromServer(packageName, text);
return asHtml(state, packageName, element);
return asHtml(state, element);
}
}
return null;
Expand All @@ -82,7 +80,7 @@ private PsiElement decideOnElement(PsiElement element, PsiElement originalElemen
return originalElement;
}

private String asHtml(SymbolState state, String packageName, PsiElement element) {
private String asHtml(SymbolState state, PsiElement element) {
HtmlBuilder builder = new HtmlBuilder();
if (LispEnvironmentService.getInstance(element.getProject()).hasFeature(LispFeatures.DOCUMENTATION)) {
String documentation = StringUtils.replace(StringUtils.replace(escape(state.documentation), " ", " "),
Expand All @@ -91,24 +89,6 @@ private String asHtml(SymbolState state, String packageName, PsiElement element)
HtmlChunk.raw(documentation));
}

if (LispEnvironmentService.getInstance(element.getProject()).hasFeature(LispFeatures.MACROEXPAND)) {
LispList form = LispParserUtil.getIfHead(element);
if (form != null && state.binding == SymbolBinding.MACRO) {
String macroExpand = LispEnvironmentService.getInstance(element.getProject()).macroexpand(form, packageName);
if (macroExpand != null) {
macroExpand = StringUtils.replace(StringUtils.replace(escape(macroExpand), " ", " "),
"\n", HtmlChunk.br().toString());
builder.append(HtmlChunk.hr());
builder.append(HtmlChunk.text(SltBundle.message("slt.documentation.macroexpand")));
builder.append(HtmlChunk.br());
builder.append(HtmlChunk.raw(macroExpand));
} else {
builder.append(HtmlChunk.hr());
builder.append(HtmlChunk.text(SltBundle.message("slt.documentation.macroexpand.generating")));
}
}
}

String doc = builder.toString();
return StringUtils.isBlank(doc) ? null : doc;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.en_circle.slt.plugin.actions;

import com.en_circle.slt.plugin.SltBundle;
import com.en_circle.slt.plugin.lisp.lisp.LispString;
import com.en_circle.slt.plugin.lisp.lisp.LispUtils;
import com.en_circle.slt.plugin.lisp.psi.LispList;
import com.en_circle.slt.plugin.services.lisp.LispEnvironmentService;
import com.en_circle.slt.plugin.swank.requests.Macroexpand1;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Macroexpand1Action extends MacroexpandActionBase {
private static final Logger log = LoggerFactory.getLogger(Macroexpand1Action.class);

@Override
protected void macroexpand(Project project, LispList form, String packageName, MacroexpandCallback callback) {
try {
LispEnvironmentService service = LispEnvironmentService.getInstance(project);
service.sendToLisp(new Macroexpand1(form.getText(), packageName, result -> {
callback.showMacroexpand(LispUtils.unescape(((LispString) result).getValue()));
}), true);
} catch (Exception e) {
log.warn(SltBundle.message("slt.error.start"), e);
Messages.showErrorDialog(project, e.getMessage(), SltBundle.message("slt.ui.errors.lisp.start"));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.en_circle.slt.plugin.actions;

import com.en_circle.slt.plugin.SltBundle;
import com.en_circle.slt.plugin.lisp.lisp.LispString;
import com.en_circle.slt.plugin.lisp.lisp.LispUtils;
import com.en_circle.slt.plugin.lisp.psi.LispList;
import com.en_circle.slt.plugin.services.lisp.LispEnvironmentService;
import com.en_circle.slt.plugin.swank.requests.Macroexpand;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MacroexpandAction extends MacroexpandActionBase {
private static final Logger log = LoggerFactory.getLogger(MacroexpandAction.class);

@Override
protected void macroexpand(Project project, LispList form, String packageName, MacroexpandCallback callback) {
try {
LispEnvironmentService service = LispEnvironmentService.getInstance(project);
service.sendToLisp(new Macroexpand(form.getText(), packageName, result -> {
callback.showMacroexpand(LispUtils.unescape(((LispString) result).getValue()));
}), true);
} catch (Exception e) {
log.warn(SltBundle.message("slt.error.start"), e);
Messages.showErrorDialog(project, e.getMessage(), SltBundle.message("slt.ui.errors.lisp.start"));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package com.en_circle.slt.plugin.actions;

import com.en_circle.slt.plugin.SltBundle;
import com.en_circle.slt.plugin.SltCommonLispFileType;
import com.en_circle.slt.plugin.environment.LispFeatures;
import com.en_circle.slt.plugin.lisp.LispParserUtil;
import com.en_circle.slt.plugin.lisp.psi.LispList;
import com.en_circle.slt.plugin.services.lisp.LispEnvironmentService;
import com.intellij.openapi.actionSystem.ActionUpdateThread;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.text.HtmlBuilder;
import com.intellij.openapi.util.text.HtmlChunk;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import javax.swing.text.html.HTMLEditorKit;
import java.awt.*;
import java.util.Objects;

public abstract class MacroexpandActionBase extends AnAction {

protected abstract void macroexpand(Project project, LispList form, String packageName, MacroexpandCallback callback);

@Override
public void actionPerformed(@NotNull AnActionEvent event) {
EditorEx editor = (EditorEx) event.getData(CommonDataKeys.EDITOR);
LispList list = null;

if (editor != null) {
PsiDocumentManager psiMgr = PsiDocumentManager.getInstance(Objects.requireNonNull(editor.getProject()));
psiMgr.commitDocument(editor.getDocument());
PsiFile psiFile = psiMgr.getPsiFile(editor.getDocument());
if (psiFile != null) {
int caretOffset = editor.getExpectedCaretOffset();
list = findList(psiFile, caretOffset, editor.getDocument());
if (list != null) {
editor.getSelectionModel().setSelection(list.getTextOffset(), list.getTextOffset() + list.getTextLength());
}
}

if (list != null) {
int offset = list.getTextOffset();
String packageName = LispParserUtil.getPackage(psiFile, offset);
macroexpand(editor.getProject(), list, packageName, text -> SwingUtilities.invokeLater(() -> {
HtmlBuilder builder = new HtmlBuilder();
String macroExpand = StringUtils.replace(StringUtils.replace(StringEscapeUtils.escapeHtml(text), " ", " "),
"\n", HtmlChunk.br().toString());
builder.append(HtmlChunk.raw(macroExpand));

JEditorPane editorPane = new JEditorPane("text/html", "");
editorPane.setEditorKit(new HTMLEditorKit());
editorPane.setText(builder.toString());

JPanel textPanel = new JPanel(new BorderLayout());
textPanel.add(editorPane, BorderLayout.CENTER);

JBPopup popup = JBPopupFactory.getInstance()
.createComponentPopupBuilder(textPanel, null)
.setProject(editor.getProject())
.setTitle(SltBundle.message("slt.documentation.macroexpand"))
.setShowBorder(true)
.setMovable(true)
.setFocusable(true)
.setRequestFocus(true)
.createPopup();
popup.showInBestPositionFor(editor.getDataContext());
}));
}
}
}

protected LispList findList(PsiFile psiFile, int caretOffset, Document document) {
PsiElement element = psiFile.findElementAt(caretOffset);
if (element != null) {
PsiElement parent = element;
while (parent != null) {
parent = parent.getParent();
if (parent instanceof LispList) {
return (LispList) parent;
}
}
}
return null;
}

@Override
public void update(@NotNull AnActionEvent event) {
event.getPresentation().setEnabledAndVisible(false);
Editor editor = event.getData(CommonDataKeys.EDITOR);
if (editor != null && event.getProject() != null) {
PsiFile file = PsiDocumentManager.getInstance(Objects.requireNonNull(editor.getProject())).getPsiFile(editor.getDocument());
if (file != null && SltCommonLispFileType.INSTANCE.equals(file.getFileType())) {
event.getPresentation().setEnabledAndVisible(LispEnvironmentService.getInstance(event.getProject())
.hasFeature(LispFeatures.MACROEXPAND));
}
}
}

@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
return ActionUpdateThread.BGT;
}

protected interface MacroexpandCallback {

void showMacroexpand(String text);

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.en_circle.slt.plugin.actions;

import com.en_circle.slt.plugin.SltBundle;
import com.en_circle.slt.plugin.lisp.lisp.LispString;
import com.en_circle.slt.plugin.lisp.lisp.LispUtils;
import com.en_circle.slt.plugin.lisp.psi.LispList;
import com.en_circle.slt.plugin.services.lisp.LispEnvironmentService;
import com.en_circle.slt.plugin.swank.requests.MacroexpandAll;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MacroexpandAllAction extends MacroexpandActionBase {
private static final Logger log = LoggerFactory.getLogger(MacroexpandAllAction.class);

@Override
protected void macroexpand(Project project, LispList form, String packageName, MacroexpandCallback callback) {
try {
LispEnvironmentService service = LispEnvironmentService.getInstance(project);
service.sendToLisp(new MacroexpandAll(form.getText(), packageName, result -> {
callback.showMacroexpand(LispUtils.unescape(((LispString) result).getValue()));
}), true);
} catch (Exception e) {
log.warn(SltBundle.message("slt.error.start"), e);
Messages.showErrorDialog(project, e.getMessage(), SltBundle.message("slt.ui.errors.lisp.start"));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.en_circle.slt.plugin.actions;

import com.en_circle.slt.plugin.SltBundle;
import com.en_circle.slt.plugin.SltCommonLispFileType;
import com.en_circle.slt.plugin.environment.LispFeatures;
import com.en_circle.slt.plugin.services.lisp.LispEnvironmentService;
import com.intellij.openapi.actionSystem.ActionUpdateThread;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;

import java.util.Objects;

public class MacroexpandGroup extends DefaultActionGroup {

public MacroexpandGroup() {
super(() -> SltBundle.message("action.slt.actions.macroexpand.group.text"), true);
}

@Override
public void update(@NotNull AnActionEvent event) {
event.getPresentation().setEnabledAndVisible(false);
Editor editor = event.getData(CommonDataKeys.EDITOR);
if (editor != null && event.getProject() != null) {
PsiFile file = PsiDocumentManager.getInstance(Objects.requireNonNull(editor.getProject())).getPsiFile(editor.getDocument());
if (file != null && SltCommonLispFileType.INSTANCE.equals(file.getFileType())) {
event.getPresentation().setEnabledAndVisible(LispEnvironmentService.getInstance(event.getProject())
.hasFeature(LispFeatures.MACROEXPAND));
}
}
}

@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
return ActionUpdateThread.BGT;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import com.en_circle.slt.plugin.environment.SltLispEnvironment;
import com.en_circle.slt.plugin.environment.SltLispEnvironment.SltLispOutputChangedListener;
import com.en_circle.slt.plugin.lisp.lisp.LispElement;
import com.en_circle.slt.plugin.lisp.psi.LispList;
import com.en_circle.slt.plugin.services.lisp.components.SltBreakpoint;
import com.en_circle.slt.plugin.services.lisp.components.SltLispEnvironmentSymbolCache.BatchedSymbolRefreshAction;
import com.en_circle.slt.plugin.swank.SlimeListener.DebugInterface;
Expand Down Expand Up @@ -55,8 +54,6 @@ static LispEnvironmentService getInstance(Project project) {

SltLispEnvironment getEnvironment();

String macroexpand(LispList form, String packageName);

void updateIndentation(LispElement element);

Integer calculateOffset(PsiElement element, PsiFile file, boolean wasAfter, String text, int offset, String packageOverride);
Expand Down
Loading

0 comments on commit da7213e

Please sign in to comment.