Skip to content

Instantly share code, notes, and snippets.

@adrienlucas
Created February 2, 2023 08:43
Show Gist options
  • Save adrienlucas/fd55df59febf83a5a2320e635b7799a0 to your computer and use it in GitHub Desktop.
Save adrienlucas/fd55df59febf83a5a2320e635b7799a0 to your computer and use it in GitHub Desktop.
"Copilot More PHP Context" for IntelliJ IDE Console
// "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