mirror of
https://github.com/Aider-AI/aider.git
synced 2025-05-29 08:44:59 +00:00
refactor: move clipboard context functionality to commands.py
This commit is contained in:
parent
402940a215
commit
623770e24b
5 changed files with 54 additions and 52 deletions
|
@ -5,49 +5,3 @@ from .editor_editblock_prompts import EditorEditBlockPrompts
|
|||
class EditorEditBlockCoder(EditBlockCoder):
|
||||
edit_format = "editor-diff"
|
||||
gpt_prompts = EditorEditBlockPrompts()
|
||||
|
||||
def format_chat_markdown(self):
|
||||
chunks = self.format_chat_chunks()
|
||||
|
||||
markdown = ""
|
||||
|
||||
# Only include specified chunks in order
|
||||
for messages in [chunks.repo, chunks.readonly_files, chunks.chat_files, chunks.cur]:
|
||||
for msg in messages:
|
||||
# Only include user messages
|
||||
if msg["role"] != "user":
|
||||
continue
|
||||
|
||||
content = msg["content"]
|
||||
|
||||
# Handle image/multipart content
|
||||
if isinstance(content, list):
|
||||
for part in content:
|
||||
if part.get("type") == "text":
|
||||
markdown += part["text"] + "\n\n"
|
||||
else:
|
||||
markdown += content + "\n\n"
|
||||
|
||||
return markdown.strip()
|
||||
|
||||
def format_chat_chunks(self):
|
||||
chunks = super().format_chat_chunks()
|
||||
# Only add reminder if there are current messages
|
||||
if chunks.cur:
|
||||
final = chunks.cur[-1]
|
||||
if self.main_model.reminder == "sys" and self.gpt_prompts.system_reminder:
|
||||
chunks.reminder = [
|
||||
dict(
|
||||
role="system",
|
||||
content=self.fmt_system_prompt(self.gpt_prompts.system_reminder),
|
||||
)
|
||||
]
|
||||
elif self.main_model.reminder == "user" and final["role"] == "user":
|
||||
# stuff it into the user message
|
||||
new_content = (
|
||||
final["content"]
|
||||
+ "\n\n"
|
||||
+ self.fmt_system_prompt(self.gpt_prompts.system_reminder)
|
||||
)
|
||||
chunks.cur[-1] = dict(role=final["role"], content=new_content)
|
||||
return chunks
|
||||
|
|
|
@ -1399,6 +1399,41 @@ class Commands:
|
|||
if user_input.strip():
|
||||
self.io.set_placeholder(user_input.rstrip())
|
||||
|
||||
def cmd_copy_context(self, args=None):
|
||||
"""Copy the current chat context as markdown, suitable to paste into a web UI"""
|
||||
|
||||
chunks = self.coder.format_chat_chunks()
|
||||
|
||||
markdown = ""
|
||||
|
||||
# Only include specified chunks in order
|
||||
for messages in [chunks.repo, chunks.readonly_files, chunks.chat_files]:
|
||||
for msg in messages:
|
||||
# Only include user messages
|
||||
if msg["role"] != "user":
|
||||
continue
|
||||
|
||||
content = msg["content"]
|
||||
|
||||
# Handle image/multipart content
|
||||
if isinstance(content, list):
|
||||
for part in content:
|
||||
if part.get("type") == "text":
|
||||
markdown += part["text"] + "\n\n"
|
||||
else:
|
||||
markdown += content + "\n\n"
|
||||
|
||||
markdown += """
|
||||
Just tell me how to edit the files to make the changes.
|
||||
Don't give me back entire files.
|
||||
Just show me the edits I need to make.
|
||||
|
||||
|
||||
"""
|
||||
|
||||
pyperclip.copy(markdown)
|
||||
self.io.tool_output("Copied context to clipboard.")
|
||||
|
||||
|
||||
def expand_subdir(file_path):
|
||||
if file_path.is_file():
|
||||
|
|
|
@ -13,6 +13,7 @@ class ClipboardWatcher:
|
|||
self.stop_event = None
|
||||
self.watcher_thread = None
|
||||
self.last_clipboard = None
|
||||
self.io.clipboard_watcher = self
|
||||
|
||||
def start(self):
|
||||
"""Start watching clipboard for changes"""
|
||||
|
@ -25,8 +26,8 @@ class ClipboardWatcher:
|
|||
current = pyperclip.paste()
|
||||
if current != self.last_clipboard:
|
||||
self.last_clipboard = current
|
||||
self.io.placeholder = current
|
||||
self.io.interrupt_input()
|
||||
self.io.placeholder = current
|
||||
time.sleep(0.5)
|
||||
except Exception as e:
|
||||
if self.verbose:
|
||||
|
|
16
aider/io.py
16
aider/io.py
|
@ -176,6 +176,7 @@ class AutoCompleter(Completer):
|
|||
class InputOutput:
|
||||
num_error_outputs = 0
|
||||
num_user_asks = 0
|
||||
clipboard_watcher = None
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
|
@ -470,8 +471,11 @@ class InputOutput:
|
|||
self.placeholder = None
|
||||
|
||||
self.interrupted = False
|
||||
if not multiline_input and self.file_watcher:
|
||||
self.file_watcher.start()
|
||||
if not multiline_input:
|
||||
if self.file_watcher:
|
||||
self.file_watcher.start()
|
||||
if self.clipboard_watcher:
|
||||
self.clipboard_watcher.start()
|
||||
|
||||
line = self.prompt_session.prompt(
|
||||
show,
|
||||
|
@ -487,8 +491,10 @@ class InputOutput:
|
|||
|
||||
# Check if we were interrupted by a file change
|
||||
if self.interrupted:
|
||||
cmd = self.file_watcher.process_changes()
|
||||
return cmd
|
||||
line = line or ""
|
||||
if self.file_watcher:
|
||||
cmd = self.file_watcher.process_changes()
|
||||
return cmd
|
||||
|
||||
except EOFError:
|
||||
return ""
|
||||
|
@ -504,6 +510,8 @@ class InputOutput:
|
|||
finally:
|
||||
if self.file_watcher:
|
||||
self.file_watcher.stop()
|
||||
if self.clipboard_watcher:
|
||||
self.clipboard_watcher.stop()
|
||||
|
||||
if line.strip("\r\n") and not multiline_input:
|
||||
stripped = line.strip("\r\n")
|
||||
|
|
|
@ -688,6 +688,10 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
|||
editor_edit_format=args.editor_edit_format,
|
||||
)
|
||||
|
||||
if args.copypaste and args.edit_format is None:
|
||||
if main_model.edit_format in ("diff", "whole"):
|
||||
main_model.edit_format = "editor-" + main_model.edit_format
|
||||
|
||||
if args.verbose:
|
||||
io.tool_output("Model metadata:")
|
||||
io.tool_output(json.dumps(main_model.info, indent=4))
|
||||
|
@ -828,7 +832,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
|||
coder.file_watcher = file_watcher
|
||||
|
||||
if args.copypaste:
|
||||
coder.clipboard_watcher = ClipboardWatcher(coder.io, verbose=args.verbose)
|
||||
ClipboardWatcher(coder.io, verbose=args.verbose)
|
||||
|
||||
coder.show_announcements()
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue