Repository: LiLittleCat/intellij-chatgpt
Branch: main
Commit: e55fd5756054
Files: 43
Total size: 93.0 KB
Directory structure:
gitextract_jsuwudpi/
├── .github/
│ ├── dependabot.yml
│ └── workflows/
│ ├── build.yml
│ ├── release.yml
│ └── run-ui-tests.yml
├── .gitignore
├── .run/
│ ├── Run IDE for UI Tests.run.xml
│ ├── Run IDE with Plugin.run.xml
│ ├── Run Plugin Tests.run.xml
│ ├── Run Plugin Verification.run.xml
│ └── Run Qodana.run.xml
├── CHANGELOG.md
├── DESCRIPTION.md
├── README.md
├── README_CN.md
├── build.gradle.kts
├── gradle/
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── qodana.yml
├── settings.gradle.kts
└── src/
├── main/
│ ├── java/
│ │ └── com/
│ │ └── lilittlecat/
│ │ └── chatgpt/
│ │ ├── action/
│ │ │ ├── AddTabAction.java
│ │ │ ├── FetchURLAction.java
│ │ │ ├── GitHubAction.java
│ │ │ ├── MorePluginAction.java
│ │ │ ├── RefreshAction.java
│ │ │ └── SettingsAction.java
│ │ ├── message/
│ │ │ └── ChatGPTBundle.java
│ │ ├── setting/
│ │ │ ├── AddOrEditUrl.form
│ │ │ ├── AddOrEditUrl.java
│ │ │ ├── ChatGPTSettingsComponent.java
│ │ │ ├── ChatGPTSettingsConfigurable.java
│ │ │ ├── ChatGPTSettingsState.java
│ │ │ ├── Test.form
│ │ │ ├── Test.java
│ │ │ └── UpdateChatGPTSettingStateTopic.java
│ │ └── window/
│ │ ├── ChatGPTToolWindow.java
│ │ └── ChatGPTToolWindowFactory.java
│ └── resources/
│ ├── META-INF/
│ │ └── plugin.xml
│ └── messages/
│ └── ChatGPTBundle.properties
└── test/
└── testData/
└── rename/
├── foo.xml
└── foo_after.xml
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/dependabot.yml
================================================
# Dependabot configuration:
# https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
# Maintain dependencies for Gradle dependencies
- package-ecosystem: "gradle"
directory: "/"
target-branch: "next"
schedule:
interval: "daily"
# Maintain dependencies for GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
target-branch: "next"
schedule:
interval: "daily"
================================================
FILE: .github/workflows/build.yml
================================================
# GitHub Actions Workflow created for testing and preparing the plugin release in following steps:
# - validate Gradle Wrapper,
# - run 'test' and 'verifyPlugin' tasks,
# - run Qodana inspections,
# - run 'buildPlugin' task and prepare artifact for the further tests,
# - run 'runPluginVerifier' task,
# - create a draft release.
#
# Workflow is triggered on push and pull_request events.
#
# GitHub Actions reference: https://help.github.com/en/actions
#
## JBIJPPTPL
name: Build
on:
# Trigger the workflow on pushes to only the 'main' branch (this avoids duplicate checks being run e.g. for dependabot pull requests)
push:
branches: [main]
# Trigger the workflow on any pull request
pull_request:
jobs:
# Run Gradle Wrapper Validation Action to verify the wrapper's checksum
# Run verifyPlugin, IntelliJ Plugin Verifier, and test Gradle tasks
# Build plugin and provide the artifact for the next workflow jobs
build:
name: Build
runs-on: ubuntu-latest
outputs:
version: ${{ steps.properties.outputs.version }}
changelog: ${{ steps.properties.outputs.changelog }}
steps:
# Free GitHub Actions Environment Disk Space
- name: Maximize Build Space
run: |
sudo rm -rf /usr/share/dotnet
sudo rm -rf /usr/local/lib/android
sudo rm -rf /opt/ghc
# Check out current repository
- name: Fetch Sources
uses: actions/checkout@v3
# Validate wrapper
- name: Gradle Wrapper Validation
uses: gradle/wrapper-validation-action@v1.0.5
# Setup Java 11 environment for the next steps
- name: Setup Java
uses: actions/setup-java@v3
with:
distribution: zulu
java-version: 11
# Set environment variables
- name: Export Properties
id: properties
shell: bash
run: |
PROPERTIES="$(./gradlew properties --console=plain -q)"
VERSION="$(echo "$PROPERTIES" | grep "^version:" | cut -f2- -d ' ')"
NAME="$(echo "$PROPERTIES" | grep "^pluginName:" | cut -f2- -d ' ')"
CHANGELOG="$(./gradlew getChangelog --unreleased --no-header --console=plain -q)"
CHANGELOG="${CHANGELOG//'%'/'%25'}"
CHANGELOG="${CHANGELOG//$'\n'/'%0A'}"
CHANGELOG="${CHANGELOG//$'\r'/'%0D'}"
echo "::set-output name=version::$VERSION"
echo "::set-output name=name::$NAME"
echo "::set-output name=changelog::$CHANGELOG"
echo "::set-output name=pluginVerifierHomeDir::~/.pluginVerifier"
./gradlew listProductsReleases # prepare list of IDEs for Plugin Verifier
# Run tests
- name: Run Tests
run: ./gradlew check
# Collect Tests Result of failed tests
- name: Collect Tests Result
if: ${{ failure() }}
uses: actions/upload-artifact@v3
with:
name: tests-result
path: ${{ github.workspace }}/build/reports/tests
# Upload Kover report to CodeCov
- name: Upload Code Coverage Report
uses: codecov/codecov-action@v3
with:
files: ${{ github.workspace }}/build/reports/kover/xml/report.xml
# Cache Plugin Verifier IDEs
- name: Setup Plugin Verifier IDEs Cache
uses: actions/cache@v3
with:
path: ${{ steps.properties.outputs.pluginVerifierHomeDir }}/ides
key: plugin-verifier-${{ hashFiles('build/listProductsReleases.txt') }}
# Run Verify Plugin task and IntelliJ Plugin Verifier tool
- name: Run Plugin Verification tasks
run: ./gradlew runPluginVerifier -Pplugin.verifier.home.dir=${{ steps.properties.outputs.pluginVerifierHomeDir }}
# Collect Plugin Verifier Result
- name: Collect Plugin Verifier Result
if: ${{ always() }}
uses: actions/upload-artifact@v3
with:
name: pluginVerifier-result
path: ${{ github.workspace }}/build/reports/pluginVerifier
# Run Qodana inspections
# - name: Qodana - Code Inspection
# uses: JetBrains/qodana-action@v2022.2.3
# Prepare plugin archive content for creating artifact
- name: Prepare Plugin Artifact
id: artifact
shell: bash
run: |
cd ${{ github.workspace }}/build/distributions
FILENAME=`ls *.zip`
unzip "$FILENAME" -d content
echo "::set-output name=filename::${FILENAME:0:-4}"
# Store already-built plugin as an artifact for downloading
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: ${{ steps.artifact.outputs.filename }}
path: ./build/distributions/content/*/*
# Prepare a draft release for GitHub Releases page for the manual verification
# If accepted and published, release workflow would be triggered
releaseDraft:
name: Release Draft
if: github.event_name != 'pull_request'
needs: build
runs-on: ubuntu-latest
permissions:
contents: write
steps:
# Check out current repository
- name: Fetch Sources
uses: actions/checkout@v3
# Remove old release drafts by using the curl request for the available releases with draft flag
- name: Remove Old Release Drafts
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh api repos/{owner}/{repo}/releases \
--jq '.[] | select(.draft == true) | .id' \
| xargs -I '{}' gh api -X DELETE repos/{owner}/{repo}/releases/{}
# Create new release draft - which is not publicly visible and requires manual acceptance
- name: Create Release Draft
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release create v${{ needs.build.outputs.version }} \
--draft \
--title "v${{ needs.build.outputs.version }}" \
--notes "$(cat << 'EOM'
${{ needs.build.outputs.changelog }}
EOM
)"
================================================
FILE: .github/workflows/release.yml
================================================
# GitHub Actions Workflow created for handling the release process based on the draft release prepared
# with the Build workflow. Running the publishPlugin task requires the PUBLISH_TOKEN secret provided.
name: Release
on:
release:
types: [prereleased, released]
jobs:
# Prepare and publish the plugin to the Marketplace repository
release:
name: Publish Plugin
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
# Check out current repository
- name: Fetch Sources
uses: actions/checkout@v3
with:
ref: ${{ github.event.release.tag_name }}
# Setup Java 11 environment for the next steps
- name: Setup Java
uses: actions/setup-java@v3
with:
distribution: zulu
java-version: 11
# Set environment variables
- name: Export Properties
id: properties
shell: bash
run: |
CHANGELOG="$(cat << 'EOM' | sed -e 's/^[[:space:]]*$//g' -e '/./,$!d'
${{ github.event.release.body }}
EOM
)"
CHANGELOG="${CHANGELOG//'%'/'%25'}"
CHANGELOG="${CHANGELOG//$'\n'/'%0A'}"
CHANGELOG="${CHANGELOG//$'\r'/'%0D'}"
echo "::set-output name=changelog::$CHANGELOG"
# Update Unreleased section with the current release note
- name: Patch Changelog
if: ${{ steps.properties.outputs.changelog != '' }}
env:
CHANGELOG: ${{ steps.properties.outputs.changelog }}
run: |
./gradlew patchChangelog --release-note="$CHANGELOG"
# Publish the plugin to the Marketplace
- name: Publish Plugin
env:
PUBLISH_TOKEN: ${{ secrets.PUBLISH_TOKEN }}
CERTIFICATE_CHAIN: ${{ secrets.CERTIFICATE_CHAIN }}
PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }}
PRIVATE_KEY_PASSWORD: ${{ secrets.PRIVATE_KEY_PASSWORD }}
run: ./gradlew publishPlugin
# Upload artifact as a release asset
- name: Upload Release Asset
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: gh release upload ${{ github.event.release.tag_name }} ./build/distributions/*
# Create pull request
- name: Create Pull Request
if: ${{ steps.properties.outputs.changelog != '' }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
VERSION="${{ github.event.release.tag_name }}"
BRANCH="changelog-update-$VERSION"
LABEL="release changelog"
git config user.email "action@github.com"
git config user.name "GitHub Action"
git checkout -b $BRANCH
git commit -am "Changelog update - $VERSION"
git push --set-upstream origin $BRANCH
gh label create "$LABEL" \
--description "Pull requests with release changelog update" \
|| true
gh pr create \
--title "Changelog update - \`$VERSION\`" \
--body "Current pull request contains patched \`CHANGELOG.md\` file for the \`$VERSION\` version." \
--label "$LABEL" \
--head $BRANCH
================================================
FILE: .github/workflows/run-ui-tests.yml
================================================
# GitHub Actions Workflow for launching UI tests on Linux, Windows, and Mac in the following steps:
# - prepare and launch IDE with your plugin and robot-server plugin, which is needed to interact with UI
# - wait for IDE to start
# - run UI tests with separate Gradle task
#
# Please check https://github.com/JetBrains/intellij-ui-test-robot for information about UI tests with IntelliJ Platform
#
# Workflow is triggered manually.
name: Run UI Tests
on:
workflow_dispatch
jobs:
testUI:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
runIde: |
export DISPLAY=:99.0
Xvfb -ac :99 -screen 0 1920x1080x16 &
gradle runIdeForUiTests &
- os: windows-latest
runIde: start gradlew.bat runIdeForUiTests
- os: macos-latest
runIde: ./gradlew runIdeForUiTests &
steps:
# Check out current repository
- name: Fetch Sources
uses: actions/checkout@v3
# Setup Java 11 environment for the next steps
- name: Setup Java
uses: actions/setup-java@v3
with:
distribution: zulu
java-version: 11
# Run IDEA prepared for UI testing
- name: Run IDE
run: ${{ matrix.runIde }}
# Wait for IDEA to be started
- name: Health Check
uses: jtalk/url-health-check-action@v3
with:
url: http://127.0.0.1:8082
max-attempts: 15
retry-delay: 30s
# Run tests
- name: Tests
run: ./gradlew test
================================================
FILE: .gitignore
================================================
.gradle
.idea
.qodana
build
================================================
FILE: .run/Run IDE for UI Tests.run.xml
================================================
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Run IDE for UI Tests" type="GradleRunConfiguration" factoryName="Gradle">
<log_file alias="idea.log" path="$PROJECT_DIR$/build/idea-sandbox/system/log/idea.log" />
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="runIdeForUiTests" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list />
</option>
<option name="vmOptions" />
</ExternalSystemSettings>
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
<DebugAllEnabled>false</DebugAllEnabled>
<method v="2" />
</configuration>
</component>
================================================
FILE: .run/Run IDE with Plugin.run.xml
================================================
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Run Plugin" type="GradleRunConfiguration" factoryName="Gradle">
<log_file alias="idea.log" path="$PROJECT_DIR$/build/idea-sandbox/system/log/idea.log" />
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value="runIde" />
</list>
</option>
<option name="vmOptions" value="" />
</ExternalSystemSettings>
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
<DebugAllEnabled>false</DebugAllEnabled>
<method v="2" />
</configuration>
</component>
================================================
FILE: .run/Run Plugin Tests.run.xml
================================================
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Run Tests" type="GradleRunConfiguration" factoryName="Gradle">
<log_file alias="idea.log" path="$PROJECT_DIR$/build/idea-sandbox/system/log/idea.log" />
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value="check" />
</list>
</option>
<option name="vmOptions" value="" />
</ExternalSystemSettings>
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
<DebugAllEnabled>false</DebugAllEnabled>
<method v="2" />
</configuration>
</component>
================================================
FILE: .run/Run Plugin Verification.run.xml
================================================
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Run Verifications" type="GradleRunConfiguration" factoryName="Gradle">
<log_file alias="idea.log" path="$PROJECT_DIR$/build/idea-sandbox/system/log/idea.log" />
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value="runPluginVerifier" />
</list>
</option>
<option name="vmOptions" value="" />
</ExternalSystemSettings>
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
<DebugAllEnabled>false</DebugAllEnabled>
<method v="2">
<option name="Gradle.BeforeRunTask" enabled="true" tasks="clean" externalProjectPath="$PROJECT_DIR$" vmOptions="" scriptParameters="" />
</method>
</configuration>
</component>
================================================
FILE: .run/Run Qodana.run.xml
================================================
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Run Qodana" type="GradleRunConfiguration" factoryName="Gradle">
<ExternalSystemSettings>
<option name="env">
<map>
<entry key="QODANA_SHOW_REPORT" value="true" />
</map>
</option>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="cleanInspections runInspections" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list />
</option>
<option name="vmOptions" />
</ExternalSystemSettings>
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
<DebugAllEnabled>false</DebugAllEnabled>
<method v="2" />
</configuration>
</component>
================================================
FILE: CHANGELOG.md
================================================
<!-- Keep a Changelog guide -> https://keepachangelog.com -->
# intellij-chatgpt Changelog
## [Unreleased]
## [1.1.1] - 2023-03-30
### Added
- Bring session token setting for official website back. [#7 (comment)](https://github.com/LiLittleCat/intellij-chatgpt/issues/7#issuecomment-1487889326)
## [1.1.0] - 2023-03-21
### Added
- Integration of third-party mirror websites for free usage.
- Support for all future IDE builds [#12](https://github.com/LiLittleCat/intellij-chatgpt/pull/12)
### Fixed
- Removed session token storage to resolve cookie setting issues [#16](https://github.com/LiLittleCat/intellij-chatgpt/issues/16)
- Change the Tool Window name to `ChatGPT Tool` [#10](https://github.com/LiLittleCat/intellij-chatgpt/issues/10)
## [1.0.3] - 2023-02-20
- Fix bugs
## [1.0.2] - 2022-12-16
- Remove session token check because of Cloudflare
- Add refresh button [#2](https://github.com/LiLittleCat/intellij-chatgpt/issues/2)
- Support version 2020.2-2022.3 [#3](https://github.com/LiLittleCat/intellij-chatgpt/issues/3)
## [1.0.1] - 2022-12-12
### Added
- Update plugin description
## [1.0.0]
### Added
- Support all JetBrains IDEs
[Unreleased]: https://github.com/LiLittleCat/intellij-chatgpt/compare/v1.1.1...HEAD
[1.1.1]: https://github.com/LiLittleCat/intellij-chatgpt/compare/v1.1.0...v1.1.1
[1.1.0]: https://github.com/LiLittleCat/intellij-chatgpt/compare/v1.0.3...v1.1.0
[1.0.3]: https://github.com/LiLittleCat/intellij-chatgpt/compare/v1.0.2...v1.0.3
[1.0.2]: https://github.com/LiLittleCat/intellij-chatgpt/compare/v1.0.1...v1.0.2
[1.0.1]: https://github.com/LiLittleCat/intellij-chatgpt/compare/v1.0.0...v1.0.1
[1.0.0]: https://github.com/LiLittleCat/intellij-chatgpt/commits/v1.0.0
================================================
FILE: DESCRIPTION.md
================================================
<!-- Plugin description -->
This Jetbrains IDEs plugin integrates [ChatGPT](https://chat.openai.com/) and [other third-party mirror websites](https://github.com/LiLittleCat/awesome-free-chatgpt) of ChatGPT into JetBrains IDEs,
providing a seamless experience for developers to interact with the ChatGPT AI model directly within their development environment.
### Feature
- 🚀 Easy to use, interact with ChatGPT without leaving the IDE.
- 🆓 Integrates free third-party mirror websites and easily update.
- ✅ Add and manage multiple ChatGPT URLs.
- 🔄 Easily switch between different ChatGPT URLs.
### How it works
This plugin uses JCEF(Java Chromium Embedded Framework) to render the content. It is a lightweight and cross-platform web browser engine that is built on top of Chromium and is used by IntelliJ IDEA to render the HTML content of the IDE.
JCEF is supported in IntelliJ IDEA 2020.2 and later. See [JCEF](https://plugins.jetbrains.com/docs/intellij/jcef.html) for more information.
### 💡 Solution for `Cannot log in to the official ChatGPT by Google account or Microsoft account`
See [Notice from README](https://github.com/LiLittleCat/intellij-chatgpt/blob/bring-back-session-token/README.md#-notice).
### Support
Feel free to submit [issue](https://github.com/LiLittleCat/awesome-free-chatgpt/issues) and [PRs](https://github.com/LiLittleCat/awesome-free-chatgpt/pulls). If you find it useful, welcome to star ⭐, your support is my motivation to move forward.
---
一个将 [ChatGPT](https://chat.openai.com/) 和 [其他第三方镜像网站](https://github.com/LiLittleCat/awesome-free-chatgpt) 整合到 JetBrains IDEs 的插件。
### 功能
- 🚀 易于使用,无需离开 IDE 即可与 ChatGPT 交互。
- 🆓 集成免费的第三方镜像网站,并且更新方便。
- ✅ 添加和管理多个 ChatGPT URL。
- 🔄 轻松在不同的 ChatGPT URL 之间切换。
### 如何工作的
此插件使用 JCEF(Java Chromium Embedded Framework)来渲染内容。它是一个轻量级且跨平台的基于 Chromium 的网络浏览器引擎,被 IntelliJ IDEA 用于渲染 IDE 的 HTML 内容。
JCEF 支持 IntelliJ IDEA 2020.2 及更高版本。有关更多信息,请参阅 [JCEF](https://plugins.jetbrains.com/docs/intellij/jcef.html)。
### 💡 `无法用谷歌账户或微软账户登录官方 ChatGPT` 的解决方案
见 [README 中的注意](https://github.com/LiLittleCat/intellij-chatgpt/blob/bring-back-session-token/README_CN.md#-%E6%B3%A8%E6%84%8F)。
### 支持
欢迎随时提交 [issue](https://github.com/LiLittleCat/awesome-free-chatgpt/issues) 和 [PRs](https://github.com/LiLittleCat/awesome-free-chatgpt/pulls),如果您觉得有用,欢迎 star ⭐,您的支持是我前进的动力。
<!-- Plugin description end -->
================================================
FILE: README.md
================================================
<img src="src/main/resources/META-INF/pluginIcon.svg" align="right" width="128" height="128" alt="icon"/>
# ChatGPT Tool

[](https://plugins.jetbrains.com/plugin/20629-chatgpt-tool)
[](https://plugins.jetbrains.com/plugin/20629-chatgpt-tool)
[中文说明](README_CN.md)
This Jetbrains IDEs plugin integrates [ChatGPT](https://chat.openai.com/) and [other third-party mirror websites](https://github.com/LiLittleCat/awesome-free-chatgpt) of ChatGPT into JetBrains IDEs,
providing a seamless experience for developers to interact with the ChatGPT AI model directly within their development environment.
> ### 💡 Notice
> Cannot log in to the official ChatGPT by Google account or Microsoft account is not caused by this plugin, but by the
> official ChatGPT itself.
>
> See https://github.com/LiLittleCat/intellij-chatgpt/issues/7 and https://github.com/JetBrains/jcef/issues/14 for more
> information.
>
> <details>
> <summary>💡 Click to expand the Solution for this</summary>
>
> 1. Go to [https://chat.openai.com/chat](https://chat.openai.com/chat) and log in or sign up.
> 2. Open dev tools.
> 3. Open `Application` > `Cookies`.
[](https://imgse.com/i/pSSKdmR)
> 4. Copy the value for `__Secure-next-auth.session-token` as settings value.
[](https://imgse.com/i/pSSK6pD)
> 5. After you enter the session token, you need to restart the IDE because ChatGPT Tool Windows needs a restart, and
you won't need to log in until the session token is expired.
> </details>
## Feature
- 🚀 Easy to use, and interact with ChatGPT without leaving the IDE.
- 🆓 Integrates free third-party mirror websites and easily update.
- ✅ Add and manage multiple ChatGPT URLs.
- 🔄 Easily switch between different ChatGPT URLs.
## How it works
This plugin uses JCEF(Java Chromium Embedded Framework) to render the content. It is a lightweight and cross-platform web browser engine that is built on top of Chromium and is used by IntelliJ IDEA to render the HTML content of the IDE.
JCEF is supported in IntelliJ IDEA 2020.2 and later. See [JCEF](https://plugins.jetbrains.com/docs/intellij/jcef.html) for more information.
## Installation
- Using IDE built-in plugin system:
<kbd>Settings/Preferences</kbd> > <kbd>Plugins</kbd> > <kbd>Marketplace</kbd> > <kbd>Search for "ChatGPT Tool"</kbd> >
<kbd>Install Plugin</kbd>
- Manually:
Download the [latest release](https://github.com/LiLittleCat/intellij-chatgpt/releases/latest) and install it manually using
<kbd>Settings/Preferences</kbd> > <kbd>Plugins</kbd> > <kbd>⚙️</kbd> > <kbd>Install plugin from disk...</kbd>
## Usage
1. Open the "ChatGPT Tool" tool window, which will load the default ChatGPT URL.

2. If you have set the [official ChatGPT](https://chat.openai.com/) as the default, you can register for an [OpenAI](https://beta.openai.com/signup) account and log in.

3. Access the settings to modify the default ChatGPT URL or add additional URLs

Explanation:
1. Quickly open the settings.
2. Refresh the currently opened page.
3. Add a new URL to the tool window.
4. Open the author's GitHub page in browser.
5. Open other plugins from the author in browser.
6. Select the default URL. The default URL will be opened when you first launch the tool window and when all opened pages are closed.
7. URL list: add, edit, and delete URLs.
8. Add a new URL.

9. Delete the selected URL.
10. Fetch the URL list from [the author's other GitHub repository](https://github.com/LiLittleCat/awesome-free-chatgpt).
4. Utilize third-party mirror websites.

================================================
FILE: README_CN.md
================================================
<img src="src/main/resources/META-INF/pluginIcon.svg" align="right" width="128" height="128" alt="icon"/>
# ChatGPT Tool

[](https://plugins.jetbrains.com/plugin/20629-chatgpt-tool)
[](https://plugins.jetbrains.com/plugin/20629-chatgpt-tool)
[English](README.md)
一个将 [ChatGPT](https://chat.openai.com/) 和 [其他第三方镜像网站](https://github.com/LiLittleCat/awesome-free-chatgpt) 整合到 JetBrains IDEs 的插件。
> ### 💡 注意
> 无法使用 Google 账户或 Microsoft 账户登录官方 ChatGPT 不是由于此插件造成的,而是由官方 ChatGPT 本身造成的。
>
> 有关更多信息,请参阅 https://github.com/LiLittleCat/intellij-chatgpt/issues/7 和 https://github.com/JetBrains/jcef/issues/14 。
>
> <details>
> <summary>💡 点击展开解决方案</summary>
>
> 1. 进入 [https://chat.openai.com/chat](https://chat.openai.com/chat),登录或注册。
> 2. 打开开发工具。
> 3. 打开 `Application` > `Cookies`。
[](https://imgse.com/i/pSSKdmR)
> 4. 复制 `__Secure-next-auth.session-token` 的值作为设置值。
[](https://imgse.com/i/pSSK6pD)
> 5. 输入会话令牌后,你需要重启 IDE,因为 ChatGPT 工具 Windows 需要重启,在会话令牌过期之前,你不需要登录。
> </details>
## 功能
- 🚀 易于使用,无需离开 IDE 即可与 ChatGPT 交互。
- 🆓 集成免费的第三方镜像网站,并且更新方便。
- ✅ 添加和管理多个 ChatGPT URL。
- 🔄 轻松在不同的 ChatGPT URL 之间切换。
## 如何工作的
此插件使用 JCEF(Java Chromium Embedded Framework)来渲染内容。它是一个轻量级且跨平台的基于 Chromium 的网络浏览器引擎,被 IntelliJ IDEA 用于渲染 IDE 的 HTML 内容。
JCEF 支持 IntelliJ IDEA 2020.2 及更高版本。有关更多信息,请参阅 [JCEF](https://plugins.jetbrains.com/docs/intellij/jcef.html)。
## 安装
- 使用 IDE 内部插件系统:
<kbd>Settings/Preferences</kbd> > <kbd>Plugins</kbd> > <kbd>Marketplace</kbd> > <kbd> 搜索 "ChatGPT Tool"</kbd> >
<kbd>Install Plugin</kbd>
- 手动安装:
下载 [最新版本](https://github.com/LiLittleCat/intellij-chatgpt/releases/latest) 找到
<kbd>Settings/Preferences</kbd> > <kbd>Plugins</kbd> > <kbd>⚙️</kbd> > <kbd>Install plugin from disk...</kbd>
手动安装。
## 使用方法
1. 打开 "ChatGPT Tool" 工具窗口,它将打开默认的 ChatGPT URL。

2. 如果您将 [官方 ChatGPT](https://chat.openai.com/) 设置为默认,您可以注册一个 [OpenAI](https://beta.openai.com/signup) 账户并登录。

3. 打开设置以更改默认的 ChatGPT URL 或添加更多 URL。

说明:
1. 快速打开设置。
2. 刷新已打开的页面。
3. 向工具窗口添加新的 URL。
4. 在浏览器中打开作者的 GitHub 页面。
5. 在浏览器中打开作者的其他插件。
6. 选择默认 URL,当您首次打开工具窗口和关闭所有已打开的页面时,将打开默认 URL。
7. URL 列表,您可以添加、编辑和删除 URL 列表。
8. 添加新的 URL。

9. 删除选定的 URL。
10. 从 [作者的另一个 GitHub 仓库](https://github.com/LiLittleCat/awesome-free-chatgpt) 获取 URL 列表。
4. 使用第三方镜像网站。

================================================
FILE: build.gradle.kts
================================================
import org.jetbrains.changelog.Changelog
import org.jetbrains.changelog.markdownToHTML
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
fun properties(key: String) = project.findProperty(key).toString()
plugins {
// Java support
id("java")
// Kotlin support
id("org.jetbrains.kotlin.jvm") version "1.8.10"
// Gradle IntelliJ Plugin
id("org.jetbrains.intellij") version "1.13.2"
// Gradle Changelog Plugin
id("org.jetbrains.changelog") version "2.0.0"
// Gradle Qodana Plugin
id("org.jetbrains.qodana") version "0.1.13"
// Gradle Kover Plugin
id("org.jetbrains.kotlinx.kover") version "0.6.1"
}
group = properties("pluginGroup")
version = properties("pluginVersion")
// Configure project's dependencies
repositories {
mavenCentral()
}
dependencies {
// implementation("com.google.guava:guava:31.1-jre")
implementation("com.squareup.okhttp3:okhttp:4.9.3")
implementation("org.json:json:20230227")
}
// Set the JVM language level used to build project. Use Java 11 for 2020.3+, and Java 17 for 2022.2+.
kotlin {
jvmToolchain(11)
}
// Configure Gradle IntelliJ Plugin - read more: https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html
intellij {
pluginName.set(properties("pluginName"))
version.set(properties("platformVersion"))
type.set(properties("platformType"))
// Plugin Dependencies. Uses `platformPlugins` property from the gradle.properties file.
plugins.set(properties("platformPlugins").split(',').map(String::trim).filter(String::isNotEmpty))
}
// Configure Gradle Changelog Plugin - read more: https://github.com/JetBrains/gradle-changelog-plugin
changelog {
groups.set(emptyList())
repositoryUrl.set(properties("pluginRepositoryUrl"))
}
// Configure Gradle Qodana Plugin - read more: https://github.com/JetBrains/gradle-qodana-plugin
qodana {
cachePath.set(file(".qodana").canonicalPath)
reportPath.set(file("build/reports/inspections").canonicalPath)
saveReport.set(true)
showReport.set(System.getenv("QODANA_SHOW_REPORT")?.toBoolean() ?: false)
}
// Configure Gradle Kover Plugin - read more: https://github.com/Kotlin/kotlinx-kover#configuration
kover.xmlReport {
onCheck.set(true)
}
tasks {
wrapper {
gradleVersion = properties("gradleVersion")
}
patchPluginXml {
version.set(properties("pluginVersion"))
sinceBuild.set(properties("pluginSinceBuild"))
untilBuild.set(properties("pluginUntilBuild"))
// Extract the <!-- Plugin description --> section from README.md and provide for the plugin's manifest
pluginDescription.set(
file("DESCRIPTION.md").readText().lines().run {
val start = "<!-- Plugin description -->"
val end = "<!-- Plugin description end -->"
if (!containsAll(listOf(start, end))) {
throw GradleException("Plugin description section not found in README.md:\n$start ... $end")
}
subList(indexOf(start) + 1, indexOf(end))
}.joinToString("\n").let { markdownToHTML(it) }
)
// Get the latest available change notes from the changelog file
changeNotes.set(provider {
with(changelog) {
renderItem(
getOrNull(properties("pluginVersion")) ?: getLatest(),
Changelog.OutputType.HTML,
)
}
})
}
// Configure UI tests plugin
// Read more: https://github.com/JetBrains/intellij-ui-test-robot
runIdeForUiTests {
systemProperty("robot-server.port", "8082")
systemProperty("ide.mac.message.dialogs.as.sheets", "false")
systemProperty("jb.privacy.policy.text", "<!--999.999-->")
systemProperty("jb.consents.confirmation.enabled", "false")
}
signPlugin {
certificateChain.set(System.getenv("CERTIFICATE_CHAIN"))
privateKey.set(System.getenv("PRIVATE_KEY"))
password.set(System.getenv("PRIVATE_KEY_PASSWORD"))
}
publishPlugin {
dependsOn("patchChangelog")
token.set(System.getenv("PUBLISH_TOKEN"))
// pluginVersion is based on the SemVer (https://semver.org) and supports pre-release labels, like 2.1.7-alpha.3
// Specify pre-release label to publish the plugin in a custom Release Channel automatically. Read more:
// https://plugins.jetbrains.com/docs/intellij/deployment.html#specifying-a-release-channel
channels.set(listOf(properties("pluginVersion").split('-').getOrElse(1) { "default" }.split('.').first()))
}
}
dependencies {
implementation(kotlin("stdlib-jdk8"))
}
val compileKotlin: KotlinCompile by tasks
compileKotlin.kotlinOptions {
jvmTarget = "1.8"
}
val compileTestKotlin: KotlinCompile by tasks
compileTestKotlin.kotlinOptions {
jvmTarget = "1.8"
}
================================================
FILE: gradle/wrapper/gradle-wrapper.properties
================================================
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
================================================
FILE: gradle.properties
================================================
# IntelliJ Platform Artifacts Repositories -> https://plugins.jetbrains.com/docs/intellij/intellij-artifacts.html
pluginGroup = com.lilittlecat.intellij-chatgpt
pluginName = ChatGPT Tool
pluginRepositoryUrl = https://github.com/LiLittleCat/intellij-chatgpt
# SemVer format -> https://semver.org
pluginVersion = 1.1.1
# Supported build number ranges and IntelliJ Platform versions -> https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
pluginSinceBuild = 202
pluginUntilBuild =
# IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension
platformType = IC
platformVersion = 2020.2
# Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html
# Example: platformPlugins = com.intellij.java, com.jetbrains.php:203.4449.22
platformPlugins =
# Gradle Releases -> https://github.com/gradle/gradle/releases
gradleVersion = 8.0.2
# Opt-out flag for bundling Kotlin standard library -> https://plugins.jetbrains.com/docs/intellij/kotlin.html#kotlin-standard-library
# suppress inspection "UnusedProperty"
kotlin.stdlib.default.dependency = false
# Enable Gradle Configuration Cache -> https://docs.gradle.org/current/userguide/configuration_cache.html
org.gradle.unsafe.configuration-cache = true
#systemProp.https.proxyHost=127.0.0.1
#systemProp.https.proxyPort=7890
#systemProp.http.proxyHost=127.0.0.1
#systemProp.http.proxyPort=7890
================================================
FILE: gradlew
================================================
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"
================================================
FILE: gradlew.bat
================================================
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
================================================
FILE: qodana.yml
================================================
# Qodana configuration:
# https://www.jetbrains.com/help/qodana/qodana-yaml.html
version: 1.0
profile:
name: qodana.recommended
exclude:
- name: All
paths:
- .qodana
================================================
FILE: settings.gradle.kts
================================================
rootProject.name = "intellij-chatgpt"
================================================
FILE: src/main/java/com/lilittlecat/chatgpt/action/AddTabAction.java
================================================
package com.lilittlecat.chatgpt.action;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentManager;
import com.lilittlecat.chatgpt.message.ChatGPTBundle;
import com.lilittlecat.chatgpt.setting.ChatGPTSettingsState;
import com.lilittlecat.chatgpt.window.ChatGPTToolWindow;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Objects;
/**
* add new tab action
*
* @author <a href="https://github.com/LiLittleCat">LiLittleCat</a>
* @since 2023/3/9
*/
public class AddTabAction extends DumbAwareAction {
public AddTabAction(@NotNull @Nls String text) {
super(() -> text, AllIcons.General.Add);
}
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
List<String> urlList = ChatGPTSettingsState.getInstance().urlList;
String[] options = urlList.toArray(new String[0]);
// String selected = Messages.showChooseDialog("Select Content", "Choose Content to Add", options, options[0], null);
String selected = Messages.showEditableChooseDialog("Select URL", "Choose a URL to Add", AllIcons.General.Add, options, options[0], null);
if (selected == null) {
return;
}
ToolWindowManager instance = ToolWindowManager.getInstance(Objects.requireNonNull(e.getProject()));
ToolWindow toolWindow = instance.getToolWindow(ChatGPTBundle.message("name"));
assert toolWindow != null;
ContentManager contentManager = toolWindow.getContentManager();
Content content = contentManager.getFactory().createContent(new ChatGPTToolWindow(selected).getContent(), selected, false);
contentManager.addContent(content);
contentManager.setSelectedContent(content);
}
}
================================================
FILE: src/main/java/com/lilittlecat/chatgpt/action/FetchURLAction.java
================================================
package com.lilittlecat.chatgpt.action;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.util.messages.MessageBus;
import com.lilittlecat.chatgpt.message.ChatGPTBundle;
import com.lilittlecat.chatgpt.setting.ChatGPTSettingsState;
import com.lilittlecat.chatgpt.setting.UpdateChatGPTSettingStateTopic;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.apache.commons.collections.CollectionUtils;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.json.JSONArray;
import javax.swing.*;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* @author <a href="https://github.com/LiLittleCat">LiLittleCat</a>
* @since 2023/3/20
*/
public class FetchURLAction extends DumbAwareAction {
public FetchURLAction(@NotNull @Nls String text) {
super(() -> text, AllIcons.Actions.CheckOut);
}
@Override
public void actionPerformed(@NotNull AnActionEvent event) {
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(3, TimeUnit.SECONDS)
.readTimeout(3, TimeUnit.SECONDS)
.build();
String primaryUrl = ChatGPTBundle.message("free.chatgpt.file.url.original");
String fallbackUrl = ChatGPTBundle.message("free.chatgpt.file.url.fallback");
try {
JSONArray jsonArray = fetchJsonArray(client, primaryUrl);
processJsonArray(jsonArray);
JOptionPane.showMessageDialog(null, ChatGPTBundle.message("success.fetch.message"), "Success", JOptionPane.INFORMATION_MESSAGE);
} catch (IOException e) {
try {
JSONArray jsonArray = fetchJsonArray(client, fallbackUrl);
processJsonArray(jsonArray);
JOptionPane.showMessageDialog(null, ChatGPTBundle.message("success.fetch.message"), "Success", JOptionPane.INFORMATION_MESSAGE);
} catch (IOException e2) {
JOptionPane.showMessageDialog(null, ChatGPTBundle.message("cannot.fetch.message"), "Error", JOptionPane.ERROR_MESSAGE);
}
}
}
private JSONArray fetchJsonArray(OkHttpClient client, String url) throws IOException {
Request request = new Request.Builder()
.url(url)
.build();
try (Response response = client.newCall(request).execute()) {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
assert response.body() != null;
String jsonData = response.body().string();
return new JSONArray(jsonData);
}
}
private void processJsonArray(JSONArray jsonArray) {
// String defaultUrl = ChatGPTSettingsState.getInstance().defaultUrl;
List<String> oldUrlList = ChatGPTSettingsState.getInstance().urlList;
// oldUrlList.clear();
// String originalUrl = ChatGPTBundle.message("original.url");
// if (originalUrl.equals(defaultUrl)) {
// oldUrlList.add(defaultUrl);
// } else {
// oldUrlList.add(originalUrl);
// oldUrlList.add(defaultUrl);
// }
for (int i = 0; i < jsonArray.length(); i++) {
String url = jsonArray.getString(i);
if (!oldUrlList.contains(url)) {
oldUrlList.add(url);
}
}
// Notify subscribers about the change
MessageBus messageBus = ApplicationManager.getApplication().getMessageBus();
messageBus.syncPublisher(UpdateChatGPTSettingStateTopic.TOPIC).stateChanged();
}
}
================================================
FILE: src/main/java/com/lilittlecat/chatgpt/action/GitHubAction.java
================================================
package com.lilittlecat.chatgpt.action;
import com.intellij.icons.AllIcons;
import com.intellij.ide.BrowserUtil;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.project.DumbAwareAction;
import com.lilittlecat.chatgpt.message.ChatGPTBundle;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
/**
* @author <a href="https://github.com/LiLittleCat">LiLittleCat</a>
* @since 2023/3/21
*/
public class GitHubAction extends DumbAwareAction {
public GitHubAction(@NotNull @Nls String text) {
super(() -> text, AllIcons.Vcs.Vendors.Github);
}
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
BrowserUtil.browse(ChatGPTBundle.message("github.url"));
}
}
================================================
FILE: src/main/java/com/lilittlecat/chatgpt/action/MorePluginAction.java
================================================
package com.lilittlecat.chatgpt.action;
import com.intellij.icons.AllIcons;
import com.intellij.ide.BrowserUtil;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.project.DumbAwareAction;
import com.lilittlecat.chatgpt.message.ChatGPTBundle;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
/**
* @author <a href="https://github.com/LiLittleCat">LiLittleCat</a>
* @since 2023/3/21
*/
public class MorePluginAction extends DumbAwareAction {
public MorePluginAction(@NotNull @Nls String text) {
super(() -> text, AllIcons.Nodes.Plugin);
}
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
BrowserUtil.browse(ChatGPTBundle.message("more.plugins.url"));
}
}
================================================
FILE: src/main/java/com/lilittlecat/chatgpt/action/RefreshAction.java
================================================
package com.lilittlecat.chatgpt.action;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentFactory;
import com.intellij.ui.content.ContentManager;
import com.lilittlecat.chatgpt.message.ChatGPTBundle;
import com.lilittlecat.chatgpt.window.ChatGPTToolWindow;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
/**
* @author LiLittleCat
* @link <a href="https://github.com/LiLittleCat">https://github.com/LiLittleCat</a>
* @since 2022/12/15
*/
public class RefreshAction extends DumbAwareAction {
public RefreshAction(@NotNull @Nls String text) {
super(() -> text, AllIcons.Actions.Refresh);
}
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
// Get the ToolWindowManager instance for the current project
ToolWindowManager instance = ToolWindowManager.getInstance(Objects.requireNonNull(e.getProject()));
// Get the tool window with the specified name
ToolWindow toolWindow = instance.getToolWindow(ChatGPTBundle.message("name"));
if (toolWindow != null) {
// Get the content manager for the tool window
ContentManager contentManager = toolWindow.getContentManager();
// Get the currently selected content
Content selectedContent = contentManager.getSelectedContent();
assert selectedContent != null;
// Get the tab name of the selected content
String selectedContentTabName = selectedContent.getTabName();
// Store the index of the selected content
int selectedIndex = contentManager.getIndexOfContent(selectedContent);
// Remove the selected content
contentManager.removeContent(selectedContent, true);
// Iterate through all contents in the content manager
for (int i = 0; i < contentManager.getContentCount(); i++) {
// Get the current content
Content content = contentManager.getContent(i);
assert content != null;
// Get the tab name of the current content
String tabName = content.getTabName();
// Remove the current content
contentManager.removeContent(content, true);
// Create a new content with the same tab name
Content browser = ContentFactory.SERVICE.getInstance().createContent(
new ChatGPTToolWindow(tabName).getContent(), tabName, false);
// Add the new content to the content manager
contentManager.addContent(browser);
}
// Set the new content as the selected content using the updated selectedIndex
Content selectedBrowser = ContentFactory.SERVICE.getInstance().createContent(
new ChatGPTToolWindow(selectedContentTabName).getContent(), selectedContentTabName,false);
contentManager.addContent(selectedBrowser, selectedIndex);
contentManager.setSelectedContent(selectedBrowser);
}
}
}
================================================
FILE: src/main/java/com/lilittlecat/chatgpt/action/SettingsAction.java
================================================
package com.lilittlecat.chatgpt.action;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.project.DumbAwareAction;
import com.lilittlecat.chatgpt.setting.ChatGPTSettingsConfigurable;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
/**
* @author LiLittleCat
* @link <a href="https://github.com/LiLittleCat">https://github.com/LiLittleCat</a>
* @since 2022/12/10
*/
public class SettingsAction extends DumbAwareAction {
public SettingsAction(@NotNull @Nls String text) {
super(() -> text, AllIcons.General.Settings);
}
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
ShowSettingsUtil.getInstance().showSettingsDialog(e.getProject(), ChatGPTSettingsConfigurable.class);
}
}
================================================
FILE: src/main/java/com/lilittlecat/chatgpt/message/ChatGPTBundle.java
================================================
package com.lilittlecat.chatgpt.message;
import com.intellij.DynamicBundle;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.PropertyKey;
import java.util.function.Supplier;
/**
* @author <a href="https://github.com/LiLittleCat">LiLittleCat</a>
* @since 2022/12/10
*/
public class ChatGPTBundle extends DynamicBundle {
@NonNls
public static final String BUNDLE = "messages.ChatGPTBundle";
private static final ChatGPTBundle INSTANCE = new ChatGPTBundle();
private ChatGPTBundle() {
super(BUNDLE);
}
@NotNull
public static @Nls String message(@NotNull @PropertyKey(resourceBundle = BUNDLE) String key, Object @NotNull ... params) {
return INSTANCE.getMessage(key, params);
}
@NotNull
public static Supplier<@Nls String> messagePointer(@NotNull @PropertyKey(resourceBundle = BUNDLE) String key, Object @NotNull ... params) {
return INSTANCE.getLazyMessage(key, params);
}
}
================================================
FILE: src/main/java/com/lilittlecat/chatgpt/setting/AddOrEditUrl.form
================================================
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.lilittlecat.chatgpt.setting.AddOrEditUrl">
<grid id="cbd77" binding="contentPane" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="10" left="10" bottom="10" right="10"/>
<constraints>
<xy x="48" y="54" width="436" height="297"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<grid id="94766" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<hspacer id="98af6">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
<grid id="9538f" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="true" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="e7465" class="javax.swing.JButton" binding="buttonOK">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="OK"/>
</properties>
</component>
<component id="5723f" class="javax.swing.JButton" binding="buttonCancel">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Cancel"/>
</properties>
</component>
</children>
</grid>
</children>
</grid>
<grid id="e3588" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="45ebb" class="javax.swing.JTextField" binding="textField1" default-binding="true">
<constraints>
<grid row="1" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties/>
</component>
<vspacer id="22b09">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<component id="f9ce4" class="javax.swing.JLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Url"/>
</properties>
</component>
</children>
</grid>
</children>
</grid>
</form>
================================================
FILE: src/main/java/com/lilittlecat/chatgpt/setting/AddOrEditUrl.java
================================================
package com.lilittlecat.chatgpt.setting;
import javax.swing.*;
import java.awt.event.*;
public class AddOrEditUrl extends JDialog {
private JPanel contentPane;
private JButton buttonOK;
private JButton buttonCancel;
private JTextField textField1;
public AddOrEditUrl() {
setContentPane(contentPane);
setModal(true);
getRootPane().setDefaultButton(buttonOK);
buttonOK.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
onOK();
}
});
buttonCancel.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
onCancel();
}
});
// call onCancel() when cross is clicked
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
onCancel();
}
});
// call onCancel() on ESCAPE
contentPane.registerKeyboardAction(new ActionListener() {
public void actionPerformed(ActionEvent e) {
onCancel();
}
}, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
}
private void onOK() {
// add your code here
dispose();
}
private void onCancel() {
// add your code here if necessary
dispose();
}
public static void main(String[] args) {
AddOrEditUrl dialog = new AddOrEditUrl();
dialog.pack();
dialog.setVisible(true);
System.exit(0);
}
}
================================================
FILE: src/main/java/com/lilittlecat/chatgpt/setting/ChatGPTSettingsComponent.java
================================================
package com.lilittlecat.chatgpt.setting;
import com.intellij.ui.components.JBLabel;
import com.intellij.ui.components.JBList;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.ui.components.JBTextArea;
import com.intellij.ui.table.JBTable;
import com.intellij.util.ui.FormBuilder;
import com.intellij.util.ui.ListTableModel;
import com.intellij.util.ui.UIUtil;
import com.lilittlecat.chatgpt.message.ChatGPTBundle;
import javax.swing.*;
/**
* @author LiLittleCat
* @link <a href="https://github.com/LiLittleCat">https://github.com/LiLittleCat</a>
* @since 2022/12/10
*/
public class ChatGPTSettingsComponent {
private final JPanel myMainPanel;
private final JBTextArea sessionToken = new JBTextArea();
private final JBTextArea defaultUrl = new JBTextArea();
private final JBTable urlTable = new JBTable();
public ChatGPTSettingsComponent() {
sessionToken.setFont(UIUtil.getLabelFont());
sessionToken.setLineWrap(true);
JBScrollPane scrollPane = new JBScrollPane(sessionToken,
ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
myMainPanel = FormBuilder.createFormBuilder()
// .addLabeledComponent(new JBLabel(ChatGPTBundle.message("setting.session.token.label")), scrollPane, 1, false)
.addLabeledComponent(new JBLabel(ChatGPTBundle.message("setting.session.token.label")), sessionToken, 1, false)
.addLabeledComponent(new JBLabel("Table"), urlTable)
.addComponentFillVertically(new JPanel(), 0)
.getPanel();
}
public JPanel getPanel() {
return myMainPanel;
}
public JComponent getPreferredFocusedComponent() {
return sessionToken;
}
public String getSessionToken() {
return sessionToken.getText();
}
public void setSessionToken(String token) {
sessionToken.setText(token);
}
}
================================================
FILE: src/main/java/com/lilittlecat/chatgpt/setting/ChatGPTSettingsConfigurable.java
================================================
package com.lilittlecat.chatgpt.setting;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.ui.cellvalidators.StatefulValidatingCellEditor;
import com.intellij.openapi.ui.cellvalidators.ValidatingTableCellRendererWrapper;
import com.intellij.openapi.ui.cellvalidators.ValidationUtils;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.*;
import com.intellij.ui.components.JBLabel;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.ui.components.JBTextArea;
import com.intellij.ui.components.fields.ExtendableTextField;
import com.intellij.ui.table.JBTable;
import com.intellij.util.messages.MessageBusConnection;
import com.intellij.util.ui.*;
import com.lilittlecat.chatgpt.action.FetchURLAction;
import com.lilittlecat.chatgpt.message.ChatGPTBundle;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.TableModelEvent;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* @author LiLittleCat
* @link <a href="https://github.com/LiLittleCat">https://github.com/LiLittleCat</a>
* @since 2022/12/10
*/
public class ChatGPTSettingsConfigurable implements SearchableConfigurable {
private MessageBusConnection connection;
// A default constructor with no arguments is required because this implementation
// is registered as an applicationConfigurable EP
public ChatGPTSettingsConfigurable() {
connection = ApplicationManager.getApplication().getMessageBus().connect();
connection.subscribe(UpdateChatGPTSettingStateTopic.TOPIC, this::refreshUI);
init();
}
private void refreshUI() {
// Update the defaultUrlComboBox
defaultUrlComboBox.removeAllItems();
List<String> items = ChatGPTSettingsState.getInstance().urlList;
for (String item : items) {
defaultUrlComboBox.addItem(item);
}
defaultUrlComboBox.setSelectedItem(ChatGPTSettingsState.getInstance().defaultUrl);
// Update the myModel
myModel.setItems(ChatGPTSettingsState.getInstance().urlList);
}
@Override
public void disposeUIResources() {
// Disconnect the message bus connection when the UI is disposed
connection.disconnect();
Disposer.dispose(myDisposable);
}
@Override
public @NotNull String getId() {
return "com.lilittlecat.chatgpt.setting.ChatGPTSettingConfigurable";
}
public void addUrl(@NotNull String url) {
if (StringUtil.isNotEmpty(url)) {
defaultUrlComboBox.addItem(url);
myModel.addRow(url);
}
}
private Disposable myDisposable = Disposer.newDisposable();
private JPanel myMainPanel;
private JBTextArea sessionToken = new JBTextArea();
private JComboBox<String> defaultUrlComboBox;
private ListTableModel<String> myModel;
private JBTable myTable;
private JComponent init() {
myModel = new ListTableModel<>() {
@Override
public void addRow() {
// add item to table
addRow("");
}
@Override
public void removeRow(int idx) {
String item = getItem(idx);
if (item.equals(ChatGPTSettingsState.getInstance().defaultUrl)) {
// popup a dialog to tell user that the default url can't be removed
JOptionPane.showMessageDialog(null, ChatGPTBundle.message("chatgpt.settings.defaultUrlCanNotBeRemoved"));
} else if (item.equals(ChatGPTBundle.message("original.url"))) {
// popup a dialog to tell user that the original url can't be removed
JOptionPane.showMessageDialog(null, ChatGPTBundle.message("chatgpt.settings.originalUrlCanNotBeRemoved"));
} else {
// remove item from table
super.removeRow(idx);
// remove item from comboBox
defaultUrlComboBox.removeItemAt(idx);
}
}
@NotNull
@Override
public List<String> getItems() {
List<String> items = super.getItems();
// change Collections.unmodifiableList to ArrayList
return new ArrayList<>(items);
}
};
// init table
myModel.addRows(ChatGPTSettingsState.getInstance().urlList);
myTable = new JBTable(myModel) {
@Override
public void editingCanceled(ChangeEvent e) {
int row = getEditingRow();
super.editingCanceled(e);
if (row >= 0 && row < myModel.getRowCount() && StringUtil.isEmpty(myModel.getRowValue(row))) {
myModel.removeRow(row);
}
}
};
JComponent table = createTable();
table.setPreferredSize(new Dimension(500, 200));
createComboBox();
sessionToken.setFont(UIUtil.getLabelFont());
sessionToken.setLineWrap(true);
JBScrollPane scrollPane = new JBScrollPane(sessionToken,
ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
myMainPanel = FormBuilder.createFormBuilder()
.addLabeledComponent(new JBLabel(ChatGPTBundle.message("setting.session.token.label")), scrollPane, 1, true)
.addLabeledComponent(new JBLabel(ChatGPTBundle.message("default.url.message")), defaultUrlComboBox, 1, false)
.addLabeledComponent(new SeparatorComponent(), new JPanel(), 1, false)
.addLabeledComponent(new JBLabel(ChatGPTBundle.message("url.list.message")), table, 3, true)
.addComponentFillVertically(new JPanel(), 0)
.getPanel();
return myMainPanel;
}
private void createComboBox() {
// get value from myTable dynamically and set first value in myTable as default value of comboBox
defaultUrlComboBox = new ComboBox<>();
Dimension preferredSize = defaultUrlComboBox.getPreferredSize();
preferredSize.width = 200; // Set the desired width here
defaultUrlComboBox.setPreferredSize(preferredSize);
List<String> items = myModel.getItems();
for (String item : items) {
defaultUrlComboBox.addItem(item);
}
defaultUrlComboBox.setSelectedItem(ChatGPTSettingsState.getInstance().defaultUrl);
}
private JComponent createTable() {
myModel.setColumnInfos(new ColumnInfo[]{new ColumnInfo<String, String>("") {
@Override
public @Nullable String valueOf(String s) {
return s;
}
@Override
public boolean isCellEditable(String s) {
return true;
}
@Override
public void setValue(String s, String value) {
int row = myTable.getSelectedRow();
if (StringUtil.isEmpty(value) && row >= 0 && row < myModel.getRowCount()) {
myModel.removeRow(row);
defaultUrlComboBox.removeItemAt(row);
}
List<String> items = new ArrayList<>(myModel.getItems());
items.set(row, value);
myModel.setItems(items);
myModel.fireTableCellUpdated(row, TableModelEvent.ALL_COLUMNS);
myTable.repaint();
// add to comboBox
defaultUrlComboBox.addItem(value);
}
}});
myTable.getColumnModel().setColumnMargin(0);
myTable.setShowColumns(false);
myTable.setShowGrid(false);
myTable.getEmptyText().setText("No websites added.");
myTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
myTable.setToolTipText("Double click to edit it");
ExtendableTextField cellEditor = new ExtendableTextField();
DefaultCellEditor editor = new StatefulValidatingCellEditor(cellEditor, myDisposable).
withStateUpdater(vi -> ValidationUtils.setExtension(cellEditor, vi));
editor.setClickCountToStart(2);
myTable.setDefaultEditor(Object.class, editor);
myTable.setDefaultRenderer(Object.class, new ValidatingTableCellRendererWrapper(new ColoredTableCellRenderer() {
{
setIpad(new JBInsets(0, 0, 0, 0));
}
@Override
protected void customizeCellRenderer(@NotNull JTable table, @Nullable Object value, boolean selected, boolean hasFocus, int row, int column) {
if (row >= 0 && row < myModel.getRowCount()) {
String prefix = myModel.getRowValue(row);
setForeground(selected ? table.getSelectionForeground() : table.getForeground());
setBackground(selected ? table.getSelectionBackground() : table.getBackground());
append(prefix, SimpleTextAttributes.REGULAR_ATTRIBUTES);
setToolTipText("Double click to edit it.");
}
}
@Override
protected SimpleTextAttributes modifyAttributes(SimpleTextAttributes attributes) {
return attributes;
}
}).bindToEditorSize(cellEditor::getPreferredSize));
AnActionButton fetchUrlListFromGithub = AnActionButton.fromAction(new FetchURLAction(ChatGPTBundle.message("chatgpt.settings.fetch.url.list.from.github")));
return ToolbarDecorator.createDecorator(myTable)
.addExtraAction(fetchUrlListFromGithub)
.disableUpDownActions()
.createPanel();
}
@Nls(capitalization = Nls.Capitalization.Title)
@Override
public String getDisplayName() {
return ChatGPTBundle.message("setting.menu.text");
}
@Override
public JComponent getPreferredFocusedComponent() {
return defaultUrlComboBox;
}
@Nullable
@Override
public JComponent createComponent() {
return myMainPanel;
}
@Override
public boolean isModified() {
ChatGPTSettingsState instance = ChatGPTSettingsState.getInstance();
boolean modified = false;
modified = !instance.defaultUrl.equals(defaultUrlComboBox.getSelectedItem());
List<String> urlList = instance.urlList;
List<String> items = myModel.getItems();
modified |= urlList.size() != items.size();
modified |= !urlList.equals(items);
modified |= !instance.sessionToken.equals(sessionToken.getText());
return modified;
}
@Override
public void apply() {
myTable.editingStopped(null);
ChatGPTSettingsState instance = ChatGPTSettingsState.getInstance();
instance.defaultUrl = Objects.requireNonNull(defaultUrlComboBox.getSelectedItem()).toString();
instance.urlList = myModel.getItems();
instance.sessionToken = sessionToken.getText();
// Refresh the UI after updating the settings
refreshUI();
// instance.urlList.addAll(myModel.getItems());
}
@Override
public void reset() {
ChatGPTSettingsState instance = ChatGPTSettingsState.getInstance();
myModel.setItems(instance.urlList);
defaultUrlComboBox.removeAllItems();
for (String s : instance.urlList) {
defaultUrlComboBox.addItem(s);
}
defaultUrlComboBox.setSelectedItem(instance.defaultUrl);
sessionToken.setText(instance.sessionToken);
}
}
================================================
FILE: src/main/java/com/lilittlecat/chatgpt/setting/ChatGPTSettingsState.java
================================================
package com.lilittlecat.chatgpt.setting;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import com.intellij.util.xmlb.XmlSerializerUtil;
import com.lilittlecat.chatgpt.message.ChatGPTBundle;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.ResourceBundle;
/**
* @author LiLittleCat
* @link <a href="https://github.com/LiLittleCat">https://github.com/LiLittleCat</a>
* @since 2022/12/10
*/
@State(
name = "com.lilittlecat.chatgpt.setting.ChatGPTSettingsState",
storages = @Storage("ChatGPTSettingsState.xml")
)
public class ChatGPTSettingsState implements PersistentStateComponent<ChatGPTSettingsState> {
public String sessionToken = "";
public String defaultUrl = ChatGPTBundle.message("default.url");
public List<String> urlList;
public ChatGPTSettingsState() {
urlList = new ArrayList<>();
urlList.add(ChatGPTBundle.message("default.url"));
// ResourceBundle bundle = ResourceBundle.getBundle(ChatGPTBundle.BUNDLE);
// Enumeration<String> keys = bundle.getKeys();
// while (keys.hasMoreElements()) {
// String key = keys.nextElement();
// if (key.startsWith("url")) {
// String url = bundle.getString(key);
// System.out.println(key + ": " + url);
// urlList.add(url);
// }
// }
}
@Nullable
@Override
public ChatGPTSettingsState getState() {
return this;
}
@Override
public void loadState(@NotNull ChatGPTSettingsState state) {
XmlSerializerUtil.copyBean(state, this);
}
// public void setSessionToken(String sessionToken) {
// this.sessionToken = sessionToken;
// }
public void setDefaultUrl(String defaultUrl) {
this.defaultUrl = defaultUrl;
}
public void setUrlList(List<String> urlList) {
this.urlList = urlList;
}
public String getSessionToken() {
return sessionToken;
}
public void setSessionToken(String sessionToken) {
this.sessionToken = sessionToken;
}
public static ChatGPTSettingsState getInstance() {
return ApplicationManager.getApplication().getService(ChatGPTSettingsState.class);
}
}
================================================
FILE: src/main/java/com/lilittlecat/chatgpt/setting/Test.form
================================================
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.lilittlecat.chatgpt.setting.Test">
<grid id="27dc6" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="408" height="400"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<grid id="e7f17" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="87bc6" class="javax.swing.JLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Default Website"/>
</properties>
</component>
<component id="89d5d" class="javax.swing.JComboBox" binding="defaultWebsite">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
<component id="7af06" class="javax.swing.JLabel">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Third Party Websites"/>
</properties>
</component>
<grid id="9f58" layout-manager="BorderLayout" hgap="0" vgap="0">
<constraints>
<grid row="2" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children/>
</grid>
</children>
</grid>
</children>
</grid>
</form>
================================================
FILE: src/main/java/com/lilittlecat/chatgpt/setting/Test.java
================================================
package com.lilittlecat.chatgpt.setting;
import com.intellij.ui.components.JBComboBoxLabel;
import javax.swing.*;
/**
* @author <a href="https://github.com/LiLittleCat">LiLittleCat</a>
* @since 2023/3/9
*/
public class Test {
private JPanel myMainPanel;
private JComboBox defaultWebsite;
private JSpinner spinner1;
}
================================================
FILE: src/main/java/com/lilittlecat/chatgpt/setting/UpdateChatGPTSettingStateTopic.java
================================================
package com.lilittlecat.chatgpt.setting;
import com.intellij.util.messages.Topic;
/**
* A topic for changing the state of the settings.
*
* @author LiLittleCat
* @link <a href="https://github.com/LiLittleCat">https://github.com/LiLittleCat</a>
* @since 2023/3/21
*/
public interface UpdateChatGPTSettingStateTopic {
Topic<UpdateChatGPTSettingStateTopic> TOPIC = Topic.create("Update Field Topic", UpdateChatGPTSettingStateTopic.class);
void stateChanged();
}
================================================
FILE: src/main/java/com/lilittlecat/chatgpt/window/ChatGPTToolWindow.java
================================================
package com.lilittlecat.chatgpt.window;
import com.intellij.openapi.ui.SimpleToolWindowPanel;
import com.intellij.ui.jcef.JBCefApp;
import com.intellij.ui.jcef.JBCefBrowser;
import com.intellij.ui.jcef.JBCefCookie;
import com.intellij.ui.jcef.JBCefCookieManager;
import com.lilittlecat.chatgpt.message.ChatGPTBundle;
import com.lilittlecat.chatgpt.setting.ChatGPTSettingsState;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.swing.*;
import javax.swing.event.HyperlinkEvent;
import java.awt.*;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* @author LiLittleCat
* @link <a href="https://github.com/LiLittleCat">https://github.com/LiLittleCat</a>
* @since 2022/12/10
*/
public class ChatGPTToolWindow extends SimpleToolWindowPanel {
private static final Logger LOG = LoggerFactory.getLogger(ChatGPTToolWindow.class);
private final JPanel content;
private final String sessionTokenName = "__Secure-next-auth.session-token";
ThreadPoolExecutor executor = new ThreadPoolExecutor(
1, 10, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<>(10));
public ChatGPTToolWindow(String url) {
super(true, false);
this.content = new JPanel(new BorderLayout());
if (!JBCefApp.isSupported()) {
JEditorPane editorPane = new JEditorPane("text/html", ChatGPTBundle.message("jBCefApp.not.supported"));
editorPane.setEditable(false);
editorPane.setOpaque(false);
editorPane.addHyperlinkListener(e -> {
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
try {
java.awt.Desktop.getDesktop().browse(e.getURL().toURI());
} catch (IOException | URISyntaxException ex) {
ex.printStackTrace();
}
}
});
JOptionPane.showMessageDialog(null, editorPane);
// this.content.add(new JLabel(ChatGPTBundle.message("jBCefApp.not.supported"), SwingConstants.CENTER));
this.content.add(editorPane, SwingConstants.CENTER);
return;
}
JBCefBrowser jbCefBrowser = new JBCefBrowser();
this.content.add(jbCefBrowser.getComponent(), BorderLayout.CENTER);
if (url.equals(ChatGPTBundle.message("default.url"))) {
setCookieForOfficalWebsite(url);
}
jbCefBrowser.loadURL(url);
}
private void setCookieForOfficalWebsite(String url) {
JBCefCookieManager jbCefCookieManager = new JBCefCookieManager();
// find if there is session token in settings
ChatGPTSettingsState state = ChatGPTSettingsState.getInstance().getState();
if (state != null) {
String sessionToken = state.sessionToken;
if (StringUtils.isNotBlank(sessionToken)) {
// check the token is right or not
// 2022.12.16 with Cloudflare, can not check token by http get
// String cookie = sessionTokenName + "=" + sessionToken;
// HttpGet httpGet = new HttpGet("https://chat.openai.com/chat");
// httpGet.setHeader("Connection", "keep-alive");
// httpGet.setHeader("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.1 Safari/605.1.15");
// httpGet.setHeader("Cookie", cookie);
// httpGet.setHeader("Origin", "https://auth0.openai.com");
// httpGet.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
// httpGet.setHeader("Accept-Language", "en-US,en;q=0.9");
// try (CloseableHttpClient httpClient = HttpClients.createDefault();
// CloseableHttpResponse httpResponse = httpClient.execute(httpGet)) {
// HttpEntity httpEntity = httpResponse.getEntity();
// String bodyString = EntityUtils.toString(httpEntity);
// if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK && !bodyString.contains("Welcome to ChatGPT")) {
JBCefCookie jbCefCookie = new JBCefCookie(sessionTokenName, sessionToken, "chat.openai.com", "/", true, true);
// use async set
jbCefCookieManager.setCookie(ChatGPTBundle.message("default.url"), jbCefCookie, false);
// }
// } catch (IOException e) {
// LOG.error("Error when check session token: ", e);
// }
}
}
// get session token after login, fill it in settings
// fill it every login, in case invalid session token cause can't login problem
executor.execute(() -> {
String currentSessionToken = null;
while (currentSessionToken == null) {
List<JBCefCookie> cookies = jbCefCookieManager.getCookies();
if (!cookies.isEmpty()) {
for (JBCefCookie cookie : cookies) {
if (cookie.getName().equals(sessionTokenName)) {
currentSessionToken = cookie.getValue();
ChatGPTSettingsState.getInstance().setSessionToken(currentSessionToken);
}
}
}
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
});
}
public JPanel getContent() {
return content;
}
}
================================================
FILE: src/main/java/com/lilittlecat/chatgpt/window/ChatGPTToolWindowFactory.java
================================================
package com.lilittlecat.chatgpt.window;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowFactory;
import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentManager;
import com.intellij.ui.content.ContentManagerEvent;
import com.intellij.ui.content.ContentManagerListener;
import com.lilittlecat.chatgpt.action.*;
import com.lilittlecat.chatgpt.message.ChatGPTBundle;
import com.lilittlecat.chatgpt.setting.ChatGPTSettingsState;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
/**
* @author LiLittleCat
* @link <a href="https://github.com/LiLittleCat">https://github.com/LiLittleCat</a>
* @since 2022/12/10
*/
public class ChatGPTToolWindowFactory implements ToolWindowFactory {
@Override
public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) {
ContentManager contentManager = toolWindow.getContentManager();
Content labelContent = contentManager.getFactory().createContent(
new ChatGPTToolWindow(ChatGPTSettingsState.getInstance().defaultUrl).getContent(),
ChatGPTSettingsState.getInstance().defaultUrl, false);
contentManager.addContent(labelContent);
contentManager.addContentManagerListener(
new ContentManagerListener() {
@Override
public void contentRemoved(@NotNull ContentManagerEvent event) {
// when all tabs are closed, add a new tab
if (contentManager.getContentCount() == 0) {
Content labelContent = contentManager.getFactory().createContent(
new ChatGPTToolWindow(ChatGPTSettingsState.getInstance().defaultUrl).getContent(),
ChatGPTSettingsState.getInstance().defaultUrl, false);
contentManager.addContent(labelContent);
}
}
}
);
// add actions to tool window
List<AnAction> anActionList = new ArrayList<>();
anActionList.add(new SettingsAction(ChatGPTBundle.message("settings.action")));
anActionList.add(new RefreshAction(ChatGPTBundle.message("refresh.action")));
anActionList.add(new AddTabAction(ChatGPTBundle.message("add.tab.action")));
anActionList.add(new GitHubAction(ChatGPTBundle.message("github.action")));
anActionList.add(new MorePluginAction(ChatGPTBundle.message("more.plugins.action")));
toolWindow.setTitleActions(anActionList);
}
}
================================================
FILE: src/main/resources/META-INF/plugin.xml
================================================
<!-- Plugin Configuration File. Read more: https://plugins.jetbrains.com/docs/intellij/plugin-configuration-file.html -->
<idea-plugin>
<id>com.lilittlecat.intellij-chatgpt</id>
<name>ChatGPT Tool</name>
<vendor email="lilittlecat@qq.com" url="https://github.com/LiLittleCat">
LiLittleCat
</vendor>
<depends>com.intellij.modules.platform</depends>
<extensions defaultExtensionNs="com.intellij">
<toolWindow factoryClass="com.lilittlecat.chatgpt.window.ChatGPTToolWindowFactory" icon="/icons/openai.svg" id="ChatGPT Tool" anchor="right" canCloseContents="true"/>
<applicationConfigurable
parentId="tools"
instance="com.lilittlecat.chatgpt.setting.ChatGPTSettingsConfigurable"
id="com.lilittlecat.chatgpt.setting.ChatGPTSettingsConfigurable"
displayName="ChatGPT Tool"/>
<applicationService serviceImplementation="com.lilittlecat.chatgpt.setting.ChatGPTSettingsState"/>
</extensions>
</idea-plugin>
================================================
FILE: src/main/resources/messages/ChatGPTBundle.properties
================================================
name=ChatGPT Tool
setting.session.token.label=Session token(only for https://chat.openai.com):
setting.menu.text=ChatGPT Tool
default.url.message=Default URL:
url.list.message=URL list:
original.url=https://chat.openai.com
default.url=https://chat.openai.com
url1=https://baidu.com
url2=https://jd.com
url3=https://bilibili.com
url4=https://douyu.com
jBCefApp.not.supported=<html><body style='text-align: center; display: flex; justify-content: center; align-items: center; height: 100%;'> \
Sorry, your IDE does not support JCEF, please use IDEA 2020.2 or later.<br>\
\ See <a href=https://plugins.jetbrains.com/docs/intellij/jcef.html?from=jetbrains.org>jcef</a> and <a href=https://github.com/LiLittleCat/intellij-chatgpt/issues/3>issue 3</a> for more details.\
</body></html>
chatgpt.settings.defaultUrlCanNotBeRemoved=Default URL can not be removed.
chatgpt.settings.originalUrlCanNotBeRemoved=Original URL can not be removed.
chatgpt.settings.fetch.url.list.from.github=Fetch URL list from GitHub
free.chatgpt.file.url.original=https://raw.githubusercontent.com/LiLittleCat/awesome-free-chatgpt/main/urls.json
free.chatgpt.file.url.fallback=https://cdn.jsdelivr.net/gh/LiLittleCat/awesome-free-chatgpt/urls.json
cannot.fetch.message=Can not fetch from remote, please check your network
success.fetch.message=Successfully fetched from remote
settings.action=Settings
refresh.action=Refresh
add.tab.action=Add Tab
github.action=Author's GitHub
github.url=https://github.com/LiLittleCat
more.plugins.action=More plugins from Author
more.plugins.url=https://plugins.jetbrains.com/organizations/LiLittleCat
================================================
FILE: src/test/testData/rename/foo.xml
================================================
<root>
<a<caret>1>Foo</a1>
</root>
================================================
FILE: src/test/testData/rename/foo_after.xml
================================================
<root>
<a2>Foo</a2>
</root>
gitextract_jsuwudpi/
├── .github/
│ ├── dependabot.yml
│ └── workflows/
│ ├── build.yml
│ ├── release.yml
│ └── run-ui-tests.yml
├── .gitignore
├── .run/
│ ├── Run IDE for UI Tests.run.xml
│ ├── Run IDE with Plugin.run.xml
│ ├── Run Plugin Tests.run.xml
│ ├── Run Plugin Verification.run.xml
│ └── Run Qodana.run.xml
├── CHANGELOG.md
├── DESCRIPTION.md
├── README.md
├── README_CN.md
├── build.gradle.kts
├── gradle/
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── qodana.yml
├── settings.gradle.kts
└── src/
├── main/
│ ├── java/
│ │ └── com/
│ │ └── lilittlecat/
│ │ └── chatgpt/
│ │ ├── action/
│ │ │ ├── AddTabAction.java
│ │ │ ├── FetchURLAction.java
│ │ │ ├── GitHubAction.java
│ │ │ ├── MorePluginAction.java
│ │ │ ├── RefreshAction.java
│ │ │ └── SettingsAction.java
│ │ ├── message/
│ │ │ └── ChatGPTBundle.java
│ │ ├── setting/
│ │ │ ├── AddOrEditUrl.form
│ │ │ ├── AddOrEditUrl.java
│ │ │ ├── ChatGPTSettingsComponent.java
│ │ │ ├── ChatGPTSettingsConfigurable.java
│ │ │ ├── ChatGPTSettingsState.java
│ │ │ ├── Test.form
│ │ │ ├── Test.java
│ │ │ └── UpdateChatGPTSettingStateTopic.java
│ │ └── window/
│ │ ├── ChatGPTToolWindow.java
│ │ └── ChatGPTToolWindowFactory.java
│ └── resources/
│ ├── META-INF/
│ │ └── plugin.xml
│ └── messages/
│ └── ChatGPTBundle.properties
└── test/
└── testData/
└── rename/
├── foo.xml
└── foo_after.xml
SYMBOL INDEX (68 symbols across 15 files)
FILE: src/main/java/com/lilittlecat/chatgpt/action/AddTabAction.java
class AddTabAction (line 26) | public class AddTabAction extends DumbAwareAction {
method AddTabAction (line 27) | public AddTabAction(@NotNull @Nls String text) {
method actionPerformed (line 31) | @Override
FILE: src/main/java/com/lilittlecat/chatgpt/action/FetchURLAction.java
class FetchURLAction (line 28) | public class FetchURLAction extends DumbAwareAction {
method FetchURLAction (line 29) | public FetchURLAction(@NotNull @Nls String text) {
method actionPerformed (line 33) | @Override
method fetchJsonArray (line 57) | private JSONArray fetchJsonArray(OkHttpClient client, String url) thro...
method processJsonArray (line 69) | private void processJsonArray(JSONArray jsonArray) {
FILE: src/main/java/com/lilittlecat/chatgpt/action/GitHubAction.java
class GitHubAction (line 15) | public class GitHubAction extends DumbAwareAction {
method GitHubAction (line 17) | public GitHubAction(@NotNull @Nls String text) {
method actionPerformed (line 21) | @Override
FILE: src/main/java/com/lilittlecat/chatgpt/action/MorePluginAction.java
class MorePluginAction (line 15) | public class MorePluginAction extends DumbAwareAction {
method MorePluginAction (line 16) | public MorePluginAction(@NotNull @Nls String text) {
method actionPerformed (line 20) | @Override
FILE: src/main/java/com/lilittlecat/chatgpt/action/RefreshAction.java
class RefreshAction (line 23) | public class RefreshAction extends DumbAwareAction {
method RefreshAction (line 24) | public RefreshAction(@NotNull @Nls String text) {
method actionPerformed (line 28) | @Override
FILE: src/main/java/com/lilittlecat/chatgpt/action/SettingsAction.java
class SettingsAction (line 16) | public class SettingsAction extends DumbAwareAction {
method SettingsAction (line 18) | public SettingsAction(@NotNull @Nls String text) {
method actionPerformed (line 22) | @Override
FILE: src/main/java/com/lilittlecat/chatgpt/message/ChatGPTBundle.java
class ChatGPTBundle (line 15) | public class ChatGPTBundle extends DynamicBundle {
method ChatGPTBundle (line 20) | private ChatGPTBundle() {
method message (line 24) | @NotNull
method messagePointer (line 29) | @NotNull
FILE: src/main/java/com/lilittlecat/chatgpt/setting/AddOrEditUrl.java
class AddOrEditUrl (line 6) | public class AddOrEditUrl extends JDialog {
method AddOrEditUrl (line 12) | public AddOrEditUrl() {
method onOK (line 45) | private void onOK() {
method onCancel (line 50) | private void onCancel() {
method main (line 55) | public static void main(String[] args) {
FILE: src/main/java/com/lilittlecat/chatgpt/setting/ChatGPTSettingsComponent.java
class ChatGPTSettingsComponent (line 20) | public class ChatGPTSettingsComponent {
method ChatGPTSettingsComponent (line 26) | public ChatGPTSettingsComponent() {
method getPanel (line 40) | public JPanel getPanel() {
method getPreferredFocusedComponent (line 44) | public JComponent getPreferredFocusedComponent() {
method getSessionToken (line 48) | public String getSessionToken() {
method setSessionToken (line 52) | public void setSessionToken(String token) {
FILE: src/main/java/com/lilittlecat/chatgpt/setting/ChatGPTSettingsConfigurable.java
class ChatGPTSettingsConfigurable (line 39) | public class ChatGPTSettingsConfigurable implements SearchableConfigurab...
method ChatGPTSettingsConfigurable (line 45) | public ChatGPTSettingsConfigurable() {
method refreshUI (line 51) | private void refreshUI() {
method disposeUIResources (line 64) | @Override
method getId (line 71) | @Override
method addUrl (line 76) | public void addUrl(@NotNull String url) {
method init (line 93) | private JComponent init() {
method createComboBox (line 159) | private void createComboBox() {
method createTable (line 172) | private JComponent createTable() {
method getDisplayName (line 245) | @Nls(capitalization = Nls.Capitalization.Title)
method getPreferredFocusedComponent (line 251) | @Override
method createComponent (line 256) | @Nullable
method isModified (line 262) | @Override
method apply (line 275) | @Override
method reset (line 287) | @Override
FILE: src/main/java/com/lilittlecat/chatgpt/setting/ChatGPTSettingsState.java
class ChatGPTSettingsState (line 22) | @State(
method ChatGPTSettingsState (line 34) | public ChatGPTSettingsState() {
method getState (line 49) | @Nullable
method loadState (line 55) | @Override
method setDefaultUrl (line 64) | public void setDefaultUrl(String defaultUrl) {
method setUrlList (line 68) | public void setUrlList(List<String> urlList) {
method getSessionToken (line 72) | public String getSessionToken() {
method setSessionToken (line 76) | public void setSessionToken(String sessionToken) {
method getInstance (line 80) | public static ChatGPTSettingsState getInstance() {
FILE: src/main/java/com/lilittlecat/chatgpt/setting/Test.java
class Test (line 11) | public class Test {
FILE: src/main/java/com/lilittlecat/chatgpt/setting/UpdateChatGPTSettingStateTopic.java
type UpdateChatGPTSettingStateTopic (line 12) | public interface UpdateChatGPTSettingStateTopic {
method stateChanged (line 15) | void stateChanged();
FILE: src/main/java/com/lilittlecat/chatgpt/window/ChatGPTToolWindow.java
class ChatGPTToolWindow (line 31) | public class ChatGPTToolWindow extends SimpleToolWindowPanel {
method ChatGPTToolWindow (line 41) | public ChatGPTToolWindow(String url) {
method setCookieForOfficalWebsite (line 70) | private void setCookieForOfficalWebsite(String url) {
method getContent (line 126) | public JPanel getContent() {
FILE: src/main/java/com/lilittlecat/chatgpt/window/ChatGPTToolWindowFactory.java
class ChatGPTToolWindowFactory (line 24) | public class ChatGPTToolWindowFactory implements ToolWindowFactory {
method createToolWindowContent (line 25) | @Override
Condensed preview — 43 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (103K chars).
[
{
"path": ".github/dependabot.yml",
"chars": 511,
"preview": "# Dependabot configuration:\n# https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/configur"
},
{
"path": ".github/workflows/build.yml",
"chars": 6005,
"preview": "# GitHub Actions Workflow created for testing and preparing the plugin release in following steps:\n# - validate Gradle W"
},
{
"path": ".github/workflows/release.yml",
"chars": 3200,
"preview": "# GitHub Actions Workflow created for handling the release process based on the draft release prepared\n# with the Build "
},
{
"path": ".github/workflows/run-ui-tests.yml",
"chars": 1614,
"preview": "# GitHub Actions Workflow for launching UI tests on Linux, Windows, and Mac in the following steps:\n# - prepare and laun"
},
{
"path": ".gitignore",
"chars": 28,
"preview": ".gradle\n.idea\n.qodana\nbuild\n"
},
{
"path": ".run/Run IDE for UI Tests.run.xml",
"chars": 976,
"preview": "<component name=\"ProjectRunConfigurationManager\">\n <configuration default=\"false\" name=\"Run IDE for UI Tests\" type=\"Gra"
},
{
"path": ".run/Run IDE with Plugin.run.xml",
"chars": 1009,
"preview": "<component name=\"ProjectRunConfigurationManager\">\n <configuration default=\"false\" name=\"Run Plugin\" type=\"GradleRunConf"
},
{
"path": ".run/Run Plugin Tests.run.xml",
"chars": 1008,
"preview": "<component name=\"ProjectRunConfigurationManager\">\n <configuration default=\"false\" name=\"Run Tests\" type=\"GradleRunConfi"
},
{
"path": ".run/Run Plugin Verification.run.xml",
"chars": 1182,
"preview": "<component name=\"ProjectRunConfigurationManager\">\n <configuration default=\"false\" name=\"Run Verifications\" type=\"Gradle"
},
{
"path": ".run/Run Qodana.run.xml",
"chars": 1016,
"preview": "<component name=\"ProjectRunConfigurationManager\">\n <configuration default=\"false\" name=\"Run Qodana\" type=\"GradleRunConf"
},
{
"path": "CHANGELOG.md",
"chars": 1718,
"preview": "<!-- Keep a Changelog guide -> https://keepachangelog.com -->\n\n# intellij-chatgpt Changelog\n\n## [Unreleased]\n\n## [1.1.1]"
},
{
"path": "DESCRIPTION.md",
"chars": 2363,
"preview": "\n<!-- Plugin description -->\n\nThis Jetbrains IDEs plugin integrates [ChatGPT](https://chat.openai.com/) and [other third"
},
{
"path": "README.md",
"chars": 4045,
"preview": "<img src=\"src/main/resources/META-INF/pluginIcon.svg\" align=\"right\" width=\"128\" height=\"128\" alt=\"icon\"/>\n\n# ChatGPT Too"
},
{
"path": "README_CN.md",
"chars": 2755,
"preview": "<img src=\"src/main/resources/META-INF/pluginIcon.svg\" align=\"right\" width=\"128\" height=\"128\" alt=\"icon\"/>\n\n# ChatGPT Too"
},
{
"path": "build.gradle.kts",
"chars": 4904,
"preview": "import org.jetbrains.changelog.Changelog\nimport org.jetbrains.changelog.markdownToHTML\nimport org.jetbrains.kotlin.gradl"
},
{
"path": "gradle/wrapper/gradle-wrapper.properties",
"chars": 202,
"preview": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributi"
},
{
"path": "gradle.properties",
"chars": 1470,
"preview": "# IntelliJ Platform Artifacts Repositories -> https://plugins.jetbrains.com/docs/intellij/intellij-artifacts.html\n\nplugi"
},
{
"path": "gradlew",
"chars": 8165,
"preview": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"Lice"
},
{
"path": "gradlew.bat",
"chars": 2747,
"preview": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \""
},
{
"path": "qodana.yml",
"chars": 181,
"preview": "# Qodana configuration:\n# https://www.jetbrains.com/help/qodana/qodana-yaml.html\n\nversion: 1.0\nprofile:\n name: qodana.r"
},
{
"path": "settings.gradle.kts",
"chars": 38,
"preview": "rootProject.name = \"intellij-chatgpt\"\n"
},
{
"path": "src/main/java/com/lilittlecat/chatgpt/action/AddTabAction.java",
"chars": 2071,
"preview": "package com.lilittlecat.chatgpt.action;\n\nimport com.intellij.icons.AllIcons;\nimport com.intellij.openapi.actionSystem.An"
},
{
"path": "src/main/java/com/lilittlecat/chatgpt/action/FetchURLAction.java",
"chars": 3796,
"preview": "package com.lilittlecat.chatgpt.action;\n\nimport com.intellij.icons.AllIcons;\nimport com.intellij.openapi.actionSystem.An"
},
{
"path": "src/main/java/com/lilittlecat/chatgpt/action/GitHubAction.java",
"chars": 770,
"preview": "package com.lilittlecat.chatgpt.action;\n\nimport com.intellij.icons.AllIcons;\nimport com.intellij.ide.BrowserUtil;\nimport"
},
{
"path": "src/main/java/com/lilittlecat/chatgpt/action/MorePluginAction.java",
"chars": 777,
"preview": "package com.lilittlecat.chatgpt.action;\n\nimport com.intellij.icons.AllIcons;\nimport com.intellij.ide.BrowserUtil;\nimport"
},
{
"path": "src/main/java/com/lilittlecat/chatgpt/action/RefreshAction.java",
"chars": 3361,
"preview": "package com.lilittlecat.chatgpt.action;\n\nimport com.intellij.icons.AllIcons;\nimport com.intellij.openapi.actionSystem.An"
},
{
"path": "src/main/java/com/lilittlecat/chatgpt/action/SettingsAction.java",
"chars": 889,
"preview": "package com.lilittlecat.chatgpt.action;\n\nimport com.intellij.icons.AllIcons;\nimport com.intellij.openapi.actionSystem.An"
},
{
"path": "src/main/java/com/lilittlecat/chatgpt/message/ChatGPTBundle.java",
"chars": 1054,
"preview": "package com.lilittlecat.chatgpt.message;\n\nimport com.intellij.DynamicBundle;\nimport org.jetbrains.annotations.Nls;\nimpor"
},
{
"path": "src/main/java/com/lilittlecat/chatgpt/setting/AddOrEditUrl.form",
"chars": 4442,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<form xmlns=\"http://www.intellij.com/uidesigner/form/\" version=\"1\" bind-to-class="
},
{
"path": "src/main/java/com/lilittlecat/chatgpt/setting/AddOrEditUrl.java",
"chars": 1687,
"preview": "package com.lilittlecat.chatgpt.setting;\n\nimport javax.swing.*;\nimport java.awt.event.*;\n\npublic class AddOrEditUrl exte"
},
{
"path": "src/main/java/com/lilittlecat/chatgpt/setting/ChatGPTSettingsComponent.java",
"chars": 1984,
"preview": "package com.lilittlecat.chatgpt.setting;\n\nimport com.intellij.ui.components.JBLabel;\nimport com.intellij.ui.components.J"
},
{
"path": "src/main/java/com/lilittlecat/chatgpt/setting/ChatGPTSettingsConfigurable.java",
"chars": 11953,
"preview": "package com.lilittlecat.chatgpt.setting;\n\nimport com.intellij.openapi.Disposable;\nimport com.intellij.openapi.applicatio"
},
{
"path": "src/main/java/com/lilittlecat/chatgpt/setting/ChatGPTSettingsState.java",
"chars": 2523,
"preview": "package com.lilittlecat.chatgpt.setting;\n\nimport com.intellij.openapi.application.ApplicationManager;\nimport com.intelli"
},
{
"path": "src/main/java/com/lilittlecat/chatgpt/setting/Test.form",
"chars": 2634,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<form xmlns=\"http://www.intellij.com/uidesigner/form/\" version=\"1\" bind-to-class="
},
{
"path": "src/main/java/com/lilittlecat/chatgpt/setting/Test.java",
"chars": 335,
"preview": "package com.lilittlecat.chatgpt.setting;\n\nimport com.intellij.ui.components.JBComboBoxLabel;\n\nimport javax.swing.*;\n\n/**"
},
{
"path": "src/main/java/com/lilittlecat/chatgpt/setting/UpdateChatGPTSettingStateTopic.java",
"chars": 476,
"preview": "package com.lilittlecat.chatgpt.setting;\n\nimport com.intellij.util.messages.Topic;\n\n/**\n * A topic for changing the stat"
},
{
"path": "src/main/java/com/lilittlecat/chatgpt/window/ChatGPTToolWindow.java",
"chars": 5868,
"preview": "package com.lilittlecat.chatgpt.window;\n\n\nimport com.intellij.openapi.ui.SimpleToolWindowPanel;\nimport com.intellij.ui.j"
},
{
"path": "src/main/java/com/lilittlecat/chatgpt/window/ChatGPTToolWindowFactory.java",
"chars": 2748,
"preview": "package com.lilittlecat.chatgpt.window;\n\nimport com.intellij.openapi.actionSystem.AnAction;\nimport com.intellij.openapi."
},
{
"path": "src/main/resources/META-INF/plugin.xml",
"chars": 1023,
"preview": "<!-- Plugin Configuration File. Read more: https://plugins.jetbrains.com/docs/intellij/plugin-configuration-file.html --"
},
{
"path": "src/main/resources/messages/ChatGPTBundle.properties",
"chars": 1619,
"preview": "name=ChatGPT Tool\nsetting.session.token.label=Session token(only for https://chat.openai.com):\nsetting.menu.text=ChatGPT"
},
{
"path": "src/test/testData/rename/foo.xml",
"chars": 39,
"preview": "<root>\n <a<caret>1>Foo</a1>\n</root>\n"
},
{
"path": "src/test/testData/rename/foo_after.xml",
"chars": 32,
"preview": "<root>\n <a2>Foo</a2>\n</root>\n"
}
]
// ... and 1 more files (download for full content)
About this extraction
This page contains the full source code of the LiLittleCat/intellij-chatgpt GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 43 files (93.0 KB), approximately 24.3k tokens, and a symbol index with 68 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.