Search code examples
pythonsublimetextopenai-apisublime-text-plugin

CodeGPT Sublime Text Plugin


I recently developed a ChatGPT plugin for Sublime Text, which is designed to enhance the coding experience by enabling users to directly send snippets of code along with specific questions to ChatGPT. This integration aims to provide quick and intelligent responses, facilitating smoother coding workflows.

However I am encountering display issues in Sublime Text where the formatting of ChatGPT's responses is not rendered correctly.

import os
import sublime
import sublime_plugin
import http.client
import requests
import json

OPENAI_API_KEY = ""

class SendToGptCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        # Capture the selected text
        self.selected_text = ''
        for region in self.view.sel():
            if not region.empty():
                self.selected_text = self.view.substr(region)
        
        # Prompt the user for additional input
        self.view.window().show_input_panel("Enter your question:", "", self.on_done, None, None)

    def on_done(self, user_input):
        code = textwrap.dedent(self.selected_text)

        # Combine the user's question with the selected text
        data = {
            'code': code,
            'question': user_input
        }

        # Send the data as an HTTP request
        self.send_http_request(data)

    def send_http_request(self, data):
        url = 'https://api.openai.com/v1/chat/completions'
        headers = {
            'Content-Type': 'application/json',
            'Authorization': f'Bearer {OPENAI_API_KEY}'
        }

        req = {
            'model': 'gpt-3.5-turbo',
            'messages': [
                {
                    'role': 'system',
                    'content': 'You are a helpful coding assistant.'
                },
                {
                    'role': 'system',
                    'content': f"context code:```{data['code']}```"
                },
                {
                    'role': 'user',
                    'content': f"question: {data['question']}"
                }
            ]
        }

        # Initialize result
        result = ""
        
        try:
            response = requests.post(url, headers=headers, data=json.dumps(req))
            response.raise_for_status()  # Raise exception if the request was not successful
            response_json = response.json()

            # Get the HTTP response and extract the completion
            if 'choices' in response_json:
                choices = response_json['choices']
                messages = []  # List to store messages

                for choice in choices:
                    # Extract 'message' from each choice
                    if 'message' in choice:
                        messages.append(choice['message']['content'])
                    else:
                        messages.append("message field not found in choice")
                
                # Join messages into a single string
                result = " ".join(messages)

            else:
                result = "Choices field not found in response"

        except (requests.RequestException, json.JSONDecodeError) as err:
            result = f"Error occurred during request: {str(err)}"
        
        self.display_result(data['question'], data['code'], result)

    def display_result(self, question, code, result):
        # Create a new buffer (tab)
        new_view = self.view.window().new_file()

        # Set the syntax to Markdown
        new_view.set_syntax_file("Packages/Markdown/Markdown.sublime-syntax")
        
        # Insert the question, code, and response
        content = f"""Question Asked:\n\n{question}\n\n"""
        new_view.run_command('insert', {'characters': content})

        content = f"""Code:\n{code}\n\n"""
        new_view.run_command('insert', {'characters': content})

        content = f"""Response:\n{result}\n\n"""
        new_view.run_command('insert', {'characters': content})

Here is the response:

Question Asked:

Lets test this code ?

Code:
def display_result(self, question, code, result):
    print(code)
        code = textwrap.dedent(code)
            print(code)
                # Create a new buffer (tab)
                    new_view = self.view.window().new_file()

                        # Set the syntax to Markdown
                            new_view.set_syntax_file("Packages/Markdown/Markdown.sublime-syntax")

                                # Insert the question, code, and response
                                    content = f"""Question Asked:\n\n{question}\n\n"""
                                        new_view.run_command('insert', {'characters': content})

                                            content = f"""Code:\n{code}\n\n"""
                                                new_view.run_command('insert', {'characters': content})

                                                    content = f"""Response:\n{result}\n\n"""
                                                        new_view.run_command('insert', {'characters': content})

                                                        Response:
                                                        Sure, please provide the code that you would like to test.

                                                        

This is what the response should look like.

Question Asked:

Lets test this code ?

Code:
def display_result(self, question, code, result):
    print(code)
    code = textwrap.dedent(code)
    print(code)
    # Create a new buffer (tab)
    new_view = self.view.window().new_file()

    # Set the syntax to Markdown
    new_view.set_syntax_file("Packages/Markdown/Markdown.sublime-syntax")

    # Insert the question, code, and response
    content = f"""Question Asked:\n\n{question}\n\n"""
    new_view.run_command('insert', {'characters': content})

    content = f"""Code:\n{code}\n\n"""
    new_view.run_command('insert', {'characters': content})

    content = f"""Response:\n{result}\n\n"""
    new_view.run_command('insert', {'characters': content})

Response:
Sure, please provide the code that you would like to test.

Im not sure why there are all these extra spaces/tabs.

Thanks for the help.


Solution

  • Use 'append' instead of 'insert' or turn auto indentation off: new_view.settings().set('auto_indent', False)