Skip to content

Instantly share code, notes, and snippets.

@mhrlife
Created November 30, 2024 10:11
Show Gist options
  • Save mhrlife/3d26a861feb1fca6084aa1a69bf1d06a to your computer and use it in GitHub Desktop.
Save mhrlife/3d26a861feb1fca6084aa1a69bf1d06a to your computer and use it in GitHub Desktop.
// Necessary imports
import com.intellij.openapi.actionSystem.*
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.fileEditor.*
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Key
import com.intellij.openapi.vfs.*
import java.awt.Toolkit
import java.awt.datatransfer.StringSelection
// Define a key for project UserData
val RECENT_FILES_KEY = Key.create<MutableList<VirtualFile>>("RecentFilesList")
// Function to get or create the recent files list
fun getRecentFilesList(project: Project): MutableList<VirtualFile> {
var list = project.getUserData(RECENT_FILES_KEY)
if (list == null) {
list = mutableListOf()
project.putUserData(RECENT_FILES_KEY, list)
}
return list
}
// Function to add a file to the recent files list
fun addToRecentFiles(project: Project, file: VirtualFile?) {
if (file != null) {
val recentFilesList = getRecentFilesList(project)
recentFilesList.remove(file) // Remove if it already exists to prevent duplicates
recentFilesList.add(0, file) // Add to the front
if (recentFilesList.size > 10) {
recentFilesList.removeAt(recentFilesList.size - 1) // Keep the size to 10
}
}
}
// Add the listener to the project
fun addRecentFilesListener(project: Project) {
val connection = project.messageBus.connect()
connection.subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, object : FileEditorManagerListener {
override fun fileOpened(source: FileEditorManager, file: VirtualFile) {
addToRecentFiles(project, file)
}
override fun selectionChanged(event: FileEditorManagerEvent) {
addToRecentFiles(project, event.newFile)
}
})
}
// Define the action
class CopyRecentFilesAction : AnAction("Copy Recent Files Context") {
override fun actionPerformed(e: AnActionEvent) {
val project = e.project ?: return
ApplicationManager.getApplication().runReadAction {
val recentFilesList = getRecentFilesList(project)
val lastFiles = recentFilesList.take(10)
val sb = StringBuilder()
sb.append("Please read the following code snippets carefully. These are recent files from my project, complete with their paths relative to the project directory. They reflect the project's structure, coding practices, and style guidelines.\n\nWhen assisting me:\n- Use these code snippets to understand the existing architecture and codebase.\n- Maintain consistency with the project's coding style, practices, and conventions as demonstrated in the snippets.\n- Ensure that any generated code integrates seamlessly with the existing project structure and follows the same patterns.\n- After reviewing the code, please help me answer my questions or generate code, keeping in mind the context provided.\n\n# Here are the code snippets:\n\n")
val projectBaseDir = project.basePath?.let { VfsUtil.findFileByIoFile(java.io.File(it), true) }
for (virtualFile in lastFiles) {
// Get the file path relative to the project base directory
val filePath = if (projectBaseDir != null) {
VfsUtilCore.getRelativePath(virtualFile, projectBaseDir, '/')
} else {
virtualFile.path // Fallback to absolute path if base directory is not available
}
val fileContent = try {
VfsUtilCore.loadText(virtualFile)
} catch (e: Exception) {
"// Error reading file: ${e.message}"
}
sb.append("``` $filePath\n")
sb.append(fileContent)
sb.append("\n```\n\n")
}
sb.append("\n\n# My Question")
val result = sb.toString()
// Copy to clipboard
val clipboard = Toolkit.getDefaultToolkit().systemClipboard
val selection = StringSelection(result)
clipboard.setContents(selection, null)
}
}
}
// Register and add the action to the Tools menu
val actionId = "CopyRecentFilesLiveAction"
val actionManager = ActionManager.getInstance()
// Unregister the previous action if it exists
if (actionManager.getAction(actionId) != null) {
actionManager.unregisterAction(actionId)
}
val action = CopyRecentFilesAction()
actionManager.registerAction(actionId, action)
val menuGroup = actionManager.getAction("ToolsMenu") as DefaultActionGroup
// Check if the action is already added to the menu
if (menuGroup.getChildren(null).none { it.templatePresentation.text == action.templatePresentation.text }) {
menuGroup.add(action)
}
// Add the listener to all open projects
val projectManager = com.intellij.openapi.project.ProjectManager.getInstance()
projectManager.openProjects.forEach { project ->
addRecentFilesListener(project)
}
@mhrlife
Copy link
Author

mhrlife commented Nov 30, 2024

LivePlugin: Copy Recent Files Content to Clipboard

Overview

This LivePlugin script for GoLand (or any IntelliJ-based IDE) allows you to copy the content of your last 5 recently opened files to the clipboard. It includes the full file paths relative to your project directory, making it ideal for providing context when seeking assistance or generating code with tools like ChatGPT.

How It Works

  • Tracks Recent Files: The plugin adds a listener that monitors file openings and selections within your project. It maintains a list of your most recently accessed files.
  • Copies Content to Clipboard: When triggered, the plugin collects the content of the last 5 recent files, formats them with their relative paths, and copies the combined text to your clipboard.
  • Facilitates Context Sharing: By copying code snippets along with their file paths, you can provide external tools or collaborators with valuable context about your project's structure and coding practices.

Setup Instructions

Prerequisites

  • GoLand IDE: Ensure you have GoLand installed. This plugin should also work with other IntelliJ-based IDEs.
  • LivePlugin: Install the LivePlugin plugin from the JetBrains Marketplace.

Installation Steps

1. Install LivePlugin

  1. Open GoLand.
  2. Navigate to File > Settings (on Windows/Linux) or GoLand > Preferences (on macOS).
  3. Select Plugins from the sidebar.
  4. Click on the Marketplace tab and search for "LivePlugin".
  5. Click Install next to LivePlugin.
  6. Restart GoLand when prompted.

2. Create a New Live Plugin

  1. After restarting, go to Plugins in the menu bar.
  2. Select LivePlugin > New Plugin.
  3. Enter a name for your plugin, e.g., "CopyRecentFilesLivePlugin".
  4. Choose Kotlin as the scripting language when prompted.

3. Add the Plugin Script

  1. In the Project view, expand the LivePlugin directory.
  2. Locate your new plugin folder (CopyRecentFilesLivePlugin) and find plugin.kts inside it.
  3. Open plugin.kts for editing.

4. Paste the Code

Replace the entire content of plugin.kts with the code from your gist. Ensure that you copy all the code accurately.

5. Save the Script

  • Save the plugin.kts file (Ctrl+S or Cmd+S).
  • LivePlugin will automatically compile and load the script upon saving.

Usage Instructions

Run the Plugin Action

  • Via Menu:
    • In GoLand, go to Tools in the menu bar.
    • Click on "Recent Files Context" at the bottom of the Tools menu.
  • Using Keyboard Shortcut (Optional):
    • Assign a keyboard shortcut to the action for quick access (instructions below).

Assigning a Keyboard Shortcut (Optional)

  1. Navigate to File > Settings (Windows/Linux) or GoLand > Preferences (macOS).
  2. Select Keymap from the sidebar.
  3. In the search bar, type "Recent Files Context".
  4. Right-click on the "Recent Files Context" action in the results.
  5. Choose "Add Keyboard Shortcut...".
  6. Press your desired key combination (e.g., Ctrl + Shift + R), then click OK.
  7. Apply the changes and close the Settings window.

Using the Plugin

  1. Open and Work with Files:
    • As you work, the plugin will keep track of the files you open or select.
  2. Trigger the Plugin:
    • Use the menu action or the keyboard shortcut you assigned.
  3. Paste the Content:
    • The combined content of your last 5 recent files is now on your clipboard.
    • Paste it into ChatGPT or any text editor to view the formatted code snippets.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment