changes for a better approach
This commit is contained in:
15
.chatgpt_config.yaml
Normal file
15
.chatgpt_config.yaml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
initial_prompt: |
|
||||||
|
You are a coding assistant who receives a project’s context and user instructions. The user will provide a prompt, and you will return modifications to the project in a YAML structure. This YAML must have a top-level key named files, which should be a list of file changes. Each element in files must be a mapping with the keys path and content. The path should be the file path relative to the project’s root directory, and content should contain the new file content as a multiline string (using the YAML | literal style). Do not include additional commentary outside of the YAML.
|
||||||
|
Here is the structure expected in your final answer:
|
||||||
|
files:
|
||||||
|
- path: "relative/path/to/file1.ext"
|
||||||
|
content: |
|
||||||
|
<full file content here>
|
||||||
|
- path: "relative/path/to/file2.ext"
|
||||||
|
content: |
|
||||||
|
<full file content here>
|
||||||
|
Based on the prompt and project context provided, you must only return the YAML structure shown above (with actual file paths and contents substituted in). Any file that should be created or modified must appear as one of the files entries. The content should contain the complete and final code for that file, reflecting all changes requested by the user.
|
||||||
|
|
||||||
|
directories:
|
||||||
|
- "lua"
|
||||||
|
- "plugin"
|
||||||
39
README.md
39
README.md
@@ -1,29 +1,20 @@
|
|||||||
# ChatGPT NeoVim Plugin
|
<!-- README.md -->
|
||||||
|
# ChatGPT NeoVim Plugin (Updated for YAML)
|
||||||
|
|
||||||
This plugin helps integrate the ChatGPT O1 model into the development workflow with Neovim.
|
This plugin integrates a ChatGPT O1 model workflow into Neovim. It allows you to generate prompts containing:
|
||||||
It provides one main interactive command: `:ChatGPT`.
|
- An **initial prompt** configured via a `.chatgpt_config.yaml` file in your project root.
|
||||||
|
- A list of directories (also specified in the `.chatgpt_config.yaml`) from which it gathers the complete project structure and file contents.
|
||||||
|
- The current file and the project's `README.md`, if present.
|
||||||
|
- It uses YAML for configuration and also expects the ChatGPT response in YAML.
|
||||||
|
|
||||||
## :ChatGPT
|
It also respects `.gitignore` entries, skipping those files from the prompt.
|
||||||
|
|
||||||
**Workflow:**
|
## Configuration
|
||||||
|
|
||||||
1. **Initial Prompt:**
|
Create a `.chatgpt_config.yaml` in your project root. For example:
|
||||||
When you run `:ChatGPT`, the plugin asks you for a prompt. After entering the prompt, it gathers context:
|
|
||||||
- The project structure based on the git repository of the currently open file.
|
|
||||||
- The `README.md` file content if it exists at the project root.
|
|
||||||
- The currently open file’s content.
|
|
||||||
|
|
||||||
It then constructs a combined prompt and automatically copies it to your system clipboard. You will be instructed to paste this prompt into the ChatGPT O1 model’s website.
|
```yaml
|
||||||
|
initial_prompt: "You are a helpful coding assistant that follows instructions meticulously."
|
||||||
2. **Pasting Prompt into ChatGPT:**
|
directories:
|
||||||
Switch to your browser, paste the prompt into ChatGPT’s interface, and submit it. ChatGPT will return one or multiple code blocks. Each code block should start with the file path on the first line, followed by the code.
|
- "lua"
|
||||||
|
- "plugin"
|
||||||
3. **Interactive File Pasting:**
|
|
||||||
Return to Neovim. After pressing `<Enter>`, the plugin enters an interactive mode:
|
|
||||||
- It will prompt you to copy the file path (the first line of the returned code block) into your clipboard and press `<Enter>`.
|
|
||||||
- Once you do that, it will store that file path.
|
|
||||||
- Next, it will ask you to copy the file content (the rest of the returned code block) to your clipboard and press `<Enter>` again.
|
|
||||||
- The plugin will then write the pasted content into the file specified by the previously stored path.
|
|
||||||
- After this file is processed, it asks if you want to paste another file. Press `y` to process another file (repeat the steps above) or `n` to finish.
|
|
||||||
|
|
||||||
By following this interactive workflow, you can iteratively apply all changes suggested by ChatGPT O1 model directly into your project files without leaving Neovim.
|
|
||||||
|
|||||||
51
lua/chatgpt_nvim/config.lua
Normal file
51
lua/chatgpt_nvim/config.lua
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
-- lua/chatgpt_nvim/config.lua
|
||||||
|
-- Changed to use YAML for configuration instead of JSON.
|
||||||
|
-- Reads from .chatgpt_config.yaml and uses lyaml to parse it.
|
||||||
|
-- If no config file is found, uses default values.
|
||||||
|
|
||||||
|
local M = {}
|
||||||
|
local uv = vim.loop
|
||||||
|
|
||||||
|
-- Attempt to require lyaml for YAML parsing.
|
||||||
|
-- Make sure lyaml is installed (e.g., via luarocks install lyaml)
|
||||||
|
local ok_yaml, lyaml = pcall(require, "lyaml")
|
||||||
|
|
||||||
|
local function get_config_path()
|
||||||
|
local cwd = vim.fn.getcwd()
|
||||||
|
local config_path = cwd .. "/.chatgpt_config.yaml"
|
||||||
|
return config_path
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.load()
|
||||||
|
local path = get_config_path()
|
||||||
|
local fd = uv.fs_open(path, "r", 438) -- 438 = 0o666
|
||||||
|
if not fd then
|
||||||
|
-- Return some default configuration if no file found
|
||||||
|
return {
|
||||||
|
initial_prompt = "",
|
||||||
|
directories = { "." },
|
||||||
|
}
|
||||||
|
end
|
||||||
|
local stat = uv.fs_fstat(fd)
|
||||||
|
local data = uv.fs_read(fd, stat.size, 0)
|
||||||
|
uv.fs_close(fd)
|
||||||
|
if data and ok_yaml then
|
||||||
|
local ok, result = pcall(lyaml.load, data)
|
||||||
|
if ok and type(result) == "table" then
|
||||||
|
local config = result[1]
|
||||||
|
if type(config) == "table" then
|
||||||
|
return {
|
||||||
|
initial_prompt = config.initial_prompt or "",
|
||||||
|
directories = config.directories or { "." },
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- Fallback if decode fails
|
||||||
|
return {
|
||||||
|
initial_prompt = "",
|
||||||
|
directories = { "." },
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
||||||
@@ -1,61 +1,134 @@
|
|||||||
|
-- lua/chatgpt_nvim/context.lua
|
||||||
|
-- Modified to:
|
||||||
|
-- 1) Use directories from config to build project structure.
|
||||||
|
-- 2) Include file contents from those directories.
|
||||||
|
-- 3) Skip files listed in .gitignore.
|
||||||
|
--
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
|
local uv = vim.loop
|
||||||
|
|
||||||
|
-- Returns a set of files mentioned in .gitignore patterns.
|
||||||
|
local function load_gitignore_patterns(root)
|
||||||
|
local gitignore_path = root .. "/.gitignore"
|
||||||
|
local fd = uv.fs_open(gitignore_path, "r", 438)
|
||||||
|
if not fd then
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
local stat = uv.fs_fstat(fd)
|
||||||
|
local data = uv.fs_read(fd, stat.size, 0)
|
||||||
|
uv.fs_close(fd)
|
||||||
|
if not data then return {} end
|
||||||
|
local patterns = {}
|
||||||
|
for line in data:gmatch("[^\r\n]+") do
|
||||||
|
line = line:match("^%s*(.-)%s*$") -- trim
|
||||||
|
if line ~= "" and not line:match("^#") then
|
||||||
|
patterns[#patterns+1] = line
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return patterns
|
||||||
|
end
|
||||||
|
|
||||||
|
local function should_ignore_file(file, ignore_patterns)
|
||||||
|
for _, pattern in ipairs(ignore_patterns) do
|
||||||
|
-- Simple pattern matching. For more complex patterns, consider using lua patterns.
|
||||||
|
-- This is a basic implementation. Adjust as needed.
|
||||||
|
if file:find(pattern, 1, true) then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
local function scandir(dir, ignore_patterns, files)
|
||||||
|
files = files or {}
|
||||||
|
local fd = uv.fs_opendir(dir, nil, 50)
|
||||||
|
if not fd then return files end
|
||||||
|
while true do
|
||||||
|
local ents = uv.fs_readdir(fd)
|
||||||
|
if not ents then break end
|
||||||
|
for _, ent in ipairs(ents) do
|
||||||
|
local fullpath = dir .. "/" .. ent.name
|
||||||
|
if not should_ignore_file(fullpath, ignore_patterns) then
|
||||||
|
if ent.type == "file" then
|
||||||
|
table.insert(files, fullpath)
|
||||||
|
elseif ent.type == "directory" and ent.name ~= ".git" then
|
||||||
|
scandir(fullpath, ignore_patterns, files)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
uv.fs_closedir(fd)
|
||||||
|
return files
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.get_project_files(directories)
|
||||||
|
local root = vim.fn.getcwd()
|
||||||
|
local ignore_patterns = load_gitignore_patterns(root)
|
||||||
|
local all_files = {}
|
||||||
|
for _, dir in ipairs(directories) do
|
||||||
|
local abs_dir = dir
|
||||||
|
if not abs_dir:match("^/") then
|
||||||
|
abs_dir = root .. "/" .. dir
|
||||||
|
end
|
||||||
|
scandir(abs_dir, ignore_patterns, all_files)
|
||||||
|
end
|
||||||
|
return all_files
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.get_project_structure(directories)
|
||||||
|
local files = M.get_project_files(directories)
|
||||||
|
-- Create a listing of files only (relative to root)
|
||||||
|
local root = vim.fn.getcwd()
|
||||||
|
local rel_files = {}
|
||||||
|
for _, f in ipairs(files) do
|
||||||
|
local rel = f:gsub("^" .. root .. "/", "")
|
||||||
|
table.insert(rel_files, rel)
|
||||||
|
end
|
||||||
|
|
||||||
|
local structure = "Files:\n" .. table.concat(rel_files, "\n")
|
||||||
|
return structure
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.get_file_contents(files)
|
||||||
|
local root = vim.fn.getcwd()
|
||||||
|
local sections = {}
|
||||||
|
for _, f in ipairs(files) do
|
||||||
|
local fd = uv.fs_open(root .. "/" .. f, "r", 438)
|
||||||
|
if fd then
|
||||||
|
local stat = uv.fs_fstat(fd)
|
||||||
|
local data = uv.fs_read(fd, stat.size, 0)
|
||||||
|
uv.fs_close(fd)
|
||||||
|
if data then
|
||||||
|
table.insert(sections, "\n<<<CGPT Current File\n" .. (root .. "/" .. f) .. "\n" .. data .. "\n<<<CGPT Current File END\n")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return table.concat(sections, "\n")
|
||||||
|
end
|
||||||
|
|
||||||
function M.get_current_file()
|
function M.get_current_file()
|
||||||
local buf = vim.api.nvim_get_current_buf()
|
local current_path = vim.fn.expand("%:p")
|
||||||
local path = vim.api.nvim_buf_get_name(buf)
|
if current_path == "" then
|
||||||
if path == "" then
|
return nil, nil
|
||||||
path = "untitled"
|
|
||||||
end
|
end
|
||||||
local lines = vim.api.nvim_buf_get_lines(buf, 0, -1, false)
|
local fd = uv.fs_open(current_path, "r", 438)
|
||||||
local content = table.concat(lines, "\n")
|
if not fd then return nil, current_path end
|
||||||
return content, path
|
local stat = uv.fs_fstat(fd)
|
||||||
end
|
local data = uv.fs_read(fd, stat.size, 0)
|
||||||
|
uv.fs_close(fd)
|
||||||
function M.get_project_structure()
|
return data, current_path
|
||||||
local handle = io.popen("git ls-files 2>/dev/null")
|
|
||||||
if handle then
|
|
||||||
local result = handle:read("*a")
|
|
||||||
handle:close()
|
|
||||||
if result and result ~= "" then
|
|
||||||
return "Files:\n" .. result
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local dhandle = io.popen("find . -type f")
|
|
||||||
if dhandle then
|
|
||||||
local dresult = dhandle:read("*a")
|
|
||||||
dhandle:close()
|
|
||||||
return "Files:\n" .. (dresult or "")
|
|
||||||
end
|
|
||||||
|
|
||||||
return "No files found."
|
|
||||||
end
|
|
||||||
|
|
||||||
local function get_git_root()
|
|
||||||
local handle = io.popen("git rev-parse --show-toplevel 2>/dev/null")
|
|
||||||
if handle then
|
|
||||||
local root = handle:read("*l")
|
|
||||||
handle:close()
|
|
||||||
return root
|
|
||||||
end
|
|
||||||
return nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.get_readme_content()
|
function M.get_readme_content()
|
||||||
local root = get_git_root()
|
local root = vim.fn.getcwd()
|
||||||
if not root then
|
local fd = uv.fs_open(root .. "/README.md", "r", 438)
|
||||||
return nil
|
if not fd then return nil end
|
||||||
end
|
local stat = uv.fs_fstat(fd)
|
||||||
local readme_path = root .. "/README.md"
|
local data = uv.fs_read(fd, stat.size, 0)
|
||||||
local f = io.open(readme_path, "r")
|
uv.fs_close(fd)
|
||||||
if f then
|
return data
|
||||||
local content = f:read("*a")
|
|
||||||
f:close()
|
|
||||||
if content and content ~= "" then
|
|
||||||
return content
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|||||||
@@ -1,29 +1,25 @@
|
|||||||
|
-- lua/chatgpt_nvim/handler.lua
|
||||||
|
-- No major changes needed, just ensure it can be reused for the new command.
|
||||||
|
-- Ensuring we have get_clipboard_content and write_file as is.
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
-- Retrieves clipboard content and trims trailing whitespace/newlines
|
|
||||||
function M.get_clipboard_content()
|
function M.get_clipboard_content()
|
||||||
local content = vim.fn.getreg('+')
|
return vim.fn.getreg('+')
|
||||||
content = content:gsub("%s+$", "")
|
|
||||||
return content
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.write_file(filepath, content)
|
function M.write_file(filepath, content)
|
||||||
local dir = filepath:match("(.*/)")
|
local fd = vim.loop.fs_open(filepath, "w", 438)
|
||||||
if dir and dir ~= "" then
|
if not fd then
|
||||||
vim.fn.mkdir(dir, "p")
|
vim.api.nvim_err_writeln("Could not open file: " .. filepath)
|
||||||
end
|
return
|
||||||
|
|
||||||
local f = io.open(filepath, "w")
|
|
||||||
if f then
|
|
||||||
f:write(content)
|
|
||||||
f:close()
|
|
||||||
else
|
|
||||||
vim.api.nvim_err_writeln("Failed to write file: " .. filepath)
|
|
||||||
end
|
end
|
||||||
|
vim.loop.fs_write(fd, content, -1)
|
||||||
|
vim.loop.fs_close(fd)
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.finish()
|
function M.finish()
|
||||||
print("All files processed. You can now continue working.")
|
print("Finished processing files.")
|
||||||
end
|
end
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|||||||
@@ -1,89 +1,97 @@
|
|||||||
|
-- lua/chatgpt_nvim/init.lua
|
||||||
|
-- Modified to:
|
||||||
|
-- 1) Use YAML for config and response parsing.
|
||||||
|
-- 2) Assume ChatGPT response is YAML of form:
|
||||||
|
-- files:
|
||||||
|
-- - path: "somefile.lua"
|
||||||
|
-- content: |
|
||||||
|
-- multi line
|
||||||
|
-- content
|
||||||
|
--
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
local context = require('chatgpt_nvim.context')
|
local context = require('chatgpt_nvim.context')
|
||||||
local handler = require('chatgpt_nvim.handler')
|
local handler = require('chatgpt_nvim.handler')
|
||||||
|
local config = require('chatgpt_nvim.config')
|
||||||
|
|
||||||
|
local ok_yaml, lyaml = pcall(require, "lyaml")
|
||||||
|
|
||||||
|
local function copy_to_clipboard(text)
|
||||||
|
vim.fn.setreg('+', text)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Parse the response from ChatGPT in YAML.
|
||||||
|
local function parse_response(raw)
|
||||||
|
if not ok_yaml then
|
||||||
|
vim.api.nvim_err_writeln("lyaml is not available. Please install lyaml for YAML parsing.")
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
local ok, data = pcall(lyaml.load, raw)
|
||||||
|
if not ok or not data then
|
||||||
|
vim.api.nvim_err_writeln("Failed to parse YAML response.")
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
-- lyaml.load returns a list of documents. We assume only one document is given.
|
||||||
|
data = data[1]
|
||||||
|
return data
|
||||||
|
end
|
||||||
|
|
||||||
function M.run_chatgpt_command()
|
function M.run_chatgpt_command()
|
||||||
-- Prompt the user for input
|
local conf = config.load()
|
||||||
local user_input = vim.fn.input("Message for O1 Model: ")
|
local user_input = vim.fn.input("Message for O1 Model: ")
|
||||||
if user_input == "" then
|
if user_input == "" then
|
||||||
print("No input provided.")
|
print("No input provided.")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local project_structure = context.get_project_structure()
|
local dirs = conf.directories or {"."}
|
||||||
|
local project_structure = context.get_project_structure(dirs)
|
||||||
|
local all_files = context.get_project_files(dirs)
|
||||||
|
local file_sections = context.get_file_contents(all_files)
|
||||||
local current_file_content, current_file_path = context.get_current_file()
|
local current_file_content, current_file_path = context.get_current_file()
|
||||||
local readme_content = context.get_readme_content()
|
local readme_content = context.get_readme_content()
|
||||||
|
|
||||||
local sections = {
|
local sections = {
|
||||||
"Following you will get instructions for a development project. First you get a prompt of the user which starts with \"<<<CGP User Message\" in a line and ends with \"<<<CGP User Message End\" in a line.",
|
conf.initial_prompt .. "\n",
|
||||||
"\nThen you get the project structure which starts with \"<<<CGPT Project Structure\" in a line and ends with \"<<<CGPT Project Structure End\" in a line",
|
|
||||||
"\nThen you get the current file for context. It contains at the first line the file path, followed by its content.It starts with \"<<<CGPT Current File\" in a line and ends with \"<<<CGPT Current File End\" in a line",
|
|
||||||
"\nLastly you get the content of the README.md for context if it is present. It starts with \"<<<CGPT README\" in a line and ends with \"<<<CGPT README End\" in a line",
|
|
||||||
"\nReturn code blocks for the changes.",
|
|
||||||
"\nIf it makes sense, also update the README.md to reflect the changes made.",
|
|
||||||
"\n\n<<<CGPT User Message\n",
|
|
||||||
user_input,
|
user_input,
|
||||||
"\n<<<CGPT User Message END",
|
"\n\nproject structure:\n",
|
||||||
"\n\n<<<CGPT Project Structure\n",
|
|
||||||
project_structure,
|
project_structure,
|
||||||
"\n<<<CGPT Project Structure END",
|
"\n\nproject files:\n"
|
||||||
"\n\n<<<CGPT Current File\n",
|
|
||||||
current_file_path .. "\n" .. current_file_content,
|
|
||||||
"\n\n<<<CGPT Current File END\n",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if readme_content then
|
-- Add all other files in configured directories
|
||||||
table.insert(sections, "\n\n<<<CGPT README\n" .. readme_content .. "\n<<<CGPT README END")
|
table.insert(sections, file_sections)
|
||||||
end
|
|
||||||
|
|
||||||
local prompt = table.concat(sections, "\n")
|
local prompt = table.concat(sections, "\n")
|
||||||
|
|
||||||
-- Copy prompt to clipboard so user can paste it into the website form.
|
-- Copy prompt to clipboard
|
||||||
vim.fn.setreg('+', prompt)
|
copy_to_clipboard(prompt)
|
||||||
print("Prompt copied to clipboard! Please paste it into the website form and get the response from the ChatGPT O1 model.")
|
print("Prompt copied to clipboard! Please paste it into the ChatGPT O1 model and get the YAML response.")
|
||||||
print("Press <Enter> once you've pasted the prompt into the website and have the first file ready to copy.")
|
|
||||||
vim.fn.input("") -- wait for user to press Enter
|
|
||||||
|
|
||||||
while true do
|
|
||||||
local another = vim.fn.input("Do you want to paste another file? (y/n): ")
|
|
||||||
if another:lower() ~= "y" then
|
|
||||||
handler.finish()
|
|
||||||
break
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Ask user for filepath
|
function M.run_chatgpt_paste_command()
|
||||||
local filepath = ""
|
print("Reading ChatGPT YAML response from clipboard...")
|
||||||
while true do
|
local raw = handler.get_clipboard_content()
|
||||||
print("Please copy the FILE PATH (the first line of the code block) to your clipboard.")
|
if raw == "" then
|
||||||
print("Press <Enter> when done.")
|
vim.api.nvim_err_writeln("Clipboard is empty. Please copy the YAML response from ChatGPT first.")
|
||||||
vim.fn.input("") -- Wait for user confirmation
|
return
|
||||||
filepath = handler.get_clipboard_content()
|
end
|
||||||
if filepath == "" then
|
|
||||||
vim.api.nvim_err_writeln("Clipboard is empty. Please copy the file path and try again.")
|
local data = parse_response(raw)
|
||||||
|
if not data or not data.files then
|
||||||
|
vim.api.nvim_err_writeln("No 'files' field found in the YAML response.")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, fileinfo in ipairs(data.files) do
|
||||||
|
if fileinfo.path and fileinfo.content then
|
||||||
|
handler.write_file(fileinfo.path, fileinfo.content)
|
||||||
|
print("Wrote file: " .. fileinfo.path)
|
||||||
else
|
else
|
||||||
print("Got file path: " .. filepath)
|
vim.api.nvim_err_writeln("Invalid file entry. Must have 'path' and 'content'.")
|
||||||
break
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Ask user for file content
|
|
||||||
local filecontent = ""
|
|
||||||
while true do
|
|
||||||
print("Now copy the FILE CONTENT (everything after the first line) to your clipboard.")
|
|
||||||
print("Press <Enter> when done.")
|
|
||||||
vim.fn.input("") -- Wait for user confirmation
|
|
||||||
filecontent = handler.get_clipboard_content()
|
|
||||||
if filecontent == "" then
|
|
||||||
vim.api.nvim_err_writeln("Clipboard is empty. Please copy the file content and try again.")
|
|
||||||
else
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
handler.write_file(filepath, filecontent)
|
|
||||||
print("Wrote file: " .. filepath)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|||||||
@@ -1,2 +1,5 @@
|
|||||||
" Defines the :ChatGPT command
|
" plugin/chatgpt.vim
|
||||||
|
" Add commands for ChatGPT and ChatGPTPaste
|
||||||
|
|
||||||
command! ChatGPT lua require('chatgpt_nvim').run_chatgpt_command()
|
command! ChatGPT lua require('chatgpt_nvim').run_chatgpt_command()
|
||||||
|
command! ChatGPTPaste lua require('chatgpt_nvim').run_chatgpt_paste_command()
|
||||||
|
|||||||
Reference in New Issue
Block a user