Created
February 2, 2023 08:43
-
-
Save adrienlucas/fd55df59febf83a5a2320e635b7799a0 to your computer and use it in GitHub Desktop.
"Copilot More PHP Context" for IntelliJ IDE Console
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// "Copilot More PHP Context" | |
// Adds the content of the imported PHP classes as a comment to the end of the opened file | |
// in order to provide more context to the Copilot plugin. | |
// This Groovy script is meant to be used with the IntelliJ IDE Console plugin. | |
import java.io.File | |
import com.intellij.openapi.actionSystem.AnAction | |
import com.intellij.openapi.actionSystem.AnActionEvent | |
import com.intellij.openapi.actionSystem.CommonDataKeys | |
import com.intellij.openapi.command.WriteCommandAction | |
import com.intellij.openapi.editor.Document | |
import com.intellij.openapi.project.Project | |
def void copilotMorePhpContext(AnActionEvent e) { | |
def project = e.getData(CommonDataKeys.PROJECT) | |
def editor = e.getData(CommonDataKeys.EDITOR) | |
def document = editor.getDocument() | |
// find all use statements using regexp | |
def useStatements = document.text.split("\n").findAll { it.startsWith("use ") } | |
// Then create a comment block with the content of the imported classes | |
def commentBlock = useStatements.collect { statement -> | |
def className = statement.replaceFirst('use ', '') | |
className = className.substring(0, className.length() - 1) | |
// App classes are in the src folder | |
def classPath = "" | |
if (className.startsWith("App\\")) { | |
classPath = className.replace("\\", "/") | |
classPath = classPath.replaceFirst("App", "./src") | |
} else { | |
// Other classes are in the vendor folder | |
// Their location are defined in the vendor/composer/autoload_static.php file | |
def autoloadStatic = new File("./vendor/composer/autoload_static.php").text | |
def pattern = ~/'(.*)' => \s*array\s*\(\s*0\s*=>\s*__DIR__\s*\.\s*'\/\.\.'\s*\.\s*'(.*)'\s*,?/ | |
def matches = autoloadStatic =~ pattern | |
matches.each { match -> | |
def (_,namespace,path) = match | |
namespace = namespace.replace("\\\\", "\\") | |
if (className.startsWith(namespace)) { | |
className = className.replace(namespace, path+"/") | |
} | |
} | |
classPath = className.replace("\\", "/") | |
classPath = "./vendor" + classPath | |
} | |
// if file does not exist, skip it | |
if (!new File(classPath + ".php").exists()) { | |
return "" | |
} | |
def classContent = new File(classPath + ".php").text | |
def pattern = ~/(public|protected)\s+(\$[a-zA-Z0-9_]+)(\s+\$[a-zA-Z0-9_]+)*;|(public|protected) function ([a-zA-Z0-9_]+)\(([^)]*)\)(: ([a-zA-Z0-9_]+))?/ | |
//def pattern = ~/(public|protected)\s+(\$[a-zA-Z0-9_]+|function\s+[a-zA-Z0-9_]+\([^)]*\))/ | |
def matcher = classContent =~ pattern | |
def publicSignatures = "" | |
while (matcher.find()) { | |
String match = matcher.group() | |
publicSignatures += match + "\n" | |
} | |
"// ${className}:\n\n${publicSignatures}" | |
}.join("\n") | |
removeCopilotContext(project, document) | |
// Finally insert the comment block at the end of the file | |
WriteCommandAction.runWriteCommandAction(project, () -> | |
document.insertString(document.textLength, "/* __COPILOT_CONTEXT__ \n${commentBlock}\n*/") | |
); | |
} | |
def void removeCopilotContext(Project project, Document document) { | |
def pattern = ~/__COPILOT_CONTEXT__/ | |
def matcher = document.text =~ pattern | |
if (!matcher.find()) return | |
WriteCommandAction.runWriteCommandAction(project, () -> | |
// Remove the entire comment block with the class signatures | |
document.deleteString(matcher.start()-3, document.textLength) | |
); | |
} | |
// Add an action to add the context | |
def action = new AnAction("Copilot More PHP Context") { | |
@Override | |
public void actionPerformed(AnActionEvent e) { | |
copilotMorePhpContext(e) | |
} | |
} | |
com.intellij.openapi.actionSystem.ActionManager.getInstance() | |
.registerAction("copilot-more-context", action) | |
// Add an action to remove the context | |
def removeContextAction = new AnAction("Remove Copilot Context") { | |
@Override | |
public void actionPerformed(AnActionEvent e) { | |
removeCopilotContext(e.getData(CommonDataKeys.PROJECT), e.getData(CommonDataKeys.EDITOR).getDocument()) | |
} | |
} | |
com.intellij.openapi.actionSystem.ActionManager.getInstance() | |
.registerAction("remove-copilot-context", removeContextAction) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment